comparison OrthancStone/Sources/Scene2D/ScenePoint2D.h @ 1804:5a872e69c74f

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 May 2021 14:48:51 +0200
parents 9ac2a65d4172
children 3889ae96d2e9
comparison
equal deleted inserted replaced
1803:d1849468729b 1804:5a872e69c74f
21 21
22 22
23 #pragma once 23 #pragma once
24 24
25 #include "../Toolbox/AffineTransform2D.h" 25 #include "../Toolbox/AffineTransform2D.h"
26 #include "../Toolbox/LinearAlgebra.h"
27 26
28 namespace OrthancStone 27 namespace OrthancStone
29 { 28 {
30 class ScenePoint2D 29 class ScenePoint2D
31 { 30 {
39 y_(0) 38 y_(0)
40 { 39 {
41 } 40 }
42 41
43 ScenePoint2D(double x, 42 ScenePoint2D(double x,
44 double y) : 43 double y) :
45 x_(x), 44 x_(x),
46 y_(y) 45 y_(y)
47 { 46 {
48 } 47 }
49 48
55 double GetY() const 54 double GetY() const
56 { 55 {
57 return y_; 56 return y_;
58 } 57 }
59 58
60 ScenePoint2D Apply(const AffineTransform2D& t) const 59 ScenePoint2D Apply(const AffineTransform2D& t) const;
61 {
62 double x = x_;
63 double y = y_;
64 t.Apply(x, y);
65 return ScenePoint2D(x, y);
66 }
67 60
68 const ScenePoint2D operator-(const ScenePoint2D& a) const 61 const ScenePoint2D operator-(const ScenePoint2D& a) const;
69 {
70 ScenePoint2D v;
71 v.x_ = x_ - a.x_;
72 v.y_ = y_ - a.y_;
73 62
74 return v; 63 const ScenePoint2D operator+(const ScenePoint2D& a) const;
75 }
76 64
77 const ScenePoint2D operator+(const ScenePoint2D& a) const 65 const ScenePoint2D operator*(double a) const;
78 {
79 ScenePoint2D v;
80 v.x_ = x_ + a.x_;
81 v.y_ = y_ + a.y_;
82 66
83 return v; 67 const ScenePoint2D operator/(double a) const;
84 }
85 68
86 const ScenePoint2D operator*(double a) const 69 static void MidPoint(ScenePoint2D& result,
87 { 70 const ScenePoint2D& a,
88 ScenePoint2D v; 71 const ScenePoint2D& b);
89 v.x_ = x_ * a;
90 v.y_ = y_ * a;
91 72
92 return v; 73 static double Dot(const ScenePoint2D& a,
93 } 74 const ScenePoint2D& b);
94 75
95 const ScenePoint2D operator/(double a) const 76 static double SquaredMagnitude(const ScenePoint2D& v);
96 {
97 ScenePoint2D v;
98 v.x_ = x_ / a;
99 v.y_ = y_ / a;
100 77
101 return v; 78 static double Magnitude(const ScenePoint2D& v);
102 }
103 79
104 static void MidPoint(ScenePoint2D& result, const ScenePoint2D& a, const ScenePoint2D& b) 80 static double SquaredDistancePtPt(const ScenePoint2D& a,
105 { 81 const ScenePoint2D& b);
106 result.x_ = 0.5 * (a.x_ + b.x_);
107 result.y_ = 0.5 * (a.y_ + b.y_);
108 }
109 82
110 static double Dot(const ScenePoint2D& a, const ScenePoint2D& b) 83 static double DistancePtPt(const ScenePoint2D& a,
111 { 84 const ScenePoint2D& b);
112 return a.x_ * b.x_ + a.y_ * b.y_;
113 }
114 85
115 static double SquaredMagnitude(const ScenePoint2D& v) 86 // Distance from point p to [a,b] segment
116 { 87 static double SquaredDistancePtSegment(const ScenePoint2D& a,
117 return v.x_ * v.x_ + v.y_ * v.y_; 88 const ScenePoint2D& b,
118 } 89 const ScenePoint2D& p);
119
120 static double Magnitude(const ScenePoint2D& v)
121 {
122 double squaredMagnitude = SquaredMagnitude(v);
123 if (LinearAlgebra::IsCloseToZero(squaredMagnitude))
124 return 0.0;
125 return sqrt(squaredMagnitude);
126 }
127
128 static double SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b)
129 {
130 ScenePoint2D n = b - a;
131 return Dot(n, n);
132 }
133
134 static double DistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b)
135 {
136 double squaredDist = SquaredDistancePtPt(a, b);
137 return sqrt(squaredDist);
138 }
139
140 /**
141 Distance from point p to [a,b] segment
142
143 Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/
144 */
145 static double SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p)
146 {
147 ScenePoint2D n = b - a;
148 ScenePoint2D pa = a - p;
149
150 double c = Dot(n, pa);
151
152 // Closest point is a
153 if (c > 0.0)
154 return Dot(pa, pa);
155
156 ScenePoint2D bp = p - b;
157
158 // Closest point is b
159 if (Dot(n, bp) > 0.0)
160 return Dot(bp, bp);
161
162 // if segment length is very short, we approximate distance to the
163 // distance with a
164 double nq = Dot(n, n);
165 if (LinearAlgebra::IsCloseToZero(nq))
166 {
167 // segment is very small: approximate distance from point to segment
168 // with distance from p to a
169 return Dot(pa, pa);
170 }
171 else
172 {
173 // Closest point is between a and b
174 ScenePoint2D e = pa - n * (c / nq);
175 return Dot(e, e);
176 }
177 }
178 }; 90 };
179 } 91 }
180