Mercurial > hg > orthanc-stone
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 |