moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / objects / intersection_types.cc
blob911ba457e2e62bd98eaf688b78da8ad14b2d1ea9
1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #include "intersection_types.h"
20 #include "bogus_imp.h"
21 #include "circle_imp.h"
22 #include "conic_imp.h"
23 #include "cubic_imp.h"
24 #include "line_imp.h"
25 #include "other_imp.h"
26 #include "point_imp.h"
28 #include <klocale.h>
30 static const char intersectlinestat[] = I18N_NOOP( "Intersect with this line" );
32 static const ArgsParser::spec argsspecConicLineIntersection[] =
34 { ConicImp::stype(), I18N_NOOP( "Intersect with this conic" ),
35 "SHOULD NOT BE SEEN", true },
36 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true },
37 { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false }
40 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicLineIntersectionType )
42 ConicLineIntersectionType::ConicLineIntersectionType()
43 : ArgsParserObjectType( "ConicLineIntersection",
44 argsspecConicLineIntersection, 3 )
48 ConicLineIntersectionType::~ConicLineIntersectionType()
52 const ConicLineIntersectionType* ConicLineIntersectionType::instance()
54 static const ConicLineIntersectionType t;
55 return &t;
58 ObjectImp* ConicLineIntersectionType::calc( const Args& parents, const KigDocument& ) const
60 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
62 int side = static_cast<const IntImp*>( parents[2] )->data();
63 assert( side == 1 || side == -1 );
64 const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data();
66 Coordinate ret;
67 if ( parents[0]->inherits( CircleImp::stype() ) )
69 // easy case..
70 const CircleImp* c = static_cast<const CircleImp*>( parents[0] );
71 ret = calcCircleLineIntersect(
72 c->center(), c->squareRadius(), line, side );
74 else
76 // harder case..
77 ret = calcConicLineIntersect(
78 static_cast<const ConicImp*>( parents[0] )->cartesianData(),
79 line, 0.0, side );
81 if ( ret.valid() ) return new PointImp( ret );
82 else return new InvalidImp;
85 static const ArgsParser::spec argsspecConicLineOtherIntersection[] =
87 { ConicImp::stype(), I18N_NOOP( "Intersect with this conic" ),
88 "SHOULD NOT BE SEEN", true },
89 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true },
90 { PointImp::stype(), I18N_NOOP( "Already computed intersection point"),
91 "SHOULD NOT BE SEEN", true }
94 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConicLineOtherIntersectionType )
96 ConicLineOtherIntersectionType::ConicLineOtherIntersectionType()
97 : ArgsParserObjectType( "ConicLineOtherIntersection",
98 argsspecConicLineOtherIntersection, 3 )
102 ConicLineOtherIntersectionType::~ConicLineOtherIntersectionType()
106 const ConicLineOtherIntersectionType* ConicLineOtherIntersectionType::instance()
108 static const ConicLineOtherIntersectionType t;
109 return &t;
112 ObjectImp* ConicLineOtherIntersectionType::calc( const Args& parents, const KigDocument& ) const
114 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
116 Coordinate p = static_cast<const PointImp*>( parents[2] )->coordinate();
117 const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data();
119 Coordinate ret;
120 // if ( parents[0]->inherits( CircleImp::stype() ) )
121 // {
122 // // easy case..
123 // const CircleImp* c = static_cast<const CircleImp*>( parents[0] );
124 // ret = calcCircleLineIntersect(
125 // c->center(), c->squareRadius(), line, side, valid );
126 // }
127 // else
128 // {
129 // harder case..
130 double pax = p.x - line.a.x;
131 double pay = p.y - line.a.y;
132 double bax = line.b.x - line.a.x;
133 double bay = line.b.y - line.a.y;
134 double knownparam = (pax*bax + pay*bay)/(bax*bax + bay*bay);
135 ret = calcConicLineIntersect(
136 static_cast<const ConicImp*>( parents[0] )->cartesianData(),
137 line, knownparam, 0 );
138 // }
139 if ( ret.valid() ) return new PointImp( ret );
140 else return new InvalidImp;
143 static const ArgsParser::spec argsspecLineLineIntersection[] =
145 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true },
146 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true }
149 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( LineLineIntersectionType )
151 LineLineIntersectionType::LineLineIntersectionType()
152 : ArgsParserObjectType( "LineLineIntersection",
153 argsspecLineLineIntersection, 2 )
157 LineLineIntersectionType::~LineLineIntersectionType()
161 const LineLineIntersectionType* LineLineIntersectionType::instance()
163 static const LineLineIntersectionType t;
164 return &t;
167 ObjectImp* LineLineIntersectionType::calc( const Args& parents, const KigDocument& d ) const
169 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
171 Coordinate p =
172 calcIntersectionPoint(
173 static_cast<const AbstractLineImp*>( parents[0] )->data(),
174 static_cast<const AbstractLineImp*>( parents[1] )->data() );
175 if ( static_cast<const AbstractLineImp*>( parents[0] )->containsPoint( p, d ) &&
176 static_cast<const AbstractLineImp*>( parents[1] )->containsPoint( p, d ) )
177 return new PointImp( p );
178 else return new InvalidImp();
181 static const ArgsParser::spec argsspecLineCubicIntersection[] =
183 { CubicImp::stype(), I18N_NOOP( "Intersect with this cubic curve" ),
184 "SHOULD NOT BE SEEN", true },
185 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true },
186 { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false }
189 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( LineCubicIntersectionType )
191 LineCubicIntersectionType::LineCubicIntersectionType()
192 : ArgsParserObjectType( "LineCubicIntersection",
193 argsspecLineCubicIntersection, 3 )
197 LineCubicIntersectionType::~LineCubicIntersectionType()
201 const LineCubicIntersectionType* LineCubicIntersectionType::instance()
203 static const LineCubicIntersectionType t;
204 return &t;
207 ObjectImp* LineCubicIntersectionType::calc( const Args& parents, const KigDocument& ) const
209 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
211 int which = static_cast<const IntImp*>( parents[2] )->data();
212 bool valid = true;
213 const Coordinate c = calcCubicLineIntersect(
214 static_cast<const CubicImp*>( parents[0] )->data(),
215 static_cast<const AbstractLineImp*>( parents[1] )->data(),
216 which, valid );
217 if ( valid ) return new PointImp( c );
218 else return new InvalidImp;
221 const ObjectImpType* ConicLineIntersectionType::resultId() const
223 return PointImp::stype();
226 const ObjectImpType* ConicLineOtherIntersectionType::resultId() const
228 return PointImp::stype();
231 const ObjectImpType* LineLineIntersectionType::resultId() const
233 return PointImp::stype();
236 const ObjectImpType* LineCubicIntersectionType::resultId() const
238 return PointImp::stype();
241 static const ArgsParser::spec argsspecCircleCircleIntersection[] =
243 { CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ),
244 "SHOULD NOT BE SEEN", true },
245 { CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ),
246 "SHOULD NOT BE SEEN", true },
247 { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false }
250 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CircleCircleIntersectionType )
252 CircleCircleIntersectionType::CircleCircleIntersectionType()
253 : ArgsParserObjectType( "CircleCircleIntersection",
254 argsspecCircleCircleIntersection, 3 )
258 CircleCircleIntersectionType::~CircleCircleIntersectionType()
262 const CircleCircleIntersectionType* CircleCircleIntersectionType::instance()
264 static const CircleCircleIntersectionType t;
265 return &t;
268 ObjectImp* CircleCircleIntersectionType::calc( const Args& parents, const KigDocument& ) const
270 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
272 int side = static_cast<const IntImp*>( parents[2] )->data();
273 assert( side == 1 || side == -1 );
274 const CircleImp* c1 = static_cast<const CircleImp*>( parents[0] );
275 const CircleImp* c2 = static_cast<const CircleImp*>( parents[1] );
276 const Coordinate o1 = c1->center();
277 const Coordinate o2 = c2->center();
278 const double r1sq = c1->squareRadius();
279 const Coordinate a = calcCircleRadicalStartPoint(
280 o1, o2, r1sq, c2->squareRadius()
282 const LineData line = LineData (a, Coordinate ( a.x -o2.y + o1.y, a.y + o2.x - o1.x ));
283 Coordinate ret = calcCircleLineIntersect( o1, r1sq, line, side );
284 if ( ret.valid() ) return new PointImp( ret );
285 else return new InvalidImp;
288 const ObjectImpType* CircleCircleIntersectionType::resultId() const
290 return PointImp::stype();
293 static const ArgsParser::spec argsspecArcLineIntersection[] =
295 { ArcImp::stype(), I18N_NOOP( "Intersect with this arc" ),
296 "SHOULD NOT BE SEEN", true },
297 { AbstractLineImp::stype(), intersectlinestat, "SHOULD NOT BE SEEN", true },
298 { IntImp::stype(), "param", "SHOULD NOT BE SEEN", false }
301 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcLineIntersectionType )
303 ArcLineIntersectionType::ArcLineIntersectionType()
304 : ArgsParserObjectType( "ArcLineIntersection",
305 argsspecArcLineIntersection, 3 )
309 ArcLineIntersectionType::~ArcLineIntersectionType()
313 const ArcLineIntersectionType* ArcLineIntersectionType::instance()
315 static const ArcLineIntersectionType t;
316 return &t;
319 ObjectImp* ArcLineIntersectionType::calc( const Args& parents, const KigDocument& ) const
321 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
323 int side = static_cast<const IntImp*>( parents[2] )->data();
324 assert( side == 1 || side == -1 );
325 const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data();
327 const ArcImp* c = static_cast<const ArcImp*>( parents[0] );
328 const double r = c->radius();
329 Coordinate ret = calcArcLineIntersect( c->center(), r*r, c->startAngle(),
330 c->angle(), line, side );
331 if ( ret.valid() ) return new PointImp( ret );
332 else return new InvalidImp;
335 const ObjectImpType* ArcLineIntersectionType::resultId() const
337 return PointImp::stype();