[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