# HG changeset patch # User Benjamin Golinvaux # Date 1557820094 -7200 # Node ID 62f6ff016085bb2915efd51078a0c787d0fd6aab # Parent 200f7e1d57d1c4db7461731619519bfddc8bf2b3 Iteration in angle measuring tool. Text label is not ok and handles and arcs (and maybe angle sides) should not scale with zoom. diff -r 200f7e1d57d1 -r 62f6ff016085 Samples/Common/AngleMeasureTool.cpp --- 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); } } { diff -r 200f7e1d57d1 -r 62f6ff016085 Samples/Common/MeasureToolsToolbox.cpp --- 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(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; } diff -r 200f7e1d57d1 -r 62f6ff016085 Samples/Common/MeasureToolsToolbox.h --- 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); diff -r 200f7e1d57d1 -r 62f6ff016085 Samples/Sdl/TrackerSampleApp.cpp --- 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!";