[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kig] /: - replace CircleBTPType/ArcBTPType by CircleBTPoType/ArcBTPoType
From: Maurizio Paolini <paolini () dmf ! unicatt ! it>
Date: 2016-04-03 20:59:58
Message-ID: E1amp7m-0006fP-TH () scm ! kde ! org
[Download RAW message or body]
Git commit 6b8a2e592403aa40b6b5297b8a92ae5d6d61a481 by Maurizio Paolini.
Committed on 03/04/2016 at 11:14.
Pushed by paolini into branch 'master'.
- replace CircleBTPType/ArcBTPType by CircleBTPoType/ArcBTPoType
- use orientation for ArcLine intersection
- treat the Arc that becomes Segment degeneracy in ArcLineIntersection
M +2 -2 misc/builtin_stuff.cc
M +4 -116 objects/arc_type.cc
M +1 -20 objects/arc_type.h
M +3 -122 objects/circle_type.cc
M +1 -17 objects/circle_type.h
M +27 -1 objects/intersection_types.cc
http://commits.kde.org/kig/6b8a2e592403aa40b6b5297b8a92ae5d6d61a481
diff --git a/misc/builtin_stuff.cc b/misc/builtin_stuff.cc
index 5e475b3..e1de877 100644
--- a/misc/builtin_stuff.cc
+++ b/misc/builtin_stuff.cc
@@ -117,7 +117,7 @@ void setupBuiltinStuff()
actions->add( new ConstructibleAction( c, "objects_new_circlebcp", Qt::Key_C ) );
c = new SimpleObjectTypeConstructor(
- CircleBTPoType::instance(), I18N_NOOP( "Circle by Three Points" ),
+ CircleBTPType::instance(), I18N_NOOP( "Circle by Three Points" ),
I18N_NOOP( "A circle constructed through three points" ),
"circlebtp" );
ctors->add( c );
@@ -327,7 +327,7 @@ void setupBuiltinStuff()
actions->add( new ConstructibleAction( c, "objects_new_halflinebyvector", 0 ) );
c = new SimpleObjectTypeConstructor(
- ArcBTPoType::instance(),
+ ArcBTPType::instance(),
I18N_NOOP( "Arc by Three Points" ),
I18N_NOOP( "Construct an arc through three points." ),
"arc" );
diff --git a/objects/arc_type.cc b/objects/arc_type.cc
index 82892be..c87eff6 100644
--- a/objects/arc_type.cc
+++ b/objects/arc_type.cc
@@ -41,7 +41,7 @@ using std::find;
#include <qstringlist.h>
/*
- * arc by three points
+ * oriented arc by three points
*/
static const char constructarcstartingstat[] = I18N_NOOP( "Construct an arc starting at this point" );
@@ -85,118 +85,6 @@ ObjectImp* ArcBTPType::calc( const Args& args, const KigDocument& ) const
Coordinate center;
double angle = 0.;
double startangle = 0.;
- if ( args.size() == 3 )
- {
- Coordinate c = static_cast<const PointImp*>( args[2] )->coordinate();
- center = calcCenter( a, b, c );
- if ( ! center.valid() )
- {
- if ( fabs( a.x - c.x ) > fabs( a.y - c.y ) )
- {
- if ( ( b.x - a.x)*(c.x - b.x) > 1e-12 ) return new SegmentImp(a, c);
- } else
- {
- if ( ( b.y - a.y)*(c.y - b.y) > 1e-12 ) return new SegmentImp(a, c);
- }
- return new InvalidImp;
- }
- Coordinate ad = a - center;
- Coordinate bd = b - center;
- Coordinate cd = c - center;
- double anglea = atan2( ad.y, ad.x );
- double angleb = atan2( bd.y, bd.x );
- double anglec = atan2( cd.y, cd.x );
-
- // anglea should be smaller than anglec
- if ( anglea > anglec )
- {
- double t = anglea;
- anglea = anglec;
- anglec = t;
- };
- if ( angleb > anglec || angleb < anglea )
- {
- startangle = anglec;
- angle = 2 * M_PI + anglea - startangle;
- }
- else
- {
- startangle = anglea;
- angle = anglec - anglea;
- };
- }
- else
- {
- // find a center and angles that look natural..
- center = (b+a)/2 + .6*(b-a).orthogonal();
- Coordinate bd = b - center;
- Coordinate ad = a - center;
- startangle = atan2( ad.y, ad.x );
- double halfangle = atan2( bd.y, bd.x ) - startangle;
- if ( halfangle < - M_PI ) halfangle += 2*M_PI;
- angle = 2 * halfangle;
- };
-
- double radius = ( a - center ).length();
- return new ArcImp( center, radius, startangle, angle );
-}
-
-const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& ) const
-{
- return PointImp::stype();
-}
-
-bool ArcBTPType::inherits( int type ) const
-{
- return Parent::inherits( type );
-}
-
-const ObjectImpType* ArcBTPType::resultId() const
-{
- return ArcImp::stype();
-}
-
-/* oriented arc by three points */
-
-static const ArgsParser::spec argsspecArcBTPo[] =
-{
- { PointImp::stype(), constructarcstartingstat,
- I18N_NOOP( "Select the start point of the new arc..." ), true },
- { PointImp::stype(), I18N_NOOP( "Construct an arc through this point" ),
- I18N_NOOP( "Select a point for the new arc to go through..." ), true },
- { PointImp::stype(), I18N_NOOP( "Construct an arc ending at this point" ),
- I18N_NOOP( "Select the end point of the new arc..." ), true }
-};
-
-KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ArcBTPoType )
-
-ArcBTPoType::ArcBTPoType()
- : ArgsParserObjectType( "ArcBTPo", argsspecArcBTPo, 3 )
-{
-}
-
-ArcBTPoType::~ArcBTPoType()
-{
-}
-
-const ArcBTPoType* ArcBTPoType::instance()
-{
- static const ArcBTPoType t;
- return &t;
-}
-
-ObjectImp* ArcBTPoType::calc( const Args& args, const KigDocument& ) const
-{
- if ( ! margsparser.checkArgs( args, 2 ) )
- return new InvalidImp;
-
- const Coordinate a =
- static_cast<const PointImp*>( args[0] )->coordinate();
- const Coordinate b =
- static_cast<const PointImp*>( args[1] )->coordinate();
- Coordinate center;
- double angle = 0.;
- double startangle = 0.;
int orientation = 1;
if ( args.size() == 3 )
{
@@ -264,17 +152,17 @@ ObjectImp* ArcBTPoType::calc( const Args& args, const KigDocument& ) const
return new ArcImp( center, orientation*radius, startangle, angle );
}
-const ObjectImpType* ArcBTPoType::impRequirement( const ObjectImp*, const Args& ) const
+const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& ) const
{
return PointImp::stype();
}
-bool ArcBTPoType::inherits( int type ) const
+bool ArcBTPType::inherits( int type ) const
{
return Parent::inherits( type );
}
-const ObjectImpType* ArcBTPoType::resultId() const
+const ObjectImpType* ArcBTPType::resultId() const
{
return ArcImp::stype();
}
diff --git a/objects/arc_type.h b/objects/arc_type.h
index 0238651..68aba5f 100644
--- a/objects/arc_type.h
+++ b/objects/arc_type.h
@@ -23,6 +23,7 @@
/**
* an arc by a start point, an intermediate point and an end point
+ * (with orientation)
*/
class ArcBTPType
: public ArgsParserObjectType
@@ -42,26 +43,6 @@ public:
};
/**
- * an arc by a start point, an intermediate point and an end point
- */
-class ArcBTPoType
- : public ArgsParserObjectType
-{
- typedef ArgsParserObjectType Parent;
- ArcBTPoType();
- ~ArcBTPoType();
-public:
- static const ArcBTPoType* instance();
-
- ObjectImp* calc( const Args& args, const KigDocument& ) const;
-
- const ObjectImpType* impRequirement( const ObjectImp* o, const Args& parents ) const;
-
- bool inherits( int type ) const;
- const ObjectImpType* resultId() const;
-};
-
-/**
* an arc by a point (center), a starting point and an angle
*/
class ArcBCPAType
diff --git a/objects/circle_type.cc b/objects/circle_type.cc
index ae221a8..7be7228 100644
--- a/objects/circle_type.cc
+++ b/objects/circle_type.cc
@@ -61,12 +61,6 @@ ObjectImp* CircleBCPType::calcx( const Coordinate& a, const Coordinate& b ) cons
return new CircleImp( a, ( b - a ).length() );
}
-const CircleBTPType* CircleBTPType::instance()
-{
- static const CircleBTPType t;
- return &t;
-}
-
static const ArgsParser::spec argsspecCircleBTP[] =
{
{ PointImp::stype(), constructcirclethroughpointstat,
@@ -88,121 +82,13 @@ CircleBTPType::~CircleBTPType()
{
}
-ObjectImp* CircleBTPType::calc( const Args& args, const KigDocument& ) const
-{
- if ( ! margsparser.checkArgs( args, 2 ) ) return new InvalidImp;
-
- const Coordinate a = static_cast<const PointImp*>( args[0] )->coordinate();
- const Coordinate b = static_cast<const PointImp*>( args[1] )->coordinate();
- Coordinate c;
- if ( args.size() == 3 )
- c = static_cast<const PointImp*>( args[2] )->coordinate();
- else
- {
- // we pick the third point so that the three points form a
- // triangle with equal sides...
-
- // midpoint:
- Coordinate m = ( b + a ) / 2;
- if ( b.y != a.y )
- {
- // direction of the perpend:
- double d = -(b.x-a.x)/(b.y-a.y);
-
- // length:
- // sqrt( 3 ) == tan( 60 ° ) == sqrt( 2^2 - 1^2 )
- double l = 1.73205080756 * (a-b).length() / 2;
-
- double d2 = d*d;
- double l2 = l*l;
- double dx = sqrt( l2 / ( d2 + 1 ) );
- double dy = sqrt( l2 * d2 / ( d2 + 1 ) );
- if( d < 0 ) dy = -dy;
-
- c.x = m.x + dx;
- c.y = m.y + dy;
- }
- else
- {
- c.x = m.x;
- c.y = m.y + ( a.x - b.x );
- };
- };
-
- const Coordinate center = calcCenter( a, b, c );
- if ( center.valid() ) return new CircleImp( center, (center - a ).length() );
-
- /*
- * case of collinear points, we need to identify the intermediate one
- */
-
- double xmin = fmin( a.x, fmin( b.x, c.x) );
- double xmax = fmax( a.x, fmax( b.x, c.x) );
- double ymin = fmin( a.y, fmin( b.y, c.y) );
- double ymax = fmax( a.y, fmax( b.y, c.y) );
- double axy, bxy, cxy;
-
- /* decide whether to work with x coordinate or y coordinate */
-
- if ( xmax - xmin > ymax - ymin )
- {
- axy = a.x;
- bxy = b.x;
- cxy = c.x;
- } else
- {
- axy = a.y;
- bxy = b.y;
- cxy = c.y;
- }
-
- /*
- * compute baricentric coordinate of c with respect to a and b
- * (if a and c are not coincident)
- */
- if ( fabs( cxy - axy ) < 1e-6*fabs( bxy - axy ) ) return new InvalidImp;
- double t = (bxy - axy)/(cxy - axy);
-
- if ( fabs( t ) < 1e-6 || fabs( 1.0 - t ) < 1e-6 ) return new InvalidImp;
-
- /*
- * t < 0: a between c and b
- * 0 < t < 1: b between a and c
- * t > 1: c between a and b
- */
- if ( t < 0.0 ) return new LineImp( c, b );
- if ( t > 1.0 ) return new LineImp( a, b );
- return new LineImp( a, c );
-}
-
-const CircleBTPoType* CircleBTPoType::instance()
+const CircleBTPType* CircleBTPType::instance()
{
- static const CircleBTPoType t;
+ static const CircleBTPType t;
return &t;
}
-static const ArgsParser::spec argsspecCircleBTPo[] =
-{
- { PointImp::stype(), constructcirclethroughpointstat,
- I18N_NOOP( "Select a point for the new circle to go through..." ), true },
- { PointImp::stype(), constructcirclethroughpointstat,
- I18N_NOOP( "Select a point for the new circle to go through..." ), true },
- { PointImp::stype(), constructcirclethroughpointstat,
- I18N_NOOP( "Select a point for the new circle to go through..." ), true }
-};
-
-KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CircleBTPoType )
-
-CircleBTPoType::CircleBTPoType()
- : ArgsParserObjectType( "CircleBTPo", argsspecCircleBTPo, 3 )
-{
-}
-
-CircleBTPoType::~CircleBTPoType()
-{
-}
-
-ObjectImp* CircleBTPoType::calc( const Args& args, const KigDocument& ) const
+ObjectImp* CircleBTPType::calc( const Args& args, const KigDocument& ) const
{
if ( ! margsparser.checkArgs( args, 2 ) ) return new InvalidImp;
@@ -311,11 +197,6 @@ const ObjectImpType* CircleBTPType::resultId() const
return CircleImp::stype();
}
-const ObjectImpType* CircleBTPoType::resultId() const
-{
- return CircleImp::stype();
-}
-
static const ArgsParser::spec argsspecCircleBPR[] =
{
{ PointImp::stype(), constructcirclewithcenterstat,
diff --git a/objects/circle_type.h b/objects/circle_type.h
index 33e2ff8..8a26cb4 100644
--- a/objects/circle_type.h
+++ b/objects/circle_type.h
@@ -51,7 +51,7 @@ public:
};
/**
- * Circle by three points
+ * Circle by three points (with orientation)
*/
class CircleBTPType
: public ArgsParserObjectType
@@ -66,21 +66,5 @@ public:
const ObjectImpType* resultId() const;
};
-/**
- * Circle by three points (with orientation)
- */
-class CircleBTPoType
- : public ArgsParserObjectType
-{
- CircleBTPoType();
- ~CircleBTPoType();
-
-public:
- static const CircleBTPoType* instance();
-
- ObjectImp* calc( const Args& args, const KigDocument& ) const;
- const ObjectImpType* resultId() const;
-};
-
#endif
diff --git a/objects/intersection_types.cc b/objects/intersection_types.cc
index e818ae9..5d356b7 100644
--- a/objects/intersection_types.cc
+++ b/objects/intersection_types.cc
@@ -606,6 +606,32 @@ const ArcLineIntersectionType* ArcLineIntersectionType::instance()
ObjectImp* ArcLineIntersectionType::calc( const Args& parents, const KigDocument& ) const
{
+ /*
+ * special case of an arc that degenerates into a line. This is possible e.g. for
+ * arcs by three points when the points get aligned.
+ */
+ if ( parents.size() == 3 && parents[0]->inherits( AbstractLineImp::stype() ) &&
+ parents[1]->inherits( AbstractLineImp::stype() ) &&
+ parents[2]->inherits( IntImp::stype() ) )
+ {
+ int side = static_cast<const IntImp*>( parents[2] )->data();
+ assert( side == 1 || side == -1 );
+ const LineData degline = static_cast<const AbstractLineImp*>( parents[0] )->data();
+ const LineData line = static_cast<const AbstractLineImp*>( parents[1] )->data();
+ const double vecprod = degline.dir().y * line.dir().x - degline.dir().x * line.dir().y;
+ /*
+ * mp: In this case only one of the two points must be valid (the other is "pushed"
+ * to infinity). The choice of which one is done such that we avoid abrupt points exchange
+ * when dinamically movint points
+ */
+ if (side*vecprod < 0)
+ {
+ Coordinate p = calcIntersectionPoint( degline, line );
+ return new PointImp( p );
+ }
+ return new InvalidImp();
+ }
+
if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
int side = static_cast<const IntImp*>( parents[2] )->data();
@@ -615,7 +641,7 @@ ObjectImp* ArcLineIntersectionType::calc( const Args& parents, const KigDocument
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 );
+ c->angle(), line, c->orientation()*side );
if ( ret.valid() ) return new PointImp( ret );
else return new InvalidImp;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic