comparison OrthancStone/Sources/Scene2D/ScenePoint2D.h @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Scene2D/ScenePoint2D.h@7ec8fea061b9
children 8563ea5d8ae4
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #pragma once
23
24 #include "../Toolbox/AffineTransform2D.h"
25 #include "../Toolbox/LinearAlgebra.h"
26
27 namespace OrthancStone
28 {
29 class ScenePoint2D
30 {
31 private:
32 double x_;
33 double y_;
34
35 public:
36 ScenePoint2D() :
37 x_(0),
38 y_(0)
39 {
40 }
41
42 ScenePoint2D(double x,
43 double y) :
44 x_(x),
45 y_(y)
46 {
47 }
48
49 double GetX() const
50 {
51 return x_;
52 }
53
54 double GetY() const
55 {
56 return y_;
57 }
58
59 ScenePoint2D Apply(const AffineTransform2D& t) const
60 {
61 double x = x_;
62 double y = y_;
63 t.Apply(x, y);
64 return ScenePoint2D(x, y);
65 }
66
67 const ScenePoint2D operator-(const ScenePoint2D& a) const
68 {
69 ScenePoint2D v;
70 v.x_ = x_ - a.x_;
71 v.y_ = y_ - a.y_;
72
73 return v;
74 }
75
76 const ScenePoint2D operator+(const ScenePoint2D& a) const
77 {
78 ScenePoint2D v;
79 v.x_ = x_ + a.x_;
80 v.y_ = y_ + a.y_;
81
82 return v;
83 }
84
85 const ScenePoint2D operator*(double a) const
86 {
87 ScenePoint2D v;
88 v.x_ = x_ * a;
89 v.y_ = y_ * a;
90
91 return v;
92 }
93
94 const ScenePoint2D operator/(double a) const
95 {
96 ScenePoint2D v;
97 v.x_ = x_ / a;
98 v.y_ = y_ / a;
99
100 return v;
101 }
102
103 static void MidPoint(ScenePoint2D& result, const ScenePoint2D& a, const ScenePoint2D& b)
104 {
105 result.x_ = 0.5 * (a.x_ + b.x_);
106 result.y_ = 0.5 * (a.y_ + b.y_);
107 }
108
109 static double Dot(const ScenePoint2D& a, const ScenePoint2D& b)
110 {
111 return a.x_ * b.x_ + a.y_ * b.y_;
112 }
113
114 static double SquaredMagnitude(const ScenePoint2D& v)
115 {
116 return v.x_ * v.x_ + v.y_ * v.y_;
117 }
118
119 static double Magnitude(const ScenePoint2D& v)
120 {
121 double squaredMagnitude = SquaredMagnitude(v);
122 if (LinearAlgebra::IsCloseToZero(squaredMagnitude))
123 return 0.0;
124 return sqrt(squaredMagnitude);
125 }
126
127 static double SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b)
128 {
129 ScenePoint2D n = b - a;
130 return Dot(n, n);
131 }
132
133 static double DistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b)
134 {
135 double squaredDist = SquaredDistancePtPt(a, b);
136 return sqrt(squaredDist);
137 }
138
139 /**
140 Distance from point p to [a,b] segment
141
142 Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/
143 */
144 static double SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p)
145 {
146 ScenePoint2D n = b - a;
147 ScenePoint2D pa = a - p;
148
149 double c = Dot(n, pa);
150
151 // Closest point is a
152 if (c > 0.0)
153 return Dot(pa, pa);
154
155 ScenePoint2D bp = p - b;
156
157 // Closest point is b
158 if (Dot(n, bp) > 0.0)
159 return Dot(bp, bp);
160
161 // if segment length is very short, we approximate distance to the
162 // distance with a
163 double nq = Dot(n, n);
164 if (LinearAlgebra::IsCloseToZero(nq))
165 {
166 // segment is very small: approximate distance from point to segment
167 // with distance from p to a
168 return Dot(pa, pa);
169 }
170 else
171 {
172 // Closest point is between a and b
173 ScenePoint2D e = pa - n * (c / nq);
174 return Dot(e, e);
175 }
176 }
177 };
178 }
179