30 #include "../misc/common.h"
34 static const char str1[] = I18N_NOOP(
"Invert with respect to this circle" );
35 static const char str2[] = I18N_NOOP(
"Select the circle we want to invert against..." );
40 I18N_NOOP(
"Compute the inversion of this object" ),
41 I18N_NOOP(
"Select the object to invert..." ),
false },
52 CircularInversionType::~CircularInversionType()
79 return args[0]->transform( t );
90 double normsq = relp.
x*relp.
x + relp.
y*relp.
y;
92 return new PointImp( refc + (refrsq/normsq)*relp );
104 double t = (relb.
x*ab.
x + relb.
y*ab.
y)/(ab.
x*ab.
x + ab.
y*ab.
y);
106 double normhsq = relh.
x*relh.
x + relh.
y*relh.
y;
109 if ( normhsq < 1e-12*refrsq )
return new LineImp( line.
a, line.
b );
110 Coordinate newcenter = refc + 0.5*refrsq/normhsq*relh;
111 double newradius = 0.5*refrsq/sqrt(normhsq);
113 return new CircleImp( newcenter, newradius );
115 if ( issegment || isray )
122 Coordinate newcenterrel = 0.5*refrsq/normhsq*relh;
125 if ( issegment ) relbinv = refrsq/relb.
squareLength() * relb;
127 if ( normhsq < 1e-12*refrsq )
129 if ( rela.squareLength() < 1e-12 )
131 return new RayImp( relbinv + refc, 2*relbinv + refc );
135 return new RayImp( relainv + refc, 2*relainv + refc );
137 if ( relb.
x*rela.x + relb.
y*rela.y > 0 )
139 return new SegmentImp( relainv + refc, relbinv + refc );
143 double newradius = 0.5*refrsq/sqrt(normhsq);
145 relainv -= newcenterrel;
146 relbinv -= newcenterrel;
147 double angle1 = atan2( relainv.
y, relainv.
x );
148 double angle2 = atan2( relbinv.
y, relbinv.
x );
149 double angle = angle2 - angle1;
150 if ( ab.x*rela.y - ab.y*rela.x > 0 )
155 while ( angle1 <= -M_PI ) angle1 += 2*M_PI;
156 while ( angle1 > M_PI ) angle1 -= 2*M_PI;
157 while ( angle < 0 ) angle += 2*M_PI;
158 while ( angle >= 2*M_PI ) angle -= 2*M_PI;
159 return new ArcImp( newcenterrel + refc, newradius, angle1, angle );
168 double clength = c.
length();
170 if ( clength != 0.0 ) cnorm = c/clength;
171 double r = circle->
radius();
174 double bsq = b.
x*b.
x + b.
y*b.
y;
176 if ( std::fabs( clength - r ) < 1e-6*clength )
182 double asq = a.
x*a.
x + a.
y*a.
y;
186 double rprime = 0.5*( bprime - aprime ).length();
188 return new CircleImp( cprime + refc, rprime );
193 const ArcImp* arc =
static_cast<const ArcImp*
>( args[0] );
195 double clength = c.
length();
197 if ( clength != 0.0 ) cnorm = c/clength;
204 double bsq = b.
x*b.
x + b.
y*b.
y;
206 if ( std::fabs( clength - r ) < 1e-6*clength )
220 ep1inv = refrsq/ep1sq * ep1;
228 ep2inv = refrsq/ep2sq * ep2;
232 if ( valid1 || valid2 )
234 if ( valid1 && valid2 )
238 double ang = atan2( -c.
y, -c.
x );
240 if ( ang < sa ) ang += 2*M_PI;
242 return new SegmentImp( ep1inv + refc, ep2inv + refc );
244 return new RayImp ( rayendp + refc,
251 double asq = a.
x*a.
x + a.
y*a.
y;
255 double rprime = 0.5*( bprime - aprime ).length();
259 double newstartangle = 2*atan2(ep1.
y,ep1.
x) - ang1;
261 double ang2 = ang1 + arc->
angle();
262 double newendangle = 2*atan2(ep2.
y,ep2.
x) - ang2;
263 double newangle = newendangle - newstartangle;
272 newstartangle = newendangle - M_PI;
273 newangle = - newangle;
276 while ( newstartangle <= -M_PI ) newstartangle += 2*M_PI;
277 while ( newstartangle > M_PI ) newstartangle -= 2*M_PI;
278 while ( newangle < 0 ) newangle += 2*M_PI;
279 while ( newangle >= 2*M_PI ) newangle -= 2*M_PI;
280 return new ArcImp( cprime + refc, rprime, newstartangle, newangle );
292 {
PointImp::stype(), I18N_NOOP(
"Compute the inversion of this point" ),
293 I18N_NOOP(
"Select the point to invert..." ),
false },
304 InvertPointType::~InvertPointType()
328 return args[0]->transform( t );
336 double normsq = relp.
x*relp.
x + relp.
y*relp.
y;
338 return new PointImp( center + (radiussq/normsq)*relp );
353 {
LineImp::stype(), I18N_NOOP(
"Compute the inversion of this line" ),
354 I18N_NOOP(
"Select the line to invert..." ),
false },
365 InvertLineType::~InvertLineType()
390 double t = (relb.
x*ab.
x + relb.
y*ab.
y)/(ab.
x*ab.
x + ab.
y*ab.
y);
392 double normhsq = relh.
x*relh.
x + relh.
y*relh.
y;
393 if ( normhsq < 1e-12*radiussq )
return new LineImp( line.
a, line.
b );
394 Coordinate newcenter = center + 0.5*radiussq/normhsq*relh;
395 double newradius = 0.5*radiussq/sqrt(normhsq);
397 return new CircleImp( newcenter, newradius );
407 I18N_NOOP(
"Select the segment to invert..." ),
false },
418 InvertSegmentType::~InvertSegmentType()
444 double t = (relb.
x*ab.
x + relb.
y*ab.
y)/(ab.
x*ab.
x + ab.
y*ab.
y);
446 double normhsq = relh.
x*relh.
x + relh.
y*relh.
y;
452 Coordinate newcenterrel = 0.5*radiussq/normhsq*relh;
456 if ( normhsq < 1e-12*radiussq )
458 if ( rela.squareLength() < 1e-12 )
460 return new RayImp( relbinv + center, 2*relbinv + center );
464 return new RayImp( relainv + center, 2*relainv + center );
466 if ( relb.
x*rela.x + relb.
y*rela.y > 0 )
468 return new SegmentImp( relainv + center, relbinv + center );
472 double newradius = 0.5*radiussq/sqrt(normhsq);
474 relainv -= newcenterrel;
475 relbinv -= newcenterrel;
476 double angle1 = atan2( relainv.
y, relainv.
x );
477 double angle2 = atan2( relbinv.
y, relbinv.
x );
478 double angle = angle2 - angle1;
479 if ( ab.x*rela.y - ab.y*rela.x > 0 )
484 while ( angle1 < 0 ) angle1 += 2*M_PI;
485 while ( angle1 >= 2*M_PI ) angle1 -= 2*M_PI;
486 while ( angle < 0 ) angle += 2*M_PI;
487 while ( angle >= 2*M_PI ) angle -= 2*M_PI;
488 return new ArcImp( newcenterrel + center, newradius, angle1, angle );
498 I18N_NOOP(
"Select the circle to invert..." ),
false },
509 InvertCircleType::~InvertCircleType()
533 double clength = c.
length();
535 if ( clength != 0.0 ) cnorm = c/clength;
536 double r = circle->
radius();
539 double bsq = b.
x*b.
x + b.
y*b.
y;
541 if ( std::fabs( clength - r ) < 1e-6*clength )
547 double asq = a.
x*a.
x + a.
y*a.
y;
551 double rprime = 0.5*( bprime - aprime ).length();
553 return new CircleImp( cprime + refc, rprime );
562 {
ArcImp::stype(), I18N_NOOP(
"Compute the inversion of this arc" ),
563 I18N_NOOP(
"Select the arc to invert..." ),
false },
574 InvertArcType::~InvertArcType()
596 const ArcImp* arc =
static_cast<const ArcImp*
>( args[0] );
598 double clength = c.
length();
600 if ( clength != 0.0 ) cnorm = c/clength;
607 double bsq = b.
x*b.
x + b.
y*b.
y;
609 if ( std::fabs( clength - r ) < 1e-6*clength )
623 ep1inv = refrsq/ep1sq * ep1;
631 ep2inv = refrsq/ep2sq * ep2;
635 if ( valid1 || valid2 )
637 if ( valid1 && valid2 )
641 double ang = atan2( -c.
y, -c.
x );
643 if ( ang < sa ) ang += 2*M_PI;
645 return new SegmentImp( ep1inv + refc, ep2inv + refc );
647 return new RayImp ( rayendp + refc,
654 double asq = a.
x*a.
x + a.
y*a.
y;
658 double rprime = 0.5*( bprime - aprime ).length();
662 double newstartangle = 2*atan2(ep1.
y,ep1.
x) - ang1;
664 double ang2 = ang1 + arc->
angle();
665 double newendangle = 2*atan2(ep2.
y,ep2.
x) - ang2;
666 double newangle = newendangle - newstartangle;
675 newstartangle = newendangle - M_PI;
676 newangle = - newangle;
679 while ( newstartangle < 0 ) newstartangle += 2*M_PI;
680 while ( newstartangle >= 2*M_PI ) newstartangle -= 2*M_PI;
681 while ( newangle < 0 ) newangle += 2*M_PI;
682 while ( newangle >= 2*M_PI ) newangle -= 2*M_PI;
683 return new ArcImp( cprime + refc, rprime, newstartangle, newangle );
Instances of this class represent a certain ObjectImp type.
This is a convenience subclass of ObjectType that a type should inherit from if its parents can be sp...
virtual bool inherits(int type) const
An ObjectImp class that is the base of the line-like ObjectImp's: SegmentImp, LineImp and RayImp...
Simple class representing a line.
Coordinate b
Another point on the line.
An ObjectImp representing a circle.
An ObjectImp representing a ray.
const Coordinate center() const
Return the center of this circle.
Coordinate firstEndPoint() const
Return the start point of this arc.
static const ObjectImpType * stype()
Returns the ObjectImpType representing the RayImp type.
Inversion of a point, line.
#define KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE(type)
static const ObjectImpType * stype()
Returns the ObjectImpType representing the LineImp type.
ObjectImp * calc(const Args &args, const KigDocument &) const
static const ArgsParser::spec argsspecInvertCircle[]
double radius() const
Return the radius of this arc.
static const ArgsParser::spec argsspecInvertArc[]
The Coordinate class is the basic class representing a 2D location by its x and y components...
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
double length() const
Length.
const ArgsParser margsparser
static const ArgsParser::spec argsspecInvertLine[]
InvertibleImpType invertibleimptypeinstance
static const CircularInversionType * instance()
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
static const ArgsParser::spec argsspecCircularInversion[]
static const InvertSegmentType * instance()
static const InvertLineType * instance()
double angle() const
Return the dimension in radians of this arc.
An ObjectImp representing a point.
std::vector< const ObjectImp * > Args
static const InvertPointType * instance()
Coordinate secondEndPoint() const
Return the end point of this arc.
Coordinate a
One point on the line.
bool checkArgs(const std::vector< ObjectCalcer * > &os) const
static const ObjectImpType * stype()
Returns the ObjectImpType representing the SegmentImp type.
ObjectImp * calc(const Args &args, const KigDocument &) const
static const ObjectImpType * stype()
Returns the ObjectImpType representing the ArcImp type.
ObjectImp * calc(const Args &args, const KigDocument &) const
const Coordinate center() const
Return the center of this arc.
static const ObjectImpType * stype()
Returns the ObjectImpType representing the CircleImp type.
double squareLength() const
Square length.
double startAngle() const
Return the start angle in radians of this arc.
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
static Coordinate invalidCoord()
Create an invalid Coordinate.
Circular inversion (new style)
double radius() const
Return the radius of this circle.
static const ObjectImpType * stype()
Returns the ObjectImpType representing PointImp's.
KigDocument is the class holding the real data in a Kig document.
static const ObjectImpType * stype()
Returns the ObjectImpType representing the AbstractLineImp type.
ObjectImp * calc(const Args &args, const KigDocument &) const
An ObjectImp representing a line.
static const ArgsParser::spec argsspecInvertSegment[]
static const InvertCircleType * instance()
An ObjectImp representing an arc.
ObjectImp * calc(const Args &args, const KigDocument &) const
The ObjectImp class represents the behaviour of an object after it is calculated. ...
static const ArgsParser::spec argsspecInvertPoint[]
static const InvertArcType * instance()
double squareRadius() const
Return the square radius of this circle.
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
This ObjectImp represents an invalid object.
ObjectImp * calc(const Args &args, const KigDocument &) const
const ObjectImpType * resultId() const
returns the ObjectImp id of the ObjectImp's produced by this ObjectType.
An ObjectImp representing a segment.