NDEVR
API Documentation
Distance.hpp
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: Distance
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/Polygon.h>
34#include <NDEVR/Polyline.h>
35#include <NDEVR/Plane.h>
36#include <NDEVR/Intersection.h>
37namespace NDEVR
38{
44 {};
45 template<uint01 t_dims, class t_type, class t_vertex>
46 t_type distanceSquared(const Bounds<t_dims, t_type, t_vertex>& bounds, const Vector<t_dims, t_type>& vertex)
47 {
48 t_type distance = 0;
49 for (uint01 dim = 0; dim < t_dims; ++dim)
50 {
51 if (vertex[dim] < bounds[MIN][dim])
52 {
53 t_type val = bounds[MIN][dim] - vertex[dim];
54 distance += val * val;
55 }
56 else if (vertex[dim] > bounds[MAX][dim] )
57 {
58 t_type val = vertex[dim] - bounds[MAX][dim];
59 distance += val * val;
60 }
61 }
62 return distance;
63 }
64 template<uint01 t_dims, class t_type, class t_vertex>
65 t_type distanceSquared(const Vector<t_dims, t_type>& vertex, const Bounds<t_dims, t_type, t_vertex>& bounds)
66 {
67 return distanceSquared(bounds, vertex);
68 }
69
70
71 template<uint01 t_dims, class t_type, class t_vertex_a, class t_vertex_b>
72 t_type distanceSquared(const LineSegment<t_dims, t_type, t_vertex_a>& line, const Bounds<t_dims, t_type, t_vertex_b>& bounds)
73 {
74 if (bounds.contains(line))
75 return cast<t_type>(0);
76 Vector<t_dims, t_type> p = line.vertex(A);
77 Vector<t_dims, t_type> v = line.ray();
78 for (uint01 i = 0; i < t_dims; ++i)
79 {
80 if ( bounds.doesIntersect(line.vertex(A)[i] - bounds[MIN][i], line.vertex(B)[i] - bounds[MIN][i], line.vertex(A), v, i)
81 || bounds.doesIntersect(line.vertex(A)[i] - bounds[MAX][i], line.vertex(B)[i] - bounds[MAX][i], line.vertex(A), v, i))
82 return cast<t_type>(0);
83 }
84
85 Vector<t_dims, t_type> t1 = (bounds[MIN] - p) / v;
86 Vector<t_dims, t_type> t2 = (bounds[MAX] - p) / v;
87 t_type p1 = getMax(t_type(0), t1.template dimensionalValue<MIN>(), t2.template dimensionalValue<MIN>());
88 t_type p2 = getMax(t_type(0), getMin(t1.template dimensionalValue<MAX>(), t2.template dimensionalValue<MAX>()));
89 Vector<t_dims, t_type> val = getMin(getMax((p + v * p1 + p + v * p2) / t_type(2), bounds[MIN]), bounds[MAX]);
90 t_type t = getMax(t_type(0), ((val - p) * v).sum() / v.magnitudeSquared());
91 val = p + v * t - val;
92 return val.magnitudeSquared();
93 }
94
95 template<uint01 t_dims, class t_type, class t_vertex_a, class t_vertex_b>
96 t_type distanceSquared(const Bounds<t_dims, t_type, t_vertex_a>& bounds, const LineSegment<t_dims, t_type, t_vertex_b>& line)
97 {
98 return distanceSquared(line, bounds);
99 }
100
101 template<uint01 t_dims, class t_type, class t_vertex>
102 t_type distanceSquared(const Bounds<t_dims, t_type, t_vertex>& a, const Bounds<t_dims, t_type, t_vertex>& b)
103 {
104 t_type distance = 0;
105 for (uint01 dim = 0; dim < t_dims; ++dim)
106 {
107 if (a[MAX][dim] < b[MIN][dim])
108 {
109 t_type val = b[MIN][dim] - a[MAX][dim];
110 distance += val * val;
111 }
112 else if(a[MIN][dim] < b[MAX][dim])
113 {
114 t_type val = a[MIN][dim] - b[MAX][dim];
115 distance += val * val;
116 }
117 }
118 return distance;
119 }
120 template<uint01 t_dims, class t_type, class t_vertex>
121 t_type distanceSquared(const LineSegment<t_dims, t_type, t_vertex>& left, const LineSegment<t_dims, t_type, t_vertex>& right, const t_type& epsilon = cast<t_type>(0))
122 {
123 return left.template closestPoints<t_type>(right, epsilon).lengthSquared();
124 }
125
129 template<uint01 t_dims, class t_type, class t_vertex>
130 constexpr t_type distanceSquared(const Triangle<t_dims, t_type, t_vertex>& tri, const t_vertex& vertex)
131 {
132 return distanceSquared(vertex, ClosestPoint(tri, vertex));
133 }
134 template<uint01 t_dims, class t_type, class t_vertex>
135 constexpr t_type distanceSquared(const t_vertex& vertex, const Triangle<t_dims, t_type, t_vertex>& tri)
136 {
137 return distanceSquared(vertex, ClosestPoint(tri, vertex));
138 }
139 template<uint01 t_dims, class t_type, class t_vertex>
140 constexpr t_type distanceSquared(const LineSegment<t_dims, t_type, t_vertex>& line, const Triangle<t_dims, t_type, t_vertex>& tri)
141 {
142 if (classify(line, tri) != IntersectionTypes::e_outside)
143 {
144 return cast<t_type>(0);
145 }
146 t_type dist_a = distanceSquared(line, tri.edge(A, B));
147 t_type dist_b = distanceSquared(line, tri.edge(B, C));
148 t_type dist_c = distanceSquared(line, tri.edge(C, A));
149 return getMin(dist_a, dist_b, dist_c);
150 }
151 template<uint01 t_dims, class t_type, class t_vertex>
152 constexpr t_type distanceSquared(const Triangle<t_dims, t_type, t_vertex>& tri, const LineSegment<t_dims, t_type, t_vertex>& line)
153 {
154 return distanceSquared(line, tri);
155 }
156
157
158 template<uint01 t_dims, class t_type, class t_vertex>
159 constexpr t_type distanceSquared(const Bounds<t_dims, t_type, t_vertex>&, const Triangle<t_dims, t_type, t_vertex>&)
160 {
161 lib_assert(false, "Not yet finished");
162 return Constant<t_type>::Invalid;// distanceSquared(line, closestPoint(tri, line));
163 }
164 template<uint01 t_dims, class t_type, class t_vertex>
165 constexpr t_type distanceSquared(const Triangle<t_dims, t_type, t_vertex>&, const Bounds<t_dims, t_type, t_vertex>&)
166 {
167 lib_assert(false, "Not yet finished");
168 return Constant<t_type>::Invalid;// distanceSquared(line, closestPoint(tri, line));
169 }
170 template<class epsilon_type, uint01 t_dims, class t_type, class t_vertex>
171 constexpr t_type distance(const t_vertex& vertex, const LineSegment<t_dims, t_type, t_vertex>& line)
172 {
173 return sqrt(cast<epsilon_type>(distanceSquared(line, vertex)));
174 }
175 template<class t_type, class t_other_type>
176 t_type distanceSquared(const t_other_type& original_object, const Polygon<t_type>& poly)
177 {
178 auto object = original_object.template as<2, t_type>();
179 if (classify(poly, object) != IntersectionTypes::e_outside)
180 {
181 return cast<t_type>(0);
182 }
183 else
184 {
185 t_type min = Constant<t_type>::Max;
186 for (uint04 i = 0; i < poly.vertexCount(); i++)
187 {
188 const t_type current = distanceSquared(poly.edge(i), object);
189 if (current < min)
190 {
191 min = current;
192 }
193 }
194 return min;
195 }
196 }
197 template<class t_type, class t_other_type>
198 t_type distanceSquared(const Polygon<t_type>& poly, const t_other_type& original_object)
199 {
200 return distanceSquared(original_object, poly);
201 }
202
203 template<uint01 t_dims, class t_type, class t_other_type>
204 t_type distanceSquared(const t_other_type& original_object, const Polyline<t_dims, t_type>& poly)
205 {
206 t_type min = Constant<t_type>::Max;
207 if (poly.vertexCount() == 0)
208 return Constant<fltp08>::Invalid;
209 if (poly.vertexCount() == 1)
210 return distanceSquared(poly.vertex(0), original_object);;
211 for (uint04 i = 0; i < poly.vertexCount() - 1; i++)
212 {
213 const t_type current = distanceSquared(poly.segment(i), original_object);
214 if (current < min)
215 {
216 min = current;
217 }
218 }
219 return min;
220 }
221 template<uint01 t_dims, class t_type, class t_other_type>
222 t_type distanceSquared(const Polyline<t_dims, t_type>& poly, const t_other_type& original_object)
223 {
224 return distanceSquared(original_object, poly);
225 }
226 template<class t_precision, uint01 t_dims, class t_type, class t_vertex>
227 t_precision distance(const LineSegment<t_dims, t_type, t_vertex>& left, const LineSegment<t_dims, t_type, t_vertex>& right, t_precision epsilon = cast<t_precision>(0))
228 {
229 return sqrt(cast<t_precision>(distanceSquared(left, right, epsilon)));
230 }
231
232 template<uint01 t_dims, class t_type, class t_vertex>
233 constexpr t_type distance(const Plane<t_dims, t_type>& plane, const Vertex<t_dims, t_vertex>& vertex)
234 {
235 return abs(dot(plane.normal, vertex) + plane.d);
236 }
237 template<uint01 t_dims, class t_type, class t_vertex>
238 constexpr t_type distance(const Vertex<t_dims, t_vertex>& vertex, const Plane<t_dims, t_type>& plane)
239 {
240 return abs(dot(plane.normal, vertex) + plane.d);
241 }
242 template<uint01 t_dims, class t_type, class t_vertex>
243 constexpr t_type distanceSquared(const Plane<t_dims, t_type>& plane, const Vertex<t_dims, t_vertex>& vertex)
244 {
245 t_type d = distance(plane, vertex);
246 return d * d;
247 }
248 template<uint01 t_dims, class t_type, class t_vertex>
249 constexpr t_type distanceSquared(const Vertex<t_dims, t_vertex>& vertex, const Plane<t_dims, t_type>& plane)
250 {
251 t_type d = distance(plane, vertex);
252 return d * d;
253 }
254 template<class t_precision, uint01 t_dims, class t_type, class t_vertex>
255 constexpr t_type distance(const LineSegment<t_dims, t_type>& line, const Vector<t_dims, t_type>& vertex)
256 {
257 return sqrt(cast<t_precision>(distanceSquared(line, vertex)));
258 }
259
260 template<uint01 t_dims, class t_type, class t_vertex>
261 constexpr t_type distance(const Plane<t_dims, t_type>& plane, const Bounds<t_dims, t_vertex>& bounds)
262 {
263 const Vertex<t_dims, t_type> c = (bounds[MIN] + bounds[MAX]) * t_type(0.5);
264 const Vector<t_dims, t_type> e = (bounds[MAX] - bounds[MIN]) * t_type(0.5);
265
266 const t_type s = dot(plane.normal, c) + plane.d;
267 const t_type r = dot(abs(plane.normal), e);
268
269 return getMax(t_type(0), abs(s) - r);
270 }
271
272 template<uint01 t_dims, class t_type, class t_vertex>
273 constexpr t_type distance(const Bounds<t_dims, t_vertex>& bounds, const Plane<t_dims, t_type>& plane)
274 {
275 return distance(plane, bounds);
276 }
277
278 template<uint01 t_dims, class t_type, class t_vertex>
279 constexpr t_type distanceSquared(const Plane<t_dims, t_type>& plane, const Bounds<t_dims, t_vertex>& bounds)
280 {
281 auto d = distance(plane, bounds);;
282 return d * d;
283 }
284
285 template<uint01 t_dims, class t_type, class t_vertex>
286 constexpr t_type distanceSquared(const Bounds<t_dims, t_vertex>& bounds, const Plane<t_dims, t_type>& plane)
287 {
288 auto d = distance(plane, bounds);;
289 return d * d;
290 }
291}
292
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:54
Dummy class for including distance functions.
Definition Distance.hpp:44
Class: LineSegment.
Definition Line.hpp:52
Logic for a given plane or N-dimensions.
Definition Plane.hpp:53
An N-sided polygon.
Definition Polygon.hpp:55
A sequence of connected line segments defined by ordered vertices along a path.
Definition PolyLine.hpp:55
A three-vertex polygon representing a triangle in N-dimensional space.
Definition Triangle.hpp:142
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
A point in N-dimensional space, used primarily for spatial location information.
Definition Vertex.hpp:44
The primary namespace for the NDEVR SDK.
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator The only requirement is that t_type have > ...
t_type dot(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
t_type sqrt(const t_type &value)
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408