Hello community,

here is the log from the commit of package kig for openSUSE:Factory checked in 
at 2016-08-31 00:07:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kig (Old)
 and      /work/SRC/openSUSE:Factory/.kig.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kig"

Changes:
--------
--- /work/SRC/openSUSE:Factory/kig/kig.changes  2016-07-24 19:46:33.000000000 
+0200
+++ /work/SRC/openSUSE:Factory/.kig.new/kig.changes     2016-08-31 
00:07:36.000000000 +0200
@@ -1,0 +2,16 @@
+Fri Aug 12 10:17:43 UTC 2016 - [email protected]
+
+- Update to KDE Applications 16.08.0
+   * KDE Applications 16.08.0
+   * https://www.kde.org/announcements/announce-applications-16.08.0.php
+
+
+-------------------------------------------------------------------
+Mon Aug  8 15:04:50 UTC 2016 - [email protected]
+
+- Update to KDE Applications 16.07.90
+   * KDE Applications 16.07.90 (16.08-RC)
+   * https://www.kde.org/announcements/announce-applications-16.07.90.php
+
+
+-------------------------------------------------------------------

Old:
----
  kig-16.04.3.tar.xz

New:
----
  kig-16.08.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kig.spec ++++++
--- /var/tmp/diff_new_pack.2bk2c6/_old  2016-08-31 00:07:37.000000000 +0200
+++ /var/tmp/diff_new_pack.2bk2c6/_new  2016-08-31 00:07:37.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           kig
-Version:        16.04.3
+Version:        16.08.0
 Release:        0
 Summary:        Interactive Geometry
 License:        GPL-2.0+

++++++ kig-16.04.3.tar.xz -> kig-16.08.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/misc/common.cpp 
new/kig-16.08.0/misc/common.cpp
--- old/kig-16.04.3/misc/common.cpp     2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/misc/common.cpp     2016-04-28 00:34:52.000000000 +0200
@@ -366,7 +366,8 @@
   double b2 = xao*xao + yao*yao;
 
   double numerator = (xdo * yao - xao * ydo);
-  if ( numerator == 0 )
+  /* mp: note that we should never compare with zero due to floating-point 
arithmetic */
+  if ( isSingular (xdo, ydo, xao, yao) )
   {
     // problem:  xdo * yao == xao * ydo <=> xdo/ydo == xao / yao
     // this means that the lines ac and ab have the same direction,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/misc/kigpainter.cpp 
new/kig-16.08.0/misc/kigpainter.cpp
--- old/kig-16.04.3/misc/kigpainter.cpp 2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/misc/kigpainter.cpp 2016-04-28 00:34:52.000000000 +0200
@@ -86,14 +86,14 @@
   Coordinate bottomLeft = center - Coordinate(radius, radius);
   Coordinate topRight = center + Coordinate(radius, radius);
   Rect r( bottomLeft, topRight );
-  QRect qr = toScreen( r );
+  QRectF qr = toScreenF( r );
   mP.drawEllipse ( qr );
   if( mNeedOverlay ) circleOverlay( center, radius );
 }
 
 void KigPainter::drawSegment( const Coordinate& from, const Coordinate& to )
 {
-  QPoint tF = toScreen(from), tT = toScreen(to);
+  QPointF tF = toScreenF(from), tT = toScreenF(to);
   mP.drawLine( tF, tT );
   if( mNeedOverlay ) segmentOverlay( from, to );
 }
@@ -506,6 +506,11 @@
   return msi.toScreen( p );
 }
 
+QPointF KigPainter::toScreenF( const Coordinate& p ) const
+{
+  return msi.toScreenF( p );
+}
+
 void KigPainter::drawGrid( const CoordinateSystem& c, bool showGrid, bool 
showAxes )
 {
   c.drawGrid( *this, showGrid, showAxes );
@@ -549,6 +554,11 @@
   return msi.toScreen( r );
 }
 
+QRectF KigPainter::toScreenF( const Rect& r ) const
+{
+  return msi.toScreenF( r );
+}
+
 QRect KigPainter::toScreenEnlarge( const Rect& r ) const
 {
   if ( overlayenlarge == 0 ) return msi.toScreen( r );
@@ -973,7 +983,7 @@
   { 
     Rect krect( 0, 0, 2*radius, 2*radius );
     krect.setCenter( center );
-    QRect rect = toScreen( krect );
+    QRectF rect = toScreenF( krect );
 
     mP.drawArc( rect, startangle, angle );
     setWholeWinOverlay();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/misc/kigpainter.h 
new/kig-16.08.0/misc/kigpainter.h
--- old/kig-16.04.3/misc/kigpainter.h   2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/misc/kigpainter.h   2016-04-28 00:34:52.000000000 +0200
@@ -89,6 +89,8 @@
 
   QPoint toScreen( const Coordinate& p ) const;
   QRect toScreen( const Rect& r ) const;
+  QPointF toScreenF( const Coordinate& p ) const;
+  QRectF toScreenF( const Rect& r ) const;
   QRect toScreenEnlarge( const Rect& r ) const;
   Coordinate fromScreen( const QPoint& p ) const;
   Rect fromScreen( const QRect& r ) const;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/misc/screeninfo.cc 
new/kig-16.08.0/misc/screeninfo.cc
--- old/kig-16.04.3/misc/screeninfo.cc  2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/misc/screeninfo.cc  2016-04-28 00:34:52.000000000 +0200
@@ -58,6 +58,23 @@
     ).normalized();
 }
 
+QPointF ScreenInfo::toScreenF( const Coordinate& p ) const
+{
+  Coordinate t = p - mkrect.bottomLeft();
+  t *= mqrect.width();
+  t /= mkrect.width();
+  // invert the y-axis: 0 is at the bottom !
+  return QPointF( t.x, mqrect.height() - t.y );
+}
+
+QRectF ScreenInfo::toScreenF( const Rect& r ) const
+{
+  return QRectF(
+    toScreenF( r.bottomLeft() ),
+    toScreenF( r.topRight() )
+    ).normalized();
+}
+
 double ScreenInfo::pixelWidth() const
 {
   Coordinate a = fromScreen( QPoint( 0, 0 ) );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/misc/screeninfo.h 
new/kig-16.08.0/misc/screeninfo.h
--- old/kig-16.04.3/misc/screeninfo.h   2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/misc/screeninfo.h   2016-04-28 00:34:52.000000000 +0200
@@ -40,6 +40,8 @@
 
   QPoint toScreen( const Coordinate& p ) const;
   QRect toScreen( const Rect& r ) const;
+  QPointF toScreenF( const Coordinate& p ) const;
+  QRectF toScreenF( const Rect& r ) const;
 
   double pixelWidth() const;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/arc_type.cc 
new/kig-16.08.0/objects/arc_type.cc
--- old/kig-16.04.3/objects/arc_type.cc 2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/objects/arc_type.cc 2016-04-28 00:34:52.000000000 +0200
@@ -41,7 +41,7 @@
 #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,12 +85,14 @@
   Coordinate center;
   double angle = 0.;
   double startangle = 0.;
+  int orientation = 1;
   if ( args.size() == 3 )
   {
     Coordinate c = static_cast<const PointImp*>( args[2] )->coordinate();
     center = calcCenter( a, b, c );
     if ( ! center.valid() )
     {
+/* TODO: return correctly oriented segment! */
       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);
@@ -100,6 +102,15 @@
       }
       return new InvalidImp;
     }
+    /* this is also done in calcCenter... should optimize in some way */
+    double xdo = b.x-a.x;
+    double ydo = b.y-a.y;
+
+    double xao = c.x-a.x;
+    double yao = c.y-a.y;
+
+    if ( xdo * yao - xao * ydo < 0.0 ) orientation = -1;
+
     Coordinate ad = a - center;
     Coordinate bd = b - center;
     Coordinate cd = c - center;
@@ -138,7 +149,7 @@
   };
 
   double radius = ( a - center ).length();
-  return new ArcImp( center, radius, startangle, angle );
+  return new ArcImp( center, orientation*radius, startangle, angle );
 }
 
 const ObjectImpType* ArcBTPType::impRequirement( const ObjectImp*, const Args& 
) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/arc_type.h 
new/kig-16.08.0/objects/arc_type.h
--- old/kig-16.04.3/objects/arc_type.h  2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/objects/arc_type.h  2016-04-28 00:34:52.000000000 +0200
@@ -23,6 +23,7 @@
 
 /**
  * an arc by a start point, an intermediate point and an end point
+ * (with orientation)
  */
 class ArcBTPType
   : public ArgsParserObjectType
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/circle_imp.cc 
new/kig-16.08.0/objects/circle_imp.cc
--- old/kig-16.04.3/objects/circle_imp.cc       2016-04-28 00:33:28.000000000 
+0200
+++ new/kig-16.08.0/objects/circle_imp.cc       2016-04-28 00:34:52.000000000 
+0200
@@ -59,12 +59,12 @@
 
 void CircleImp::draw( KigPainter& p ) const
 {
-  p.drawCircle( mcenter, mradius );
+  p.drawCircle( mcenter, fabs( mradius ) );
 }
 
 bool CircleImp::contains( const Coordinate& p, int width, const KigWidget& w ) 
const
 {
-  return fabs((mcenter - p).length() - mradius) <= w.screenInfo().normalMiss( 
width );
+  return fabs((mcenter - p).length() - fabs( mradius )) <= 
w.screenInfo().normalMiss( width );
 }
 
 bool CircleImp::inRect( const Rect& r, int width, const KigWidget& w ) const
@@ -78,9 +78,9 @@
 
   // we allow a miss of some pixels ..
   double miss = w.screenInfo().normalMiss( width );
-  double bigradius = mradius + miss;
+  double bigradius = fabs( mradius ) + miss;
   bigradius *= bigradius;
-  double smallradius = mradius - miss;
+  double smallradius = fabs( mradius ) - miss;
   smallradius *= smallradius;
 
   const int in = -1;
@@ -212,7 +212,12 @@
 
 double CircleImp::radius() const
 {
-  return mradius;
+  return fabs( mradius );
+}
+
+double CircleImp::orientation() const
+{
+  return (mradius > 0)?1:(-1);
 }
 
 double CircleImp::surface() const
@@ -369,6 +374,6 @@
 
 Rect CircleImp::surroundingRect() const
 {
-  Coordinate d( mradius, mradius );
+  Coordinate d( fabs( mradius ), fabs( mradius ) );
   return Rect( mcenter - d, mcenter + d );
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/circle_imp.h 
new/kig-16.08.0/objects/circle_imp.h
--- old/kig-16.04.3/objects/circle_imp.h        2016-04-28 00:33:28.000000000 
+0200
+++ new/kig-16.08.0/objects/circle_imp.h        2016-04-28 00:34:52.000000000 
+0200
@@ -74,6 +74,10 @@
    */
   double radius() const;
   /**
+   * Return the orientation of this circle.
+   */
+  double orientation() const;
+  /**
    * Return the square radius of this circle.  Use this in preference
    * to sqr( radius() ).
    */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/circle_type.cc 
new/kig-16.08.0/objects/circle_type.cc
--- old/kig-16.04.3/objects/circle_type.cc      2016-04-28 00:33:28.000000000 
+0200
+++ new/kig-16.08.0/objects/circle_type.cc      2016-04-28 00:34:52.000000000 
+0200
@@ -61,12 +61,6 @@
   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,6 +82,12 @@
 {
 }
 
+const CircleBTPType* CircleBTPType::instance()
+{
+  static const CircleBTPType t;
+  return &t;
+}
+
 ObjectImp* CircleBTPType::calc( const Args& args, const KigDocument& ) const
 {
   if ( ! margsparser.checkArgs( args, 2 ) ) return new InvalidImp;
@@ -131,7 +131,18 @@
 
   const Coordinate center = calcCenter( a, b, c );
   if ( center.valid() )
-    return new CircleImp( center, (center - a ).length() );
+  {
+    /* this is also done in calcCenter... should optimize in some way */
+    double xdo = b.x-a.x;
+    double ydo = b.y-a.y;
+
+    double xao = c.x-a.x;
+    double yao = c.y-a.y;
+
+    double determinant = (xdo * yao - xao * ydo);
+    if (determinant > 0) return new CircleImp( center, (center - a ).length() 
);
+      else return new CircleImp( center, -(center - a ).length() );
+  }
 
   /*
    * case of collinear points, we need to identify the intermediate one
@@ -141,7 +152,7 @@
   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;
+  double d, axy, bxy, cxy;
 
   /* decide whether to work with x coordinate or y coordinate */
 
@@ -150,30 +161,30 @@
     axy = a.x;
     bxy = b.x;
     cxy = c.x;
+    d = xmax - xmin;
   } else
   {
     axy = a.y;
     bxy = b.y;
     cxy = c.y;
+    d = ymax - ymin;
   }
 
-  /*
-   * 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( axy - cxy ) >= d ) // b between a and c
+    return new LineImp( a, c );
+  if ( fabs( cxy - bxy ) >= d ) // a between c and b
+    return new LineImp( c, b );
 
-  if ( fabs( t ) < 1e-6  || fabs( 1.0 - t ) < 1e-6 ) return new InvalidImp;
+  // otherwise: c between b and a
+  return new LineImp( b, a);
 
   /*
-   * t < 0:     a between c and b
-   * 0 < t < 1: b between a and c
-   * t > 1:     c between a and b
+   * mp: note that the orientation of the new line is from a to c
+   * if b is intermediate, otherwise it is reversed whenever
+   * two of the three points cross each-other.
+   * This should give consistent results when intersecting circles that
+   * degenerate into lines
    */
-  if ( t < 0.0 ) return new LineImp( c, b );
-  if ( t > 1.0 ) return new LineImp( a, b );
-  return new LineImp( a, c );
 }
 
 const ObjectImpType* CircleBCPType::resultId() const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/circle_type.h 
new/kig-16.08.0/objects/circle_type.h
--- old/kig-16.04.3/objects/circle_type.h       2016-04-28 00:33:28.000000000 
+0200
+++ new/kig-16.08.0/objects/circle_type.h       2016-04-28 00:34:52.000000000 
+0200
@@ -51,7 +51,7 @@
 };
 
 /**
- * Circle by three points
+ * Circle by three points (with orientation)
  */
 class CircleBTPType
   : public ArgsParserObjectType
@@ -66,4 +66,5 @@
   const ObjectImpType* resultId() const;
 };
 
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/intersection_types.cc 
new/kig-16.08.0/objects/intersection_types.cc
--- old/kig-16.04.3/objects/intersection_types.cc       2016-04-28 
00:33:28.000000000 +0200
+++ new/kig-16.08.0/objects/intersection_types.cc       2016-04-28 
00:34:52.000000000 +0200
@@ -57,6 +57,32 @@
 
 ObjectImp* ConicLineIntersectionType::calc( const Args& parents, const 
KigDocument& doc ) const
 {
+  /*
+   * special case of a circle that degenerates into a line.  This is possible 
e.g. for
+   * circles 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();
@@ -70,7 +96,7 @@
     // easy case..
     const CircleImp* c = static_cast<const CircleImp*>( parents[0] );
     ret = calcCircleLineIntersect(
-      c->center(), c->squareRadius(), line, side );
+      c->center(), c->squareRadius(), line, c->orientation()*side );
   }
   else
   {
@@ -493,6 +519,41 @@
 
 ObjectImp* CircleCircleIntersectionType::calc( const Args& parents, const 
KigDocument& ) const
 {
+  if ( parents.size() == 3 &&
+       ( parents[0]->inherits( LineImp::stype() ) || parents[1]->inherits( 
LineImp::stype() ) ) &&
+       parents[2]->inherits( IntImp::stype() ) )
+  {
+    /* This the special case when one or both circles degenerate into a line
+     */
+    int il = 0;
+    int ori = 1;
+    if ( parents[1]->inherits( LineImp::stype() ) ) { il = 1; ori = -1; }
+    const LineData line = static_cast<const AbstractLineImp*>( parents[il] 
)->data();
+    int side = static_cast<const IntImp*>( parents[2] )->data();
+    assert( side == 1 || side == -1 );
+    if ( parents[1 - il]->inherits( CircleImp::stype() ) )
+    {
+      const CircleImp* c = static_cast<const CircleImp*>( parents[1 - il] );
+      const Coordinate o = c->center();
+      const double rsq = c->squareRadius();
+      ori *= c->orientation();
+      Coordinate ret = calcCircleLineIntersect( o, rsq, line, ori*side );
+      if ( ret.valid() ) return new PointImp( ret );
+      else return new InvalidImp;
+    } else {
+      // same code as for ConicLineIntersection with degenerate conic
+      assert (il == 1);
+      const LineData degline = static_cast<const AbstractLineImp*>( parents[0] 
)->data();
+      const double vecprod = degline.dir().y * line.dir().x - degline.dir().x 
* line.dir().y;
+      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();
@@ -501,12 +562,13 @@
   const CircleImp* c2 = static_cast<const CircleImp*>( parents[1] );
   const Coordinate o1 = c1->center();
   const Coordinate o2 = c2->center();
+  const int ori = ( c1->orientation()*c2->orientation() < 0 )?(-1):(1);
   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 );
+  Coordinate ret = calcCircleLineIntersect( o1, r1sq, line, ori*side );
   if ( ret.valid() ) return new PointImp( ret );
   else return new InvalidImp;
 }
@@ -544,6 +606,32 @@
 
 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();
@@ -553,7 +641,7 @@
   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;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/other_imp.cc 
new/kig-16.08.0/objects/other_imp.cc
--- old/kig-16.04.3/objects/other_imp.cc        2016-04-28 00:33:28.000000000 
+0200
+++ new/kig-16.08.0/objects/other_imp.cc        2016-04-28 00:34:52.000000000 
+0200
@@ -346,7 +346,7 @@
   if ( ! t.isHomothetic() )
   {
     //CircleImp support = CircleImp( mcenter, mradius );
-    ConicCartesianData data = CircleImp( mcenter, mradius ).cartesianData();
+    ConicCartesianData data = CircleImp( mcenter, fabs( mradius ) 
).cartesianData();
     //return new InvalidImp();
     ConicArcImp conicarc = ConicArcImp( data, msa, ma );
     return conicarc.transform ( t );
@@ -373,7 +373,7 @@
 
 void ArcImp::draw( KigPainter& p ) const
 {
-  p.drawArc( mcenter, mradius, msa, ma );
+  p.drawArc( mcenter, fabs( mradius ), msa, ma );
 }
 
 bool ArcImp::contains( const Coordinate& p, int width, const KigWidget& w ) 
const
@@ -467,7 +467,7 @@
   else if ( which == Parent::numberOfProperties() + numprop++ )
     return new PointImp( mcenter );
   else if ( which == Parent::numberOfProperties() + numprop++ )
-    return new DoubleImp( mradius );
+    return new DoubleImp( fabs( mradius ) );
   else if ( which == Parent::numberOfProperties() + numprop++ )
     return new AngleImp( mcenter, msa, ma, false );
   else if ( which == Parent::numberOfProperties() + numprop++ )
@@ -477,7 +477,7 @@
   else if ( which == Parent::numberOfProperties() + numprop++ )
     return new DoubleImp( sectorSurface() );
   else if ( which == Parent::numberOfProperties() + numprop++ )
-    return new DoubleImp( mradius * ma );
+    return new DoubleImp( fabs( mradius ) * ma );
   else if ( which == Parent::numberOfProperties() + numprop++ )
     return new CircleImp( mcenter, mradius );
   else if ( which == Parent::numberOfProperties() + numprop++ )
@@ -517,13 +517,15 @@
 //
   angle = max( 0., min( angle, ma ) );
   angle /= ma;
+  if ( mradius < 0 ) angle = 1.0 - angle;  // this is to avoid abrupt jumps 
when an ArcBTPType changes concavity
   return angle;
 }
 
 const Coordinate ArcImp::getPoint( double p, const KigDocument& ) const
 {
+  if ( mradius < 0 ) p = 1.0 - p;  // this is to avoid abrupt jumps when an 
ArcBTPType changes concavity
   double angle = msa + p * ma;
-  Coordinate d = Coordinate( cos( angle ), sin( angle ) ) * mradius;
+  Coordinate d = Coordinate( cos( angle ), sin( angle ) ) * fabs( mradius );
   return mcenter + d;
 }
 
@@ -534,7 +536,12 @@
 
 double ArcImp::radius() const
 {
-  return mradius;
+  return fabs( mradius );
+}
+
+double ArcImp::orientation() const
+{
+  return ( mradius >= 0)?1:(-1);
 }
 
 double ArcImp::startAngle() const
@@ -549,14 +556,18 @@
 
 Coordinate ArcImp::firstEndPoint() const
 {
-  double angle = msa;
-  return mcenter + Coordinate( cos( angle ), sin( angle ) ) * mradius;
+  /**
+   * mp: We take advantage of the arc orientation (mainly for the benefit of 
arc through 3 points)
+   * in order to avoid abrupt jumps when moving points
+   */
+  const double angle = mradius >= 0 ? msa : msa+ma;
+  return mcenter + Coordinate( cos( angle ), sin( angle ) ) * fabs( mradius );
 }
 
 Coordinate ArcImp::secondEndPoint() const
 {
-  double angle = msa + ma;
-  return mcenter + Coordinate( cos( angle ), sin( angle ) ) * mradius;
+  const double angle = mradius >= 0 ? msa+ma : msa;
+  return mcenter + Coordinate( cos( angle ), sin( angle ) ) * fabs( mradius );
 }
 
 const Coordinate VectorImp::a() const
@@ -663,7 +674,7 @@
 
 bool ArcImp::internalContainsPoint( const Coordinate& p, double threshold ) 
const
 {
-  return isOnArc( p, mcenter, mradius, msa, ma, threshold );
+  return isOnArc( p, mcenter, fabs( mradius ), msa, ma, threshold );
 }
 
 bool AngleImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
@@ -724,13 +735,13 @@
   // points, and all extreme x and y positions in between.
   //Rect ret( mcenter, 0, 0 );
   double a = msa;
-  //ret.setContains( mcenter + mradius*Coordinate( cos( a ), sin( a ) ) );
-  Rect ret ( mcenter + mradius*Coordinate( cos( a ), sin( a ) ), 0, 0 );
+  //ret.setContains( mcenter + fabs( mradius )*Coordinate( cos( a ), sin( a ) 
) );
+  Rect ret ( mcenter + fabs( mradius )*Coordinate( cos( a ), sin( a ) ), 0, 0 
);
   a = msa + ma;
-  ret.setContains( mcenter + mradius*Coordinate( cos( a ), sin( a ) ) );
+  ret.setContains( mcenter + fabs( mradius )*Coordinate( cos( a ), sin( a ) ) 
);
   for ( a = -2*M_PI; a <= 2*M_PI; a+=M_PI/2 )
   {
-    Coordinate d = mcenter + mradius*Coordinate( cos( a ), sin( a ) );
+    Coordinate d = mcenter + fabs( mradius )*Coordinate( cos( a ), sin( a ) );
     if ( msa <= a && a <= msa + ma )
       ret.setContains( d );
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kig-16.04.3/objects/other_imp.h 
new/kig-16.08.0/objects/other_imp.h
--- old/kig-16.04.3/objects/other_imp.h 2016-04-28 00:33:28.000000000 +0200
+++ new/kig-16.08.0/objects/other_imp.h 2016-04-28 00:34:52.000000000 +0200
@@ -220,6 +220,10 @@
    */
   double radius() const;
   /**
+   * Return the orientation of this arc (usually > 0)
+   */
+  double orientation() const;
+  /**
    * Return the start angle in radians of this arc.
    */
   double startAngle() const;


Reply via email to