changeset 651:62f6ff016085

Iteration in angle measuring tool. Text label is not ok and handles and arcs (and maybe angle sides) should not scale with zoom.
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 14 May 2019 09:48:14 +0200
parents 200f7e1d57d1
children 6646957eff7f
files Samples/Common/AngleMeasureTool.cpp Samples/Common/MeasureToolsToolbox.cpp Samples/Common/MeasureToolsToolbox.h Samples/Sdl/TrackerSampleApp.cpp
diffstat 4 files changed, 120 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/Samples/Common/AngleMeasureTool.cpp	Tue May 14 09:48:01 2019 +0200
+++ b/Samples/Common/AngleMeasureTool.cpp	Tue May 14 09:48:14 2019 +0200
@@ -160,9 +160,9 @@
         {
           PolylineSceneLayer::Chain chain;
 
-          AddArc(chain, GetScene(), side1End_, center_, side2End_, 
-            20.0*pixelToScene, true); //TODO: true means always clockwise
-          polylineLayer->AddChain(chain, true);
+          AddShortestArc(chain, GetScene(), side1End_, center_, side2End_, 
+            20.0*pixelToScene);
+          polylineLayer->AddChain(chain, false);
         }
       }
       {
--- a/Samples/Common/MeasureToolsToolbox.cpp	Tue May 14 09:48:01 2019 +0200
+++ b/Samples/Common/MeasureToolsToolbox.cpp	Tue May 14 09:48:14 2019 +0200
@@ -29,6 +29,11 @@
 
 namespace OrthancStone
 {
+  double RadiansToDegrees(double angleRad)
+  {
+    static const double factor = 180.0 / g_pi;
+    return angleRad * factor;
+  }
 
   void AddSquare(PolylineSceneLayer::Chain& chain,
     const Scene2D&      scene,
@@ -58,7 +63,7 @@
     chain.push_back(startRB);
     chain.push_back(startLB);
   }
-
+#if 0
   void AddArc(
       PolylineSceneLayer::Chain& chain
     , const Scene2D&      scene
@@ -75,11 +80,21 @@
       chain, scene, c, radiusS, p1cAngle, p2cAngle, 
       clockwise, subdivisionsCount);
   }
+#endif
 
-  double RadiansToDegrees(double angleRad)
+  void AddShortestArc(
+      PolylineSceneLayer::Chain& chain
+    , const Scene2D&             scene
+    , const ScenePoint2D&        p1
+    , const ScenePoint2D&        c
+    , const ScenePoint2D&        p2
+    , const double&              radiusS
+    , const int                  subdivisionsCount)
   {
-    static const double factor = 180.0 / g_pi;
-    return angleRad * factor;
+    double p1cAngle = atan2(p1.GetY() - c.GetY(), p1.GetX() - c.GetX());
+    double p2cAngle = atan2(p2.GetY() - c.GetY(), p2.GetX() - c.GetX());
+    AddShortestArc(
+      chain, scene, c, radiusS, p1cAngle, p2cAngle, subdivisionsCount);
   }
 
   void GetPositionOnBisectingLine(
@@ -100,6 +115,39 @@
     result = ScenePoint2D(posX, posY);
   }
    
+
+  void AddShortestArc(
+      PolylineSceneLayer::Chain&  chain
+    , const Scene2D&              scene
+    , const ScenePoint2D&         centerS
+    , const double&               radiusS
+    , const double                startAngleRad
+    , const double                endAngleRad
+    , const int                   subdivisionsCount)
+  {
+    // this gives a signed difference between angle which
+    // is the smallest difference (in magnitude) between 
+    // the angles
+    double delta = NormalizeAngle(endAngleRad-startAngleRad);
+
+    chain.clear();
+    chain.reserve(subdivisionsCount + 1);
+
+    double angleIncr = delta/static_cast<double>(subdivisionsCount);
+
+    double theta = startAngleRad;
+    for (int i = 0; i < subdivisionsCount + 1; ++i)
+    {
+      double offsetX = radiusS * cos(theta);
+      double offsetY = radiusS * sin(theta);
+      double pointX = centerS.GetX() + offsetX;
+      double pointY = centerS.GetY() + offsetY;
+      chain.push_back(ScenePoint2D(pointX, pointY));
+      theta += angleIncr;
+    }
+  }
+
+#if 0
   void AddArc(
       PolylineSceneLayer::Chain& chain
     , const Scene2D&      scene
@@ -145,6 +193,7 @@
       theta += angleIncr;
     }
   }
+#endif
 
   void AddCircle(PolylineSceneLayer::Chain& chain,
     const Scene2D&      scene,
@@ -179,9 +228,9 @@
   double NormalizeAngle(double angle)
   {
     double retAngle = angle;
-    while (retAngle < 0)
+    while (retAngle < -1.0*g_pi)
       retAngle += 2 * g_pi;
-    while (retAngle >= 2 * g_pi)
+    while (retAngle >= g_pi)
       retAngle -= 2 * g_pi;
     return retAngle;
   }
--- a/Samples/Common/MeasureToolsToolbox.h	Tue May 14 09:48:01 2019 +0200
+++ b/Samples/Common/MeasureToolsToolbox.h	Tue May 14 09:48:14 2019 +0200
@@ -34,8 +34,46 @@
     const ScenePoint2D& centerS,
     const double&       sideLength);
 
+
   /**
-    Creates an arc centered pm c that goes
+    Creates an arc centered on c that goes
+    - from a point r1:
+      - so that r1 belongs to the p1,c line
+      - so that the distance from c to r1 equals radius
+    - to a point r2:
+      - so that r2 belongs to the p2,c line
+      - so that the distance from c to r2 equals radius
+    - that follows the shortest among the two possible paths
+
+    Warning: the existing chain content will be wiped out.
+  */
+  void AddShortestArc(
+      PolylineSceneLayer::Chain&  chain
+    , const Scene2D&              scene
+    , const ScenePoint2D&         p1
+    , const ScenePoint2D&         c
+    , const ScenePoint2D&         p2
+    , const double&               radiusS
+    , const int                   subdivisionsCount = 63);
+
+  /**
+    Creates an arc (open curve) with "numSubdivisions" (N + 1 points) from 
+    start angle to end angle, by following the shortest arc.
+
+    Warning: the existing chain content will be wiped out.
+  */
+  void AddShortestArc(
+      PolylineSceneLayer::Chain&  chain
+    , const Scene2D&              scene
+    , const ScenePoint2D&         centerS
+    , const double&               radiusS
+    , const double                startAngleRad
+    , const double                endAngleRad
+    , const int                   subdivisionsCount = 63);
+
+#if 0
+  /**
+    Creates an arc centered on c that goes
     - from a point r1:
       - so that r1 belongs to the p1,c line
       - so that the distance from c to r1 equals radius
@@ -51,22 +89,22 @@
 
   void AddArc(
       PolylineSceneLayer::Chain& chain
-    , const Scene2D&      scene
-    , const ScenePoint2D& p1
-    , const ScenePoint2D& c
-    , const ScenePoint2D& p2
-    , const double&       radiusS
-    , const bool          clockwise
-    , const int           subdivisionsCount = 63);
-    
+    , const Scene2D&             scene
+    , const ScenePoint2D&        p1
+    , const ScenePoint2D&        c
+    , const ScenePoint2D&        p2
+    , const double&              radiusS
+    , const bool                 clockwise
+    , const int                  subdivisionsCount = 63);
+ 
   /**
-    Creates an arc (open curve) with "numSubdivisions"
-    (N + 1 points) from start angle to end angle.
+    Creates an arc (open curve) with "numSubdivisions" (N + 1 points) from 
+    start angle to end angle with the supplied radius.
 
-    if clockwise is true, the arc is drawn from start to end 
-    by increasing the angle values.
+    if clockwise is true, the arc is drawn from start to end by increasing the
+    angle values.
 
-    otherwise, the angle value decreases from start to end.
+    Otherwise, the angle value decreases from start to end.
 
     Warning: the existing chain content will be wiped out.
   */
@@ -79,7 +117,7 @@
     , const double        endAngleRad
     , const bool          clockwise
     , const int           subdivisionsCount = 63);
-
+#endif
   /**
     Creates a circle (closed curve) with "numSubdivisions"
     (N points)
@@ -94,7 +132,7 @@
 
   /**
     Adds or subtracts 2*pi as many times as need to shift the specified
-    angle to a value such as:   0 <= value < 2*pi
+    angle to a value such as: -pi <= value < pi
    */
   double NormalizeAngle(double angle);
 
--- a/Samples/Sdl/TrackerSampleApp.cpp	Tue May 14 09:48:01 2019 +0200
+++ b/Samples/Sdl/TrackerSampleApp.cpp	Tue May 14 09:48:14 2019 +0200
@@ -21,6 +21,7 @@
 #include "TrackerSampleApp.h"
 
 #include "../Common/CreateLineMeasureTracker.h"
+#include "../Common/CreateAngleMeasureTracker.h"
 
 #include "../../Applications/Sdl/SdlOpenGLWindow.h"
 
@@ -162,7 +163,8 @@
     else if (event.type == SDL_MOUSEBUTTONDOWN)
     {
       PointerEvent e;
-      e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y));
+      e.AddPosition(compositor.GetPixelCenterCoordinates(
+        event.button.x, event.button.y));
       if (activeTracker_)
       {
         activeTracker_->PointerDown(e);
@@ -257,9 +259,6 @@
           //LOG(TRACE) << "Creating RotateSceneTracker";
           return CreateSimpleTrackerAdapter(PointerTrackerPtr(
             new RotateSceneTracker(scene_, e)));
-        case GuiTool_LineMeasure:
-          return FlexiblePointerTrackerPtr(new CreateLineMeasureTracker(
-            scene_, undoStack_, measureTools_, e));
         case GuiTool_Pan:
           return CreateSimpleTrackerAdapter(PointerTrackerPtr(
             new PanSceneTracker(scene_, e)));
@@ -272,8 +271,12 @@
         //  return new CircleMeasureTracker(scene_, measureTools_, undoStack_, e);
         //case GuiTool_EllipseMeasure:
         //  return new EllipseMeasureTracker(scene_, measureTools_, undoStack_, e);
+        case GuiTool_LineMeasure:
+          return FlexiblePointerTrackerPtr(new CreateLineMeasureTracker(
+            scene_, undoStack_, measureTools_, e));
         case GuiTool_AngleMeasure:
-          LOG(ERROR) << "Not implemented yet!";
+          return FlexiblePointerTrackerPtr(new CreateAngleMeasureTracker(
+            scene_, undoStack_, measureTools_, e));
           return NULL;
         case GuiTool_CircleMeasure:
           LOG(ERROR) << "Not implemented yet!";