MeshLib C++ Docs
Loading...
Searching...
No Matches
MRLineSegm.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMeshFwd.h"
4#include "MRVector2.h"
5
6namespace MR
7{
10
11
13template <typename V>
15{
16 using T = typename V::ValueType;
17 V a, b;
18
19 [[nodiscard]] constexpr LineSegm() noexcept = default;
20 [[nodiscard]] constexpr LineSegm( const V & a, const V & b ) noexcept : a( a ), b( b ) { }
21 template <typename U>
22 [[nodiscard]] constexpr explicit LineSegm( const LineSegm<U> & p ) noexcept : a( p.a ), b( p.b ) { }
24 [[nodiscard]] V dir() const { return b - a; }
26 [[nodiscard]] T lengthSq() const { return dir().lengthSq(); }
28 [[nodiscard]] T length() const { return dir().length(); }
30 [[nodiscard]] V operator()( T param ) const { return ( 1 - param ) * a + param * b; }
31};
32
33template <typename V>
34[[nodiscard]] inline bool operator == ( const LineSegm<V> & a, const LineSegm<V> & b )
35{
36 return a.a == b.a && a.b == b.b;
37}
38
39template <typename V>
40[[nodiscard]] V closestPointOnLineSegm( const V& pt, const LineSegm<V> & l )
41{
42 auto ab = l.b - l.a;
43 auto dt = dot( pt - l.a, ab );
44 auto abLengthSq = ab.lengthSq();
45 if ( dt <= 0 )
46 return l.a;
47 if ( dt >= abLengthSq )
48 return l.b;
49 auto ratio = dt / abLengthSq;
50 return l.a * ( 1 - ratio ) + l.b * ratio;
51}
52
55template <typename V>
56[[nodiscard]] bool doSegmentsIntersect( const LineSegm<V> & x, const LineSegm<V> & y,
57 typename V::ValueType * xPos = nullptr, typename V::ValueType * yPos = nullptr )
58{
60 const auto xvec = x.b - x.a;
61 const auto ya = cross( xvec, y.a - x.a );
62 const auto yb = cross( xvec, y.b - x.a );
63 if ( ya * yb > 0 )
64 return false;
65
67 const auto yvec = y.b - y.a;
68 const auto xa = cross( yvec, x.a - y.a );
69 const auto xb = cross( yvec, x.b - y.a );
70 if ( xa * xb > 0 )
71 return false;
72
74 if ( cross( xvec, yvec ) == 0 )
75 {
77 if ( xvec != V() )
78 {
79 if ( dot( xvec, y.a - x.a ) * dot( xvec, y.b - x.a ) > 0 &&
80 dot( -xvec, y.a - x.b ) * dot( -xvec, y.b - x.b ) > 0 )
81 return false;
82 }
83 else if ( yvec != V() )
84 {
85 if ( dot( yvec, x.a - y.a ) * dot( yvec, x.b - y.a ) > 0 &&
86 dot( -yvec, x.a - y.b ) * dot( -yvec, x.b - y.b ) > 0 )
87 return false;
88 }
89 else if ( x.a != y.a )
90 return false;
91 }
92
93 if ( xPos )
94 {
96 const auto denom = xa - xb;
97 *xPos = denom == 0 ? 0 : xa / denom;
98 }
99 if ( yPos )
100 {
102 const auto denom = ya - yb;
103 *yPos = denom == 0 ? 0 : ya / denom;
104 }
105 return true;
106}
107
110template <typename V>
111[[nodiscard]] bool doSegmentLineIntersect( const LineSegm<V> & x, const Line<V> & y,
112 typename V::ValueType * xPos = nullptr, typename V::ValueType * yPos = nullptr )
113{
115 const auto xa = cross( y.d, x.a - y.p );
116 const auto xb = cross( y.d, x.b - y.p );
117
120 if ( ( xa <= 0 ) == ( xb <= 0 ) )
121 return false;
122
123 if ( xPos )
124 {
126 const auto denom = xa - xb;
127 *xPos = denom == 0 ? 0 : xa / denom;
128 }
129 if ( yPos )
130 {
132 const auto xvec = x.b - x.a;
133 const auto ya = cross( xvec, y.p - x.a );
134 const auto yb = cross( xvec, y.p + y.d - x.a );
135
136 const auto denom = ya - yb;
137 *yPos = denom == 0 ? 0 : ya / denom;
138 }
139 return true;
140}
141
142MR_BIND_TEMPLATE( bool doSegmentsIntersect( const LineSegm<Vector2<float>>& x, const LineSegm<Vector2<float>>& y, float* xPos, float* yPos ) )
143MR_BIND_TEMPLATE( bool doSegmentsIntersect( const LineSegm<Vector2<double>>& x, const LineSegm<Vector2<double>>& y, double* xPos, double* yPos ) )
144
145MR_BIND_TEMPLATE( bool doSegmentLineIntersect( const LineSegm<Vector2<float>>& x, const Line<Vector2<float>>& y, float* xPos, float* yPos ) )
146MR_BIND_TEMPLATE( bool doSegmentLineIntersect( const LineSegm<Vector2<double>>& x, const Line<Vector2<double>>& y, double* xPos, double* yPos ) )
147
148}
MRMESH_API bool operator==(const BitSet &a, const BitSet &b)
compare that two bit sets have the same set bits (they can be equal even if sizes are distinct but la...
constexpr LineSegm() noexcept=default
T length() const
returns the length of this line segment
Definition MRLineSegm.h:28
typename V::ValueType T
Definition MRLineSegm.h:16
V closestPointOnLineSegm(const V &pt, const LineSegm< V > &l)
Definition MRLineSegm.h:40
V a
Definition MRLineSegm.h:17
constexpr LineSegm(const LineSegm< U > &p) noexcept
Definition MRLineSegm.h:22
V d
Definition MRLine.h:19
T lengthSq() const
returns squared length of this line segment
Definition MRLineSegm.h:26
V operator()(T param) const
returns point on the line, where param=0 returns a and param=1 returns b
Definition MRLineSegm.h:30
bool doSegmentLineIntersect(const LineSegm< V > &x, const Line< V > &y, typename V::ValueType *xPos=nullptr, typename V::ValueType *yPos=nullptr)
Definition MRLineSegm.h:111
bool doSegmentsIntersect(const LineSegm< V > &x, const LineSegm< V > &y, typename V::ValueType *xPos=nullptr, typename V::ValueType *yPos=nullptr)
Definition MRLineSegm.h:56
V dir() const
returns directional vector of the line
Definition MRLineSegm.h:24
V p
Definition MRLine.h:19
V b
Definition MRLineSegm.h:17
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
a segment of straight dimensional line
Definition MRLineSegm.h:15
Definition MRLine.h:16