3#include "vipra/geometry/f3d.hpp"
5#include "vipra/macros/performance.hpp"
6#include "vipra/types/float.hpp"
8namespace VIPRA::Geometry {
9enum class Orientation { COLLINEAR, CLOCKWISE, COUNTERCLOCKWISE };
18 F3D_FUNC
auto length()
const noexcept -> VIPRA::f_pnt {
return start.distance_to(end); }
25 F3D_FUNC
auto direction() const noexcept -> VIPRA::
f3d {
return (end - start).
unit(); }
36 Line line,
VIPRA::f3d point)
noexcept -> Orientation
38 VIPRA::f_pnt val = (line.end.y - line.start.y) * (point.x - line.end.x) -
39 (line.end.x - line.start.x) * (point.y - line.end.y);
41 if ( val > 0 )
return Orientation::CLOCKWISE;
42 if ( val < 0 )
return Orientation::COUNTERCLOCKWISE;
43 return Orientation::COLLINEAR;
56 const VIPRA::f_pnt lineLength = start.distance_to(end);
58 if ( lineLength == 0.0 )
return start;
60 const VIPRA::f_pnt t =
61 std::max(
static_cast<VIPRA::f_pnt
>(0.0),
62 std::min(
static_cast<VIPRA::f_pnt
>(1.0),
63 (point - start).dot(end - start) / (lineLength * lineLength)));
64 return start + (end - start) * t;
76 return point.x <= std::max(start.x, end.x) && point.y <= std::max(start.y, end.y) &&
77 point.x >= std::min(start.x, end.x) && point.y >= std::min(start.y, end.y);
87 [[nodiscard]] VIPRA_INLINE
constexpr auto does_intersect(Line other)
const noexcept
104 const VIPRA::f_pnt a1 = end.y - start.y;
105 const VIPRA::f_pnt b1 = start.x - end.x;
106 const VIPRA::f_pnt c1 = a1 * start.x + b1 * start.y;
108 const VIPRA::f_pnt a2 = other.end.y - other.start.y;
109 const VIPRA::f_pnt b2 = other.start.x - other.end.x;
110 const VIPRA::f_pnt c2 = a2 * other.start.x + b2 * other.start.y;
112 const VIPRA::f_pnt determinant = a1 * b2 - a2 * b1;
114 if ( determinant == 0 )
return VIPRA::f3d{0, 0, 0};
116 const VIPRA::f_pnt x = (b2 * c1 - b1 * c2) / determinant;
117 const VIPRA::f_pnt y = (a1 * c2 - a2 * c1) / determinant;
131 Line line2)
noexcept ->
bool
138 if ( ori1 != ori2 && ori3 != ori4 )
return true;
140 if ( ori1 == Orientation::COLLINEAR && line1.is_point_on(line2.start) )
return true;
141 if ( ori2 == Orientation::COLLINEAR && line1.is_point_on(line2.end) )
return true;
142 if ( ori3 == Orientation::COLLINEAR && line2.is_point_on(line1.start) )
return true;
143 if ( ori4 == Orientation::COLLINEAR && line2.is_point_on(line1.end) )
return true;
148 constexpr Line() =
default;
149 constexpr ~Line() =
default;
150 constexpr Line(
const Line&) =
default;
152 constexpr auto operator=(
const Line&) ->
Line& =
default;
153 constexpr auto operator=(
Line&&) ->
Line& =
default;
static VIPRA_INLINE constexpr auto orientation_to(Line line, VIPRA::f3d point) noexcept -> Orientation
Calculates the orientation of a point relative to a line.
Definition line.hpp:35
VIPRA_INLINE constexpr auto closest_point(VIPRA::f3d point) const noexcept -> VIPRA::f3d
Calculates the closest point on the line to another point.
Definition line.hpp:52
VIPRA_INLINE constexpr auto is_point_on(VIPRA::f3d point) const -> bool
Checks if a point is on the line.
Definition line.hpp:74
constexpr auto intersection_point(Line other) const noexcept -> VIPRA::f3d
Calculates the intersection point of two lines.
Definition line.hpp:100
VIPRA_INLINE constexpr auto does_intersect(Line other) const noexcept -> bool
Checks if the line intersects another.
Definition line.hpp:87
static constexpr auto do_intersect(Line line1, Line line2) noexcept -> bool
Checks if two lines intersect.
Definition line.hpp:130
F3D_FUNC auto direction() const noexcept -> VIPRA::f3d
Returns unit vector in direction of line from start.
Definition line.hpp:25
F3D_FUNC auto unit() const noexcept -> f3d
Returns the unit vector in the direction of the f3d.
Definition f3d.hpp:227