diff options
Diffstat (limited to 'kig/objects/intersection_types.cpp')
-rw-r--r-- | kig/objects/intersection_types.cpp | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/kig/objects/intersection_types.cpp b/kig/objects/intersection_types.cpp new file mode 100644 index 00000000..0718bc23 --- /dev/null +++ b/kig/objects/intersection_types.cpp @@ -0,0 +1,338 @@ +// Copyright (C) 2003 Dominique Devriese <devriese@kde.org> + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + +#include "intersection_types.h" + +#include "bogus_imp.h" +#include "circle_imp.h" +#include "conic_imp.h" +#include "cubic_imp.h" +#include "line_imp.h" +#include "other_imp.h" +#include "point_imp.h" + +#include <tdelocale.h> + +static const char intersectlinestat[] = I18N_NOOP( "Intersect with this line" ); + +static const ArgsParser::spec argsspecConicLineIntersection[] = +{ + { ConicImp::stype(), I18N_NOOP( "Intersect with this conic" ), + "SHOULD NOT BE SEEN", true }, + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }, + { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicLineIntersectionType ) + +ConicLineIntersectionType::ConicLineIntersectionType() + : ArgsParserObjectType( "ConicLineIntersection", + argsspecConicLineIntersection, 3 ) +{ +} + +ConicLineIntersectionType::~ConicLineIntersectionType() +{ +} + +const ConicLineIntersectionType* ConicLineIntersectionType::instance() +{ + static const ConicLineIntersectionType t; + return &t; +} + +ObjectImp* ConicLineIntersectionType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + int side = static_cast<const IntImp*>( parents[2] )->data(); + assert( side == 1 || side == -1 ); + const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data(); + + Coordinate ret; + if ( parents[0]->inherits( CircleImp::stype() ) ) + { + // easy case.. + const CircleImp* c = static_cast<const CircleImp*>( parents[0] ); + ret = calcCircleLineIntersect( + c->center(), c->squareRadius(), line, side ); + } + else + { + // harder case.. + ret = calcConicLineIntersect( + static_cast<const ConicImp*>( parents[0] )->cartesianData(), + line, 0.0, side ); + } + if ( ret.valid() ) return new PointImp( ret ); + else return new InvalidImp; +} + +static const ArgsParser::spec argsspecConicLineOtherIntersection[] = +{ + { ConicImp::stype(), I18N_NOOP( "Intersect with this conic" ), + "SHOULD NOT BE SEEN", true }, + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }, + { PointImp::stype(), I18N_NOOP( "Already computed intersection point"), + "SHOULD NOT BE SEEN", true } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicLineOtherIntersectionType ) + +ConicLineOtherIntersectionType::ConicLineOtherIntersectionType() + : ArgsParserObjectType( "ConicLineOtherIntersection", + argsspecConicLineOtherIntersection, 3 ) +{ +} + +ConicLineOtherIntersectionType::~ConicLineOtherIntersectionType() +{ +} + +const ConicLineOtherIntersectionType* ConicLineOtherIntersectionType::instance() +{ + static const ConicLineOtherIntersectionType t; + return &t; +} + +ObjectImp* ConicLineOtherIntersectionType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + Coordinate p = static_cast<const PointImp*>( parents[2] )->coordinate(); + const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data(); + + Coordinate ret; +// if ( parents[0]->inherits( CircleImp::stype() ) ) +// { +// // easy case.. +// const CircleImp* c = static_cast<const CircleImp*>( parents[0] ); +// ret = calcCircleLineIntersect( +// c->center(), c->squareRadius(), line, side, valid ); +// } +// else +// { + // harder case.. + double pax = p.x - line.a.x; + double pay = p.y - line.a.y; + double bax = line.b.x - line.a.x; + double bay = line.b.y - line.a.y; + double knownparam = (pax*bax + pay*bay)/(bax*bax + bay*bay); + ret = calcConicLineIntersect( + static_cast<const ConicImp*>( parents[0] )->cartesianData(), + line, knownparam, 0 ); +// } + if ( ret.valid() ) return new PointImp( ret ); + else return new InvalidImp; +} + +static const ArgsParser::spec argsspecLineLineIntersection[] = +{ + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }, + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( LineLineIntersectionType ) + +LineLineIntersectionType::LineLineIntersectionType() + : ArgsParserObjectType( "LineLineIntersection", + argsspecLineLineIntersection, 2 ) +{ +} + +LineLineIntersectionType::~LineLineIntersectionType() +{ +} + +const LineLineIntersectionType* LineLineIntersectionType::instance() +{ + static const LineLineIntersectionType t; + return &t; +} + +ObjectImp* LineLineIntersectionType::calc( const Args& parents, const KigDocument& d ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + Coordinate p = + calcIntersectionPoint( + static_cast<const AbstractLineImp*>( parents[0] )->data(), + static_cast<const AbstractLineImp*>( parents[1] )->data() ); + if ( static_cast<const AbstractLineImp*>( parents[0] )->containsPoint( p, d ) && + static_cast<const AbstractLineImp*>( parents[1] )->containsPoint( p, d ) ) + return new PointImp( p ); + else return new InvalidImp(); +} + +static const ArgsParser::spec argsspecLineCubicIntersection[] = +{ + { CubicImp::stype(), I18N_NOOP( "Intersect with this cubic curve" ), + "SHOULD NOT BE SEEN", true }, + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }, + { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( LineCubicIntersectionType ) + +LineCubicIntersectionType::LineCubicIntersectionType() + : ArgsParserObjectType( "LineCubicIntersection", + argsspecLineCubicIntersection, 3 ) +{ +} + +LineCubicIntersectionType::~LineCubicIntersectionType() +{ +} + +const LineCubicIntersectionType* LineCubicIntersectionType::instance() +{ + static const LineCubicIntersectionType t; + return &t; +} + +ObjectImp* LineCubicIntersectionType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + int which = static_cast<const IntImp*>( parents[2] )->data(); + bool valid = true; + const Coordinate c = calcCubicLineIntersect( + static_cast<const CubicImp*>( parents[0] )->data(), + static_cast<const AbstractLineImp*>( parents[1] )->data(), + which, valid ); + if ( valid ) return new PointImp( c ); + else return new InvalidImp; +} + +const ObjectImpType* ConicLineIntersectionType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* ConicLineOtherIntersectionType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* LineLineIntersectionType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* LineCubicIntersectionType::resultId() const +{ + return PointImp::stype(); +} + +static const ArgsParser::spec argsspecCircleCircleIntersection[] = +{ + { CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ), + "SHOULD NOT BE SEEN", true }, + { CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ), + "SHOULD NOT BE SEEN", true }, + { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CircleCircleIntersectionType ) + +CircleCircleIntersectionType::CircleCircleIntersectionType() + : ArgsParserObjectType( "CircleCircleIntersection", + argsspecCircleCircleIntersection, 3 ) +{ +} + +CircleCircleIntersectionType::~CircleCircleIntersectionType() +{ +} + +const CircleCircleIntersectionType* CircleCircleIntersectionType::instance() +{ + static const CircleCircleIntersectionType t; + return &t; +} + +ObjectImp* CircleCircleIntersectionType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + int side = static_cast<const IntImp*>( parents[2] )->data(); + assert( side == 1 || side == -1 ); + const CircleImp* c1 = static_cast<const CircleImp*>( parents[0] ); + const CircleImp* c2 = static_cast<const CircleImp*>( parents[1] ); + const Coordinate o1 = c1->center(); + const Coordinate o2 = c2->center(); + const double r1sq = c1->squareRadius(); + const Coordinate a = calcCircleRadicalStartPoint( + o1, o2, r1sq, c2->squareRadius() + ); + const LineData line = LineData (a, Coordinate ( a.x -o2.y + o1.y, a.y + o2.x - o1.x )); + Coordinate ret = calcCircleLineIntersect( o1, r1sq, line, side ); + if ( ret.valid() ) return new PointImp( ret ); + else return new InvalidImp; +} + +const ObjectImpType* CircleCircleIntersectionType::resultId() const +{ + return PointImp::stype(); +} + +static const ArgsParser::spec argsspecArcLineIntersection[] = +{ + { ArcImp::stype(), I18N_NOOP( "Intersect with this arc" ), + "SHOULD NOT BE SEEN", true }, + { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }, + { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcLineIntersectionType ) + +ArcLineIntersectionType::ArcLineIntersectionType() + : ArgsParserObjectType( "ArcLineIntersection", + argsspecArcLineIntersection, 3 ) +{ +} + +ArcLineIntersectionType::~ArcLineIntersectionType() +{ +} + +const ArcLineIntersectionType* ArcLineIntersectionType::instance() +{ + static const ArcLineIntersectionType t; + return &t; +} + +ObjectImp* ArcLineIntersectionType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + int side = static_cast<const IntImp*>( parents[2] )->data(); + assert( side == 1 || side == -1 ); + const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data(); + + const ArcImp* c = static_cast<const ArcImp*>( parents[0] ); + const double r = c->radius(); + Coordinate ret = calcArcLineIntersect( c->center(), r*r, c->startAngle(), + c->angle(), line, side ); + if ( ret.valid() ) return new PointImp( ret ); + else return new InvalidImp; +} + +const ObjectImpType* ArcLineIntersectionType::resultId() const +{ + return PointImp::stype(); +} |