Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Scene2D/ScenePoint2D.cpp @ 1804:5a872e69c74f
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 May 2021 14:48:51 +0200 |
parents | |
children | 3889ae96d2e9 |
comparison
equal
deleted
inserted
replaced
1803:d1849468729b | 1804:5a872e69c74f |
---|---|
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-2021 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 Lesser 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 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with this program. If not, see | |
19 * <http://www.gnu.org/licenses/>. | |
20 **/ | |
21 | |
22 | |
23 #include "ScenePoint2D.h" | |
24 | |
25 | |
26 namespace OrthancStone | |
27 { | |
28 ScenePoint2D ScenePoint2D::Apply(const AffineTransform2D& t) const | |
29 { | |
30 double x = x_; | |
31 double y = y_; | |
32 t.Apply(x, y); | |
33 return ScenePoint2D(x, y); | |
34 } | |
35 | |
36 | |
37 const ScenePoint2D ScenePoint2D::operator-(const ScenePoint2D& a) const | |
38 { | |
39 ScenePoint2D v; | |
40 v.x_ = x_ - a.x_; | |
41 v.y_ = y_ - a.y_; | |
42 return v; | |
43 } | |
44 | |
45 | |
46 const ScenePoint2D ScenePoint2D::operator+(const ScenePoint2D& a) const | |
47 { | |
48 ScenePoint2D v; | |
49 v.x_ = x_ + a.x_; | |
50 v.y_ = y_ + a.y_; | |
51 return v; | |
52 } | |
53 | |
54 | |
55 const ScenePoint2D ScenePoint2D::operator*(double a) const | |
56 { | |
57 ScenePoint2D v; | |
58 v.x_ = x_ * a; | |
59 v.y_ = y_ * a; | |
60 return v; | |
61 } | |
62 | |
63 | |
64 const ScenePoint2D ScenePoint2D::operator/(double a) const | |
65 { | |
66 ScenePoint2D v; | |
67 v.x_ = x_ / a; | |
68 v.y_ = y_ / a; | |
69 return v; | |
70 } | |
71 | |
72 | |
73 void ScenePoint2D::MidPoint(ScenePoint2D& result, | |
74 const ScenePoint2D& a, | |
75 const ScenePoint2D& b) | |
76 { | |
77 result.x_ = 0.5 * (a.x_ + b.x_); | |
78 result.y_ = 0.5 * (a.y_ + b.y_); | |
79 } | |
80 | |
81 | |
82 double ScenePoint2D::Dot(const ScenePoint2D& a, const ScenePoint2D& b) | |
83 { | |
84 return a.x_ * b.x_ + a.y_ * b.y_; | |
85 } | |
86 | |
87 | |
88 double ScenePoint2D::SquaredMagnitude(const ScenePoint2D& v) | |
89 { | |
90 return v.x_ * v.x_ + v.y_ * v.y_; | |
91 } | |
92 | |
93 | |
94 double ScenePoint2D::Magnitude(const ScenePoint2D& v) | |
95 { | |
96 double squaredMagnitude = SquaredMagnitude(v); | |
97 | |
98 if (LinearAlgebra::IsCloseToZero(squaredMagnitude)) | |
99 { | |
100 return 0.0; | |
101 } | |
102 else | |
103 { | |
104 return sqrt(squaredMagnitude); | |
105 } | |
106 } | |
107 | |
108 | |
109 double ScenePoint2D::SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) | |
110 { | |
111 ScenePoint2D n = b - a; | |
112 return Dot(n, n); | |
113 } | |
114 | |
115 | |
116 double ScenePoint2D::DistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) | |
117 { | |
118 double squaredDist = SquaredDistancePtPt(a, b); | |
119 return sqrt(squaredDist); | |
120 } | |
121 | |
122 | |
123 double ScenePoint2D::SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p) | |
124 { | |
125 // Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/ | |
126 | |
127 ScenePoint2D n = b - a; | |
128 ScenePoint2D pa = a - p; | |
129 | |
130 double c = Dot(n, pa); | |
131 | |
132 // Closest point is a | |
133 if (c > 0.0) | |
134 { | |
135 return Dot(pa, pa); | |
136 } | |
137 | |
138 ScenePoint2D bp = p - b; | |
139 | |
140 // Closest point is b | |
141 if (Dot(n, bp) > 0.0) | |
142 { | |
143 return Dot(bp, bp); | |
144 } | |
145 | |
146 // if segment length is very short, we approximate distance to the | |
147 // distance with a | |
148 double nq = Dot(n, n); | |
149 if (LinearAlgebra::IsCloseToZero(nq)) | |
150 { | |
151 // segment is very small: approximate distance from point to segment | |
152 // with distance from p to a | |
153 return Dot(pa, pa); | |
154 } | |
155 else | |
156 { | |
157 // Closest point is between a and b | |
158 ScenePoint2D e = pa - n * (c / nq); | |
159 return Dot(e, e); | |
160 } | |
161 } | |
162 } |