36#include <math/vector2d.h>
38typedef std::optional<VECTOR2I> OPT_VECTOR2I;
43 using ecoord = VECTOR2I::extended_type;
44 friend inline std::ostream& operator<<( std::ostream& aStream,
const SEG& aSeg );
62 SEG(
int aX1,
int aY1,
int aX2,
int aY2 ) :
99 m_index( aSeg.m_index )
103 SEG& operator=(
const SEG& aSeg )
107 m_index = aSeg.m_index;
112 bool operator==(
const SEG& aSeg )
const
114 return (A == aSeg.A && B == aSeg.B) ;
117 bool operator!=(
const SEG& aSeg )
const
119 return (A != aSeg.A || B != aSeg.B);
122 static SEG::ecoord Square(
int a )
124 return ecoord( a ) * a;
144 const ecoord det = ( B - A ).Cross( aP - A );
146 return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
198 OPT_VECTOR2I
Intersect(
const SEG& aSeg,
bool aIgnoreEndpoints =
false,
199 bool aLines =
false )
const;
201 bool Intersects(
const SEG& aSeg )
const;
230 bool Collide(
const SEG& aSeg,
int aClearance,
int* aActual =
nullptr )
const;
232 ecoord SquaredDistance(
const SEG& aSeg )
const;
242 ecoord SquaredDistance(
const VECTOR2I& aP )
const
244 return (
NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
255 void CanonicalCoefs( ecoord& qA, ecoord& qB, ecoord& qC )
const
257 qA = ecoord{ A.y } - B.y;
258 qB = ecoord{ B.x } - A.x;
259 qC = -qA * A.x - qB * A.y;
271 CanonicalCoefs( qa, qb, qc );
273 ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
274 ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
276 return ( d1 <= 1 && d2 <= 1 );
279 bool ApproxCollinear(
const SEG& aSeg )
const
282 CanonicalCoefs( p, q, r );
284 ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
285 ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
287 return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
290 bool ApproxParallel(
const SEG& aSeg,
int aDistanceThreshold = 1 )
const
293 CanonicalCoefs( p, q, r );
295 ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
296 ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
298 return std::abs( dist1 - dist2 ) <= aDistanceThreshold;
301 bool ApproxPerpendicular(
const SEG& aSeg )
const
305 return aSeg.ApproxParallel( perp );
308 bool Overlaps(
const SEG& aSeg )
const
310 if( aSeg.A == aSeg.B )
312 if( A == aSeg.A || B == aSeg.A )
315 return Contains( aSeg.A );
321 if( Contains( aSeg.A ) || Contains( aSeg.B ) )
324 if( aSeg.Contains( A ) || aSeg.Contains( B ) )
331 bool Contains(
const SEG& aSeg )
const
333 if( aSeg.A == aSeg.B )
334 return Contains( aSeg.A );
339 if( Contains( aSeg.A ) && Contains( aSeg.B ) )
352 return ( A - B ).EuclideanNorm();
355 ecoord SquaredLength()
const
357 return ( A - B ).SquaredEuclideanNorm();
360 ecoord TCoef(
const VECTOR2I& aP )
const;
373 bool Contains(
const VECTOR2I& aP )
const;
388 return A + ( B - A ) / 2;
394 bool intersects(
const SEG& aSeg,
bool aIgnoreEndpoints =
false,
bool aLines =
false,
402inline SEG::ecoord SEG::TCoef(
const VECTOR2I& aP )
const
405 return d.
Dot( aP - A);
408inline std::ostream& operator<<( std::ostream& aStream,
const SEG& aSeg )
410 aStream <<
"[ " << aSeg.A <<
" - " << aSeg.B <<
" ]";
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition seg.cpp:249
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
Definition seg.cpp:297
SEG(const VECTOR2I &aA, const VECTOR2I &aB, int aIndex)
Create a segment between (aA) and (aB), referenced to a multi-segment shape.
Definition seg.h:86
int Index() const
Return the index of this segment in its parent shape (applicable only to non-local segments).
Definition seg.h:368
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition seg.cpp:227
int Length() const
Return the length (this).
Definition seg.h:350
SEG(int aX1, int aY1, int aX2, int aY2)
Create a segment between (aX1, aY1) and (aX2, aY2).
Definition seg.h:62
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition seg.cpp:154
SEG()
Create an empty (0, 0) segment.
Definition seg.h:54
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
Definition seg.h:268
SEG ParallelSeg(const VECTOR2I &aP) const
Compute a segment parallel to this one, passing through point aP.
Definition seg.cpp:174
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition seg.h:209
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition seg.cpp:285
double AngleDegrees(const SEG &aOther) const
Determine the smallest angle between two segments (result in degrees)
Definition seg.cpp:61
SEG(const SEG &aSeg)
Copy constructor.
Definition seg.h:96
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition seg.cpp:268
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
Definition seg.cpp:165
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
Definition seg.h:142
SEG(const VECTOR2I &aA, const VECTOR2I &aB)
Create a segment between (aA) and (aB).
Definition seg.h:72
SEG Reversed() const
Returns the center point of the line.
Definition seg.h:380
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition vector2d.h:515