diff Framework/Scene2D/ScenePoint2D.h @ 865:a29c13497557

Added operators to ScenePoint2D + highlight support on MouseOver for measuring tools
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 25 Jun 2019 15:24:13 +0200
parents 5c551f078c18
children c71ef52602a0
line wrap: on
line diff
--- a/Framework/Scene2D/ScenePoint2D.h	Mon Jun 24 19:07:34 2019 +0200
+++ b/Framework/Scene2D/ScenePoint2D.h	Tue Jun 25 15:24:13 2019 +0200
@@ -13,7 +13,7 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Affero General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  **/
@@ -22,7 +22,7 @@
 #pragma once
 
 #include "../Toolbox/AffineTransform2D.h"
-
+#include "../Toolbox/LinearAlgebra.h"
 
 namespace OrthancStone
 {
@@ -40,7 +40,7 @@
     }
 
     ScenePoint2D(double x,
-                 double y) :
+      double y) :
       x_(x),
       y_(y)
     {
@@ -63,5 +63,74 @@
       t.Apply(x, y);
       return ScenePoint2D(x, y);
     }
+
+    const ScenePoint2D operator-(const ScenePoint2D& a) const
+    {
+      ScenePoint2D v;
+      v.x_ = x_ - a.x_;
+      v.y_ = y_ - a.y_;
+
+      return v;
+    }
+
+    const ScenePoint2D operator*(double a) const
+    {
+      ScenePoint2D v;
+      v.x_ = x_ * a;
+      v.y_ = y_ * a;
+
+      return v;
+    }
+
+    static double Dot(const ScenePoint2D& a, const ScenePoint2D& b)
+    {
+      return a.x_ * b.x_ + a.y_ * b.y_;
+    }
+
+    static double SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b)
+    {
+      ScenePoint2D n = b - a;
+      return Dot(n, n);
+    }
+
+    /**
+    Distance from point p to [a,b] segment
+
+    Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/
+    */
+    static double SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p)
+    {
+      ScenePoint2D n = b - a;
+      ScenePoint2D pa = a - p;
+
+      double c = Dot(n, pa);
+
+      // Closest point is a
+      if (c > 0.0)
+        return Dot(pa, pa);
+
+      ScenePoint2D bp = p - b;
+
+      // Closest point is b
+      if (Dot(n, bp) > 0.0)
+        return Dot(bp, bp);
+
+      // if segment length is very short, we approximate distance to the
+      // distance with a
+      double nq = Dot(n, n);
+      if (LinearAlgebra::IsCloseToZero(nq))
+      {
+        // segment is very small: approximate distance from point to segment
+        // with distance from p to a
+        return Dot(pa, pa);
+      }
+      else
+      {
+        // Closest point is between a and b
+        ScenePoint2D e = pa - n * (c / nq);
+        return Dot(e, e);
+      }
+    }
   };
 }
+