33#include <NDEVR/BaseValues.h>
34#include <NDEVR/Vertex.h>
35#include <NDEVR/VectorFunctions.h>
50 template<u
int01 t_dims,
class t_type,
class t_vertex = Vertex<t_dims, t_type>>
51 class LineSegment :
public Vector<2, t_vertex>
54 constexpr LineSegment()
56 constexpr LineSegment(
const t_vertex& p1,
const t_vertex& p2)
57 : Vector<2, t_vertex>(p1, p2)
59 explicit constexpr LineSegment(
const Vector<2, t_vertex>& line)
60 : Vector<2, t_vertex>(line)
72 template<u
int01 t_new_dims,
class t_new_type,
class t_new_vertex = Vertex<t_new_dims, t_new_type>>
73 constexpr LineSegment<t_new_dims, t_new_type, t_new_vertex>
as()
const
90 template<
class t_
inter_type>
91 constexpr inline t_vertex
pointAt(t_inter_type index)
const
123 constexpr inline t_vertex
ray()
const
191 template<
class t_precision = t_type>
192 constexpr bool isParallel(
const LineSegment<t_dims, t_type, t_vertex>& line, t_precision epsilon = 0)
const
196 return (
equals(ray_1, ray_2, epsilon) ||
equals(ray_1, -ray_2, epsilon));
213 template<
class t_precision = t_type>
214 constexpr bool isCollinear(
const LineSegment<t_dims, t_type>& line, t_precision epsilon = 0)
const
216 return isParallel<t_precision>(line, epsilon) && distanceSquared<t_precision>(line, epsilon) <= epsilon * epsilon;
233 template<
class t_precision = t_type>
234 constexpr bool isCollinear(
const t_vertex& vert, t_precision epsilon = t_precision(1e-10))
const
236 const Vector<t_dims, t_precision> ray_1(
vertex(B) -
vertex(A));
237 const Vector<t_dims, t_precision> ray_2(vert -
vertex(A));
238 const Vector<t_dims, t_precision> c =
cross(ray_1, ray_2);
257 template<
class t_precision,
class t_other_vertex>
258 constexpr LineSegment<t_dims, t_precision>
closestPoints(
const LineSegment<t_dims, t_type, t_other_vertex>& l2, t_precision epsilon = 0)
const
260 const Vector<t_dims, t_precision> u(
ray());
261 const Vector<t_dims, t_precision> v(l2.
ray());
262 const Vector<t_dims, t_precision> w(
vertex(A) - l2.
vertex(A));
264 const t_precision a(
dot(u, u));
265 const t_precision b(
dot(u, v));
266 const t_precision c(
dot(v, v));
268 const t_precision d(
dot(u, w));
269 const t_precision e(
dot(v, w));
271 const t_precision D((a * c) - (b * b));
282 if (sN <
static_cast<t_precision
>(0))
284 sN =
static_cast<t_precision
>(0);
297 sN =
static_cast<t_precision
>(0);
298 sD =
static_cast<t_precision
>(1);
303 if (tN <
static_cast<t_precision
>(0))
305 tN =
static_cast<t_precision
>(0);
308 sN =
static_cast<t_precision
>(0);
321 if ((-d + b) <
static_cast<t_precision
>(0))
322 sN =
static_cast<t_precision
>(0);
323 else if ((-d + b) > a)
333 t_precision sc =
abs(sN) <= epsilon ?
static_cast<t_precision
>(0) : sN / sD;
334 t_precision tc =
abs(sN) <= epsilon ?
static_cast<t_precision
>(0) : tN / tD;
339 return LineSegment<t_dims, t_precision>(
347 template<
bool t_clip = true>
350 const Vector<t_dims, t_type> ray_1 =
ray();
351 const Vector<t_dims, t_type> ray_2 = p -
vertex(A);
353 t_type
sum = (ray_1 * ray_2).
sum();
356 if (mag_squared != 0)
358 if constexpr (t_clip)
381 template<
class t_precision = t_type>
416 template<
class t_
inter_type>
417 constexpr LineSegment<t_dims, t_type>
scale(
const t_inter_type&
scale)
const
421 template<
class t_
inter_type>
427 constexpr LineSegment<t_dims, t_type> extend(
const t_type& extension)
const
430 return LineSegment<t_dims, t_type>(
vertex(A) - dx,
vertex(B) + dx);
432 constexpr LineSegment<t_dims, t_type> extend(
const t_type& a_extension,
const t_type& b_extension)
const
435 return LineSegment<t_dims, t_type>(
vertex(A) - (dx * a_extension),
vertex(B) + (dx * b_extension));
446 template<
class t_precision = t_type>
464 return ray().magnitudeSquared();
483 template<
class t_precision = t_type>
484 constexpr Vector<t_dims, t_precision>
intersection(
const LineSegment& r, t_precision epsilon = 0)
const
490 return Vector<t_dims, t_type>(Constant<t_type>::Invalid);
505 template<
class t_precision = t_type>
509 if(
IsValid(intersection_location))
511 return Constant<t_precision>::Invalid;
528 template<
class t_precision = t_type>
533 template<
class t_precision = t_type,
class t_vertex_type>
545 const t_precision zero = t_precision(0);
548 if (
abs(rxs) <= epsilon &&
abs(qpxr) <= epsilon)
550 const t_precision rr =
dot(r, r);
551 const t_precision t0 =
dot(qp, r) / rr;
552 const t_precision t1 = t0 +
dot(s, r) / rr;
553 const t_precision tmin =
getMin(t0, t1);
554 const t_precision tmax =
getMin(t0, t1);
555 return tmax >= zero && tmin <= t_precision(1);
559 if (
abs(rxs) <= epsilon)
564 const t_precision u = qpxr / rxs;
566 return (t >= -epsilon && t <= t_precision(1) + epsilon &&
567 u >= -epsilon && u <= t_precision(1) + epsilon);
582 template<
bool t_clip,
class t_precision>
586 return Constant<t_precision>::Invalid;
591 if (value >=
vertex(A)[dim])
593 else if (value <=
vertex(B)[dim])
598 if (value >=
vertex(B)[dim])
600 else if (value <=
vertex(A)[dim])
604 return (
vertex(A)[dim] - value) / ((value -
vertex(B)[dim]) + (
vertex(A)[dim] - value));
623 template<
bool t_clip,
class t_precision>
624 constexpr t_vertex
pointAt(t_precision value,
uint01 dim,
const t_vertex& nan_return = Constant<t_vertex>::Invalid)
const
632 if (value >=
vertex(A)[dim])
634 else if (value <=
vertex(B)[dim])
639 if (value >=
vertex(B)[dim])
641 else if (value <=
vertex(A)[dim])
645 const t_precision dt =
vertex(A)[dim] - value;
646 const t_precision dy = value -
vertex(B)[dim];
667 template<
class t_buffer_type>
670 if(vertices.size() < 2)
671 return Constant<LineSegment>::Invalid;
672 if(vertices.size() == 2)
673 return LineSegment(vertices[0], vertices[1]);
675 t_vertex total_vector(0);
676 t_type total_volume = 0;
677 t_type total_x_sqr = 0;
678 for(
uint04 i = 0; i < vertices.size(); i++)
680 total_vector += vertices[i];
681 total_x_sqr += vertices[i][dim_0] * vertices[i][dim_0];
682 total_volume += vertices[i][dim_0] * vertices[i][dim_1];
685 const t_type x_sqr = total_vector[dim_0] * total_vector[dim_0];
686 const t_type a = (total_vector[dim_1] * total_x_sqr - total_vector[dim_0] * total_volume) / (vertices.size() * total_x_sqr - x_sqr);
688 const t_type b = (vertices.size() * total_volume - total_vector[dim_0] * total_vector[dim_1]) / (vertices.size() * total_x_sqr - x_sqr);
690 const t_vertex p1(vertices[0]);
691 const t_vertex p2 = vertices.getLast();
692 p1[dim_1] = a + b * p1[dim_0];
693 p2[dim_1] = a + b * p2[dim_0];
695 return LineSegment(p1, p2);
715 template<u
int01 t_dims,
class t_type,
class t_vertex>
718 const t_vertex v_t(vertex - line.
vertex(A));
719 const t_type t =
dot(v_t, ray);
721 return v_t.magnitudeSquared();
722 else if (t >= dot_ray)
723 return distanceSquared(vertex, line.
vertex(B));
726 t_vertex vc = (ray * t) / dot_ray + line.
vertex(A);
727 return distanceSquared(vertex, vc);
744 template<u
int01 t_dims,
class t_type,
class t_vertex>
747 const t_vertex ray_value(line.
ray());
748 const t_type dot_ray =
dot(ray_value, ray_value);
767 template<u
int01 t_dims,
class t_type,
class t_vertex>
770 return distanceSquared(line, vertex);
790 template<u
int01 t_dims,
class t_type,
class t_vertex>
793 if (
equals(left[A], right[A], epsilon))
795 return (
equals(left[B], right[B], epsilon));
797 if (
equals(left[B], right[A], epsilon))
799 return (
equals(left[A], right[B], epsilon));
808 template<u
int01 t_dims,
class t_type>
809 static constexpr bool IsInvalid(
const LineSegment<t_dims, t_type>& value)
811 for (
uint01 dim = 0; dim < 2; ++dim)
818 template<u
int01 t_dims,
class t_type>
821 for (
uint01 dim = 0; dim < 2; ++dim)
828 template<u
int01 t_dims,
class t_type,
class t_vector>
831 constexpr const static LineSegment<t_dims, t_type> Invalid{ Constant<t_vector>::Invalid, Constant<t_vector>::Invalid };
832 constexpr const static LineSegment<t_dims, t_type> Min{ Constant<t_vector>::Min, Constant<t_vector>::Min };
833 constexpr const static LineSegment<t_dims, t_type> Max{ Constant<t_vector>::Max, Constant<t_vector>::Max };
constexpr t_vertex closestValue(const t_vertex &p) const
constexpr LineSegment< t_dims, t_type > scale(const t_inter_type &scale) const
Scales.
constexpr LineSegment< t_new_dims, t_new_type, t_new_vertex > as() const
constexpr t_type lengthSquared() const
constexpr t_precision getLocationAt(t_precision value, uint01 dim) const
constexpr Vector< t_dims, t_precision > intersection(const LineSegment &r, t_precision epsilon=0) const
Intersections.
constexpr t_precision intersectionPosition(const LineSegment< t_dims, t_type > &segment) const
constexpr const t_vertex & vertex(uint01 index) const
constexpr t_type closestPos(const t_vertex &p) const
Returns the closest value where 0 is.
static constexpr LineSegment createBestFitLine(const t_buffer_type &vertices, uint01 dim_0, uint01 dim_1)
Creates best fit line.
constexpr bool isCollinear(const t_vertex &vert, t_precision epsilon=t_precision(1e-10)) const
Query if the line is collinear with the given vertex.
constexpr t_vertex ray() const
constexpr t_precision length() const
constexpr LineSegment< t_dims, t_precision > closestPoints(const LineSegment< t_dims, t_type, t_other_vertex > &l2, t_precision epsilon=0) const
Closest vertices.
constexpr t_vertex pointAt(t_inter_type index) const
constexpr t_vertex midpoint() const
Gets the midpoint.
constexpr t_vertex & vertex(uint01 index)
constexpr t_vertex pointAt(t_precision value, uint01 dim, const t_vertex &nan_return=Constant< t_vertex >::Invalid) const
Point at.
constexpr bool isParallel(const LineSegment< t_dims, t_type, t_vertex > &line, t_precision epsilon=0) const
Query if 'line' is parallel.
constexpr t_vertex center() const
constexpr bool isCollinear(const LineSegment< t_dims, t_type > &line, t_precision epsilon=0) const
Query if 'line' is collinear.
constexpr bool intersects(const LineSegment< 3, t_type > &segment, t_precision epsilon=cast< t_precision >(1e-9)) const
Query if this object intersects the given segment.
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
constexpr t_type sum() const
constexpr Vector< t_dims, t_norm_type > normalized(Vector< t_dims, t_norm_type > value_if_nan=Constant< Vector< t_dims, t_norm_type > >::Invalid) const
constexpr t_type magnitudeSquared() const
Vectors are commonly used to model forces such as wind, sea current, gravity, and electromagnetism.
constexpr t_type & operator[](uint01 dimension_index)
Accesses the value of a certain dimension.
constexpr t_magnitude_type magnitude() const
Vectors are commonly used to model forces such as wind, sea current, gravity, and electromagnetism.
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 > ...
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
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...
constexpr Vector< 1, t_type > cross(const Vector< 1, t_type > &, const Vector< 1, t_type > &)
constexpr t_type distanceSquaredOptimized(const LineSegment< t_dims, t_type, t_vertex > &line, const t_vertex &vertex, const t_vertex &ray, const t_type &dot_ray)
Distance squared optimized.
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 bool equals(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))
Tests if objects are considered equal.
constexpr t_type clip(const t_type &value, const t_type &lower_bound, const t_type &upper_bound)
Clips the value given so that that the returned value falls between upper and lower bound.
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...