33#include <NDEVR/BaseValues.h>
34#include <NDEVR/Vertex.h>
35#include <NDEVR/LineSegment.h>
36#include <NDEVR/Triangle.h>
37#include <NDEVR/RadialObject.h>
52 template<u
int01 t_dims,
class t_type,
class t_vertex = Vertex<t_dims, t_type>>
53 class Bounds :
public Vector<2, t_vertex>
63 constexpr Bounds(
const t_vertex& vertex)
64 : Vector<2, t_vertex>(vertex, vertex)
77 constexpr Bounds(
const t_vertex& min,
const t_vertex& max)
78 :
Vector<2, t_vertex>(min, max)
80 constexpr Bounds(
const t_type& min_scaler,
const t_type& max_scaler)
81 : Vector<2, t_vertex>(t_vertex(min_scaler), t_vertex(max_scaler))
84 constexpr Bounds(
const Vector<2, t_vertex>& bounds)
85 : Vector<2, t_vertex>(bounds)
88 constexpr Bounds(
const Bounds& bounds_a,
const Bounds& bounds_b)
89 : Vector<2, t_vertex>(
getMin(bounds_a[MIN], bounds_b[MIN]),
getMax(bounds_a[MAX], bounds_b[MAX]))
92 constexpr Bounds(
const Bounds& bounds,
const t_vertex& vector)
93 : Vector<2, t_vertex>(
getMin(bounds[MIN], vector),
getMax(bounds[MAX], vector))
95 constexpr Bounds(
const LineSegment<t_dims, t_type, t_vertex>& line)
96 : Vector<2, t_vertex>(
getMin(line.vertex(A), line.vertex(B)),
getMax(line.vertex(A), line.vertex(B)))
99 constexpr Bounds(
const Triangle<t_dims, t_type, t_vertex>& tri)
100 : Vector<2, t_vertex>(
101 getMin(tri.vertex(A), tri.vertex(B), tri.vertex(C))
102 ,
getMax(tri.vertex(A), tri.vertex(B), tri.vertex(C)))
105 constexpr Bounds(
const RadialObject<t_dims, t_type, t_vertex>& radial)
106 : Vector<2, t_vertex>(radial.
center() - radial.radius(), radial.
center() + radial.radius())
113 constexpr Ray<t_dims, t_type>
span()
const
148 return span().product();
157 t_vertex side_lengths =
span();
158 for (
uint01 dim_a = 0; dim_a < t_dims; dim_a++)
160 for (
uint01 dim_b = 0; dim_b < t_dims; dim_b++)
164 area += side_lengths[dim_a] * side_lengths[dim_b];
177 constexpr void expand(
const t_type& expansion_scaler)
179 (*this)[MIN] -= expansion_scaler;
180 (*this)[MAX] += expansion_scaler;
189 constexpr void expand(
const t_vertex& expansion_vector)
201 constexpr Bounds<t_dims, t_type>
scale(
const Vector<t_dims, t_type>&
scale,
const Vector<t_dims, t_type>&
center)
const
205 return Bounds<t_dims, t_type>(
getMin(scale_a, scale_b),
getMax(scale_a, scale_b));
212 constexpr Bounds<t_dims, t_type>
scale(
const t_type&
scale,
const Vector<t_dims, t_type>&
center)
const
216 return Bounds<t_dims, t_type>(
getMin(scale_a, scale_b),
getMax(scale_a, scale_b));
219 constexpr Bounds<t_dims, t_type>
scale(
const t_type& center_scale)
const
222 t_vertex scale_a = Vector<2, t_vertex>::m_values[MIN].scale(center_scale, point);
223 t_vertex scale_b = Vector<2, t_vertex>::m_values[MAX].scale(center_scale, point);
225 return Bounds<t_dims, t_type>(scale_a, scale_b);
227 return Bounds<t_dims, t_type>(scale_b, scale_a);
235 template<u
int01 t_new_dims,
class t_new_type,
class t_new_vertex = Vertex<t_new_dims, t_new_type>>
236 constexpr decltype(
auto)
as(t_new_type extra_fill_value = t_new_type(0))
const
238 if constexpr (t_new_dims == t_dims
239 && std::is_same_v<t_new_type, t_type>
240 && std::is_same_v<t_new_vertex, t_vertex>)
242 return static_cast<const Bounds&
>(*this);
246 return Bounds<t_new_dims, t_new_type, t_new_vertex>(
260 template<
bool t_allow_bounds =
true,
uint01 tdims = t_dims
261 ,
typename =
typename std::enable_if<tdims == 1>::type>
262 constexpr bool contains(
const t_type & value)
const
266 return !(!(value >= (*this)[MIN][0]) || !(value <= (*this)[MAX][0]));
270 return !(!(value > (*this)[MIN][0]) || !(value < (*this)[MAX][0]));
282 template<
bool t_allow_bounds = true>
283 constexpr bool contains(
const t_vertex& vector)
const
287 for (
uint01 dim = 0; dim < t_dims; ++dim)
289 if (!(vector[dim] >= (*
this)[MIN][dim]) || !(vector[dim] <= (*
this)[MAX][dim]))
295 for (
uint01 dim = 0; dim < t_dims; ++dim)
297 if (!(vector[dim] > (*
this)[MIN][dim]) || !(vector[dim] < (*
this)[MAX][dim]))
318 template<
bool t_allow_bounds = true>
319 constexpr bool contains(
const Bounds& bounds)
const
323 for (
uint01 dim = 0; dim < t_dims; ++dim)
325 if (!(bounds[MIN][dim] >= (*
this)[MIN][dim]))
327 if (!(bounds[MAX][dim] <= (*
this)[MAX][dim]))
333 for (
uint01 dim = 0; dim < t_dims; ++dim)
335 if (!(bounds[MIN][dim] >(*
this)[MIN][dim]))
337 if (!(bounds[MAX][dim] < (*
this)[MAX][dim]))
356 template<
bool t_allow_bounds = true>
361 for (
uint01 dim = 0; dim < t_dims; ++dim)
363 if (!(line.
vertex(A)[dim] >= (*
this)[MIN][dim] && line.
vertex(B)[dim] >= (*
this)[MIN][dim]))
365 if (!(line.
vertex(A)[dim] <= (*
this)[MAX][dim] && line.
vertex(B)[dim] <= (*
this)[MAX][dim]))
371 for (
uint01 dim = 0; dim < t_dims; ++dim)
373 if (!(line.
vertex(A)[dim] > (*
this)[MIN][dim] && line.
vertex(B)[dim] > (*
this)[MIN][dim]))
375 if (!(line.
vertex(A)[dim] < (*
this)[MAX][dim] && line.
vertex(B)[dim] < (*
this)[MAX][dim]))
395 template<
bool t_allow_bounds = true>
398 for (
uint01 tri_index = A; tri_index <= C; tri_index++)
417 for (
uint01 dim = 0; dim < t_dims; ++dim)
419 if ((*
this)[MAX][dim] < vector[dim])
420 (*this)[MAX][dim] = vector[dim];
421 if ((*
this)[MIN][dim] > vector[dim])
422 (*this)[MIN][dim] = vector[dim];
425 template<u
int01 tdims = t_dims>
426 constexpr void addToBounds(
typename std::enable_if<tdims == 1, const t_type&>::type scaler)
428 for (
uint01 dim = 0; dim < tdims; ++dim)
430 if ((*
this)[MAX][dim] < scaler)
431 (*this)[MAX][dim] = scaler;
432 if ((*
this)[MIN][dim] > scaler)
433 (*this)[MIN][dim] = scaler;
451 for (
uint01 dim = 0; dim < t_dims; ++dim)
453 if ((*
this)[MAX][dim] < bounds[MAX][dim])
454 (*this)[MAX][dim] = bounds[MAX][dim];
455 if ((*
this)[MIN][dim] > bounds[MIN][dim])
456 (*this)[MIN][dim] = bounds[MIN][dim];
509 template<
bool t_allow_bounds = true>
534 t_vertex closest_edge;
535 for(
uint01 dim = 0; dim < t_dims; ++dim)
536 closest_edge[dim] =
abs(vertex[dim] - (*
this)[MIN][dim]) >
abs(vertex[dim] - (*
this)[MAX][dim]) ? (*this)[MAX][dim] : (*this)[MIN][dim];
556 t_vertex closest_vertex;
557 for(
uint01 dim = 0; dim < t_dims; ++dim)
558 closest_vertex[dim] = (vertex[dim] < (*
this)[MIN][dim]) ? (*this)[MIN][dim] : (vertex[dim] > (*this)[MAX][dim]) ? (*
this)[MAX][dim] : vertex[dim];
559 return closest_vertex;
578 t_vertex furthest_vertex;
579 for(
uint01 dim = 0; dim < t_dims; ++dim)
580 furthest_vertex[dim] =
abs(vertex[dim] - (*
this)[MIN][dim]) >
abs(vertex[dim] - (*
this)[MAX][dim]) ? (*this)[MIN][dim] : (*this)[MAX][dim];
581 return furthest_vertex;
602 constexpr bool doesIntersect(t_type distance_a, t_type distance_b,
const t_vertex& origin,
const Vector<t_dims, t_type>& ray,
uint01 exclusion_axis)
const
607 t_type unit_value = (-distance_a / (distance_b - distance_a));
608 for (
uint01 dim = 0; dim < exclusion_axis; ++dim)
610 t_type hit_location = origin[dim] + ray[dim] * unit_value;
611 if (hit_location < (*
this)[MIN][dim] || hit_location > (*
this)[MAX][dim])
614 for (
uint01 dim = exclusion_axis + 1; dim < t_dims; ++dim)
616 t_type hit_location = origin[dim] + ray[dim] * unit_value;
617 if (hit_location < (*
this)[MIN][dim] || hit_location > (*
this)[MAX][dim])
635 template<
class t_other_vertex_type>
636 constexpr bool intersects(
const Bounds<t_dims, t_type, t_other_vertex_type>& bounds)
const
638 for (
uint01 dim = 0; dim < t_dims; ++dim)
640 if (!((*
this)[MAX][dim] > bounds[MIN][dim] && (*
this)[MIN][dim] < bounds[MAX][dim]))
647 template<
class t_other_vertex_type>
654 const Vector<t_dims, t_type> ray = seg.
ray();
655 for (
uint01 i = 0; i < t_dims; ++i)
669 template<
bool t_allow_bounds = true>
672 t_type dist_squared = circle.
radius() * circle.
radius();
673 for (
uint01 dim = 0; dim < t_dims; ++dim)
675 if (circle.getCenter()[dim] < (*
this)[MIN][dim])
677 t_type value = circle.
center()[dim] - (*this)[MIN][dim];
678 dist_squared -= (value * value);
680 else if (circle.getCenter()[dim] > (*
this)[MAX][dim])
682 t_type value = circle.
center()[dim] - (*this)[MAX][dim];
683 dist_squared -= (value * value);
687 if (dist_squared < 0)
692 if (dist_squared <= 0)
706 if (
getMin((*
this)[MIN], (*
this)[MAX]) != (*
this)[MIN])
708 if (
getMax((*
this)[MIN], (*
this)[MAX]) != (*
this)[MAX])
719 t_vertex min = (*this)[MIN];
720 t_vertex max = (*this)[MAX];
721 (*this)[MIN] =
getMin(min, max);
722 (*this)[MAX] =
getMax(min, max);
726 (*this)[MAX] -= center_scale;
727 (*this)[MIN] -= center_scale;
734 template<u
int01 t_dims,
class t_type,
class t_vertex>
737 constexpr static Bounds<t_dims, t_type, t_vertex> Invalid{ Constant<t_type>::Invalid, Constant<t_type>::Invalid };
738 constexpr static Bounds<t_dims, t_type, t_vertex> Min{ Constant<t_type>::Max, Constant<t_type>::Min };
739 constexpr static Bounds<t_dims, t_type, t_vertex> Max{ Constant<t_type>::Min, Constant<t_type>::Max };
742 template<u
int01 t_dims,
class t_type,
class t_vertex>
745 for (
uint01 dim = 0; dim < 2; ++dim)
752 template<u
int01 t_dims,
class t_type,
class t_vertex>
755 for (
uint01 dim = 0; dim < 2; ++dim)
A specification of upper and lower bounds in N-dimensions.
constexpr void expand(const t_type &expansion_scaler)
Expands the given expansion scaler.
constexpr Bounds(const t_vertex &vertex)
Given the vector, creates bounds of size 0 where max and min are both equal to the vertex.
constexpr void expand(const t_vertex &expansion_vector)
Expands the given expansion scaler.
constexpr bool intersects(const Bounds< t_dims, t_type, t_other_vertex_type > &bounds) const
constexpr t_type span(uint01 dim) const
The side length of one axis of the bounds.
constexpr t_type surfaceArea() const
The surface area of the shape.
constexpr bool contains(const Triangle< t_dims, t_type, t_vertex > &tri) const
constexpr t_type volume() const
Returns the volume of the bounds.
constexpr void addToBounds(const t_vertex &vector)
constexpr void addToBounds(const Bounds &bounds)
constexpr bool contains(const LineSegment< t_dims, t_type, t_vertex > &line) const
Author: Tyler Parke.
constexpr void addToBounds(const LineSegment< t_dims, t_type, t_vertex > &line_segment)
constexpr t_type center(uint01 dim) const
Returns the center of the bounds in a single dimention.
constexpr t_vertex furthestValue(const t_vertex &vertex) const
constexpr bool doesIntersect(t_type distance_a, t_type distance_b, const t_vertex &origin, const Vector< t_dims, t_type > &ray, uint01 exclusion_axis) const
Checks for intersection of the ray from a given distance, excluding one axis.
constexpr Bounds< t_dims, t_type > scale(const Vector< t_dims, t_type > &scale, const Vector< t_dims, t_type > ¢er) const
Scales this geometry about a center point.
constexpr bool contains(const Bounds &bounds) const
constexpr decltype(auto) as(t_new_type extra_fill_value=t_new_type(0)) const
Casts this object into an object of different dimension or precision.
constexpr void addToBounds(const Triangle< t_dims, t_type, t_vertex > &triangle)
void ensureValid()
Ensures that this is a valid bounds object.
constexpr bool validate() const
Validates this object.
constexpr Bounds(const t_vertex ¢er, t_type size)
Given the center, creates bounds of size where max and min are both equal to the vertex + size and.
constexpr Vertex< t_dims, fltp08 > center() const
constexpr bool contains(const RadialObject< t_dims, t_type > &radial_object) const
constexpr bool intersects(const RadialObject< t_dims, t_type > &circle) const
Query if this object contains the given circle.
constexpr t_vertex closestEdge(const t_vertex &vertex) const
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds.
constexpr bool contains(const t_vertex &vector) const
Query if this object contains the given vector.
constexpr bool contains(const t_type &value) const
Query if this object contains the given value.
constexpr t_vertex closestValue(const t_vertex &vertex) const
constexpr const t_vertex & vertex(uint01 index) const
constexpr t_vertex ray() const
constexpr const t_vertex & center() const
constexpr t_type radius() const
A three-vertex polygon representing a triangle in N-dimensional space.
constexpr t_vertex & vertex(TriangleLocation triangle_node)
Vertices the given triangle node.
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
t_type m_values[t_dims]
The values[t dims].
The primary namespace for the NDEVR SDK.
static constexpr Angle< t_angle_type > & operator-=(Angle< t_angle_type > &angle, const Angle< t_angle_type > &sub)
Subtraction assignment operator for Angles.
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 > ...
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...