NDEVR
API Documentation
RadialObject.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: RadialObject
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/BaseValues.h>
34#include <NDEVR/Vertex.h>
35#include <NDEVR/VectorFunctions.h>
36#include "Matrix.hpp"
37
38namespace NDEVR
39{
40
50 template<uint01 t_dims, class t_type, class t_vertex = Vertex<t_dims, t_type>>
51 class RadialObject
52 {
53 public:
54 constexpr RadialObject(t_type r = 0)
55 : m_center(0)
56 , m_radius(r)
57 {}
58 constexpr RadialObject(const t_vertex& center, t_type radius)
59 : m_center(center)
60 , m_radius(radius)
61 {}
72
73 constexpr RadialObject(const t_vertex& vertex_a, const t_vertex& vertex_b, const t_vertex& vertex_c)
74 : m_center(Constant<t_type>::Invalid)
75 , m_radius(Constant<t_type>::Invalid)
76 {
77 static_assert(t_dims == 2, "Radial Object given 3 points must be defined in 2 dimensions");
78 const t_vertex A = vertex_a;
79 const t_vertex B = vertex_b;
80 const t_vertex C = vertex_c;
81
82 const t_type D = 2 * (A[X] * (B[Y] - C[Y]) + B[X] * (C[Y] - A[Y]) + C[X] * (A[Y] - B[Y]));
83 if (D == t_type(0))
84 return; // Degenerate / colinear
85
86 const t_type A_sq = A[X] * A[X] + A[Y] * A[Y];
87 const t_type B_sq = B[X] * B[X] + B[Y] * B[Y];
88 const t_type C_sq = C[X] * C[X] + C[Y] * C[Y];
89
90 const t_type Ux = (A_sq * (B[Y] - C[Y]) + B_sq * (C[Y] - A[Y]) + C_sq * (A[Y] - B[Y])) / D;
91 const t_type Uy = (A_sq * (C[X] - B[X]) + B_sq * (A[X] - C[X]) + C_sq * (B[X] - A[X])) / D;
92
93 m_center = t_vertex(Ux, Uy);
94 m_radius = distance<t_type>(m_center, vertex_a);
95 }
96
97
110 template<bool t_allow_bounds = true>
111 constexpr bool contains(const t_vertex& vector) const
112 {
113 if(t_allow_bounds)
114 return distanceSquared(m_center, vector) <= m_radius * m_radius;
115 else
116 return distanceSquared(m_center, vector) < m_radius * m_radius;
117 }
118
128
129 constexpr t_type radius() const {return m_radius;}
130
131
132
142 template<uint01 t_new_dims, class t_new_type, class t_new_vertex = Vertex<t_new_dims, t_new_type>>
143 constexpr RadialObject<t_new_dims, t_new_type> as() const
144 {
145 return RadialObject<t_new_dims, t_new_type>(t_new_vertex(m_center.template as<t_new_dims, t_new_type>()), cast<t_new_type>(m_radius));
146 }
147
157
158 [[nodiscard]] constexpr const t_vertex& center() const {return m_center;}
159
160 bool operator==(const RadialObject& rad) const
161 {
162 return m_radius == rad.m_radius && (m_center == rad.m_center);
163 }
164 bool operator!=(const RadialObject& rad) const
165 {
166 return m_radius != rad.m_radius || m_center != rad.m_center;
167 }
168 private:
170 t_vertex m_center;
172 t_type m_radius;
173 };
174
175 template<uint01 t_dims, class t_type, class t_vector>
176 struct Constant<RadialObject<t_dims, t_type, t_vector>>
177 {
178 constexpr const static RadialObject<t_dims, t_type, t_vector> Invalid{ Constant<t_vector>::Invalid, Constant<t_type>::Invalid };
179 constexpr const static RadialObject<t_dims, t_type, t_vector> Min{ t_vector(0), 0 };
180 constexpr const static RadialObject<t_dims, t_type, t_vector> Max{ t_vector(0), Constant<t_type>::Max};
181 };
182
187 template<uint01 t_dims, class t_type, class t_vertex = Vertex<t_dims, t_type>>
188 class BiRadialObject
189 {
190 public:
191 constexpr BiRadialObject(t_type r = 0)
192 : m_axis_major(Vector<t_dims, t_type>(0.0))
193 , m_radius(r)
194 {}
195 constexpr BiRadialObject(const t_vertex& p1, const t_vertex& p2, t_type radius)
196 : m_axis_major(p1, p2)
197 , m_radius(radius)
198 {}
199
200
201 template<class t_matrix_type = fltp08>
202 static BiRadialObject<t_dims, t_type, t_vertex> fromCircleTransform(const Matrix<t_matrix_type>& mat)
203 {
204 BiRadialObject<t_dims, t_type, t_vertex> object;
205 Vertex<3, fltp08> center = mat.decomposeOffset();
206 Ray<3, fltp08> direction = mat * Ray<3, fltp08>(0.5, 0, 0);
207
208 object.m_axis_major[A] = center + direction;
209 object.m_axis_major[B] = center - direction;
210
211 Vector<t_dims, t_type> scale = mat.decomposeScale();
212
213 object.m_radius = getMin(scale[X], scale[Y]);
214
215 return object;
216 }
229
230 constexpr bool contains(const t_vertex& vector) const
231 {
232 fltp08 total_distance = distance<fltp08>(m_axis_major[A], vector) + distance<fltp08>(m_axis_major[B], vector);
233 return m_radius > total_distance - distance<fltp08>(m_axis_major[A], m_axis_major[B]);
234 }
235
245
246 constexpr t_type radius() const { return m_radius; }
247
248
249
259 template<uint01 t_new_dims, class t_new_type>
260 constexpr BiRadialObject<t_new_dims, t_new_type> as() const
261 {
262 return BiRadialObject<t_new_dims, t_new_type>(m_axis_major[A].template as<t_new_dims, t_new_type>(), m_axis_major[B].template as<t_new_dims, t_new_type>(), cast<t_new_type>(m_radius));
263 }
264
274
275 constexpr t_vertex center() const { return t_vertex((m_axis_major[A] + m_axis_major[B]) / cast<t_type>(2)); }
276 constexpr const t_vertex& axisPoint(uint01 vertex) const
277 {
278 return m_axis_major[vertex];
279 }
280
281 template<class t_ratio_type = fltp08>
282 t_ratio_type minorToMajorRatio() const
283 {
284 const t_ratio_type axis_distance = distance<t_ratio_type>(m_axis_major[A], m_axis_major[B]);
285 return cast<t_ratio_type>(m_radius) / (cast<t_ratio_type>(m_radius) + axis_distance / cast<t_ratio_type>(2));
286 }
287 template<class t_matrix_type = fltp08>
288 Matrix<t_matrix_type> fromCircleTransform() const
289 {
290 Matrix<t_matrix_type> mat = Matrix<t_matrix_type>::ScalerMatrix(m_radius);
291 if (m_axis_major[B] - m_axis_major[A] == t_vertex(0))
292 return mat;
293 Vector<t_dims, t_type> axis = (m_axis_major[B] - m_axis_major[A]).template normalized<t_matrix_type>();
294 t_matrix_type scale = cast<t_matrix_type>(1) / minorToMajorRatio<t_matrix_type>();
295 mat = mat.scale(axis, scale);
296 return mat;
297 }
298 private:
300 Vector<2, t_vertex> m_axis_major;
302 t_type m_radius;
303 };
304};
constexpr bool contains(const t_vertex &vector) const
constexpr t_type radius() const
constexpr t_vertex center() const
constexpr BiRadialObject< t_new_dims, t_new_type > as() const
Templated logic for doing matrix multiplication.
Definition Matrix.hpp:182
A radial object.
constexpr RadialObject< t_new_dims, t_new_type > as() const
constexpr const t_vertex & center() const
constexpr t_type radius() const
constexpr bool contains(const t_vertex &vector) const
constexpr RadialObject(const t_vertex &vertex_a, const t_vertex &vertex_b, const t_vertex &vertex_c)
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...
double fltp08
Defines an alias representing an 8 byte floating-point number.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...