31 #include <math/vector2d.h>
32 #include <core/optional.h>
34 typedef OPT<VECTOR2I> OPT_VECTOR2I;
39 typedef VECTOR2I::extended_type ecoord;
42 friend inline std::ostream& operator<<( std::ostream& aStream,
const SEG& aSeg );
61 SEG(
int aX1,
int aY1,
int aX2,
int aY2 ) :
92 SEG(
const SEG& aSeg ) : A( aSeg.A ), B( aSeg.B ), m_index( aSeg.m_index )
96 SEG& operator=(
const SEG& aSeg )
100 m_index = aSeg.m_index;
105 bool operator==(
const SEG& aSeg )
const
107 return (A == aSeg.A && B == aSeg.B) ;
110 bool operator!=(
const SEG& aSeg )
const
112 return (A != aSeg.A || B != aSeg.B);
134 const ecoord det = ( B - A ).Cross( aP - A );
136 return det < 0 ? -1 : ( det > 0 ? 1 : 0 );
169 OPT_VECTOR2I
Intersect(
const SEG& aSeg,
bool aIgnoreEndpoints =
false,
170 bool aLines =
false )
const;
184 bool Collide(
const SEG& aSeg,
int aClearance )
const;
186 ecoord SquaredDistance(
const SEG& aSeg )
const;
197 return sqrt( SquaredDistance( aSeg ) );
200 ecoord SquaredDistance(
const VECTOR2I& aP )
const
202 return (
NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
214 return sqrt( SquaredDistance( aP ) );
217 void CanonicalCoefs( ecoord& qA, ecoord& qB, ecoord& qC )
const
221 qC = -qA * A.x - qB * A.y;
234 CanonicalCoefs( qa, qb, qc );
236 ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
237 ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
239 return ( d1 <= 1 && d2 <= 1 );
242 bool ApproxCollinear(
const SEG& aSeg )
const
245 CanonicalCoefs( p, q, r );
247 ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
248 ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
250 return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
253 bool ApproxParallel (
const SEG& aSeg )
const
256 CanonicalCoefs( p, q, r );
258 ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
259 ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
261 return std::abs( dist1 - dist2 ) <= 1;
265 bool Overlaps(
const SEG& aSeg )
const
267 if( aSeg.A == aSeg.B )
269 if( A == aSeg.A || B == aSeg.A )
272 return Contains( aSeg.A );
278 if( Contains( aSeg.A ) || Contains( aSeg.B ) )
280 if( aSeg.Contains( A ) || aSeg.Contains( B ) )
294 return ( A - B ).EuclideanNorm();
297 ecoord SquaredLength()
const
299 return ( A - B ).SquaredEuclideanNorm();
302 ecoord TCoef(
const VECTOR2I& aP )
const;
315 bool Contains(
const VECTOR2I& aP )
const;
317 bool PointCloserThan(
const VECTOR2I& aP,
int aDist )
const;
327 return A + ( B - A ) / 2;
340 ecoord l_squared = d.
Dot( d );
345 ecoord t = d.
Dot( aP - A );
347 int xp = rescale( t, (ecoord)d.x, l_squared );
348 int yp = rescale( t, (ecoord)d.y, l_squared );
355 ecoord p = A.y - B.y;
356 ecoord q = B.x - A.x;
357 ecoord r = -p * A.x - q * A.y;
359 ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q );
361 return aDetermineSide ? dist : std::abs( dist );
364 inline SEG::ecoord SEG::TCoef(
const VECTOR2I& aP )
const
367 return d.
Dot( aP - A);
373 ecoord l_squared = d.
Dot( d );
378 ecoord t = d.
Dot( aP - A );
382 else if( t > l_squared )
385 int xp = rescale( t, (ecoord)d.x, l_squared );
386 int yp = rescale( t, (ecoord)d.y, l_squared );
391 inline std::ostream& operator<<( std::ostream& aStream,
const SEG& aSeg )
393 aStream <<
"[ " << aSeg.A <<
" - " << aSeg.B <<
" ]";