Loading common/geometry/seg.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const { VECTOR2I d = B - A; ecoord dist_sq = (ecoord) aDist * aDist; ecoord dist_sq_thr = (ecoord) (aDist + 1) * (aDist + 1); SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - A ); Loading @@ -60,6 +61,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const if( num > ( dist_sq + 100 ) ) return false; else if( num < ( dist_sq - 100 ) ) return true; } Loading include/geometry/seg.h +57 −8 Original line number Diff line number Diff line Loading @@ -206,6 +206,13 @@ public: return sqrt( SquaredDistance( aP ) ); } void CanonicalCoefs ( ecoord& qA, ecoord& qB, ecoord& qC) const { qA = A.y - B.y; qB = B.x - A.x; qC = -qA * A.x - qB * A.y; } /** * Function Collinear() * Loading @@ -215,9 +222,8 @@ public: */ bool Collinear( const SEG& aSeg ) const { ecoord qa = A.y - B.y; ecoord qb = B.x - A.x; ecoord qc = -qa * A.x - qb * A.y; ecoord qa, qb, qc; CanonicalCoefs ( qa, qb, qc ); ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc ); ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc ); Loading @@ -225,6 +231,29 @@ public: return ( d1 <= 1 && d2 <= 1 ); } bool ApproxCollinear( const SEG& aSeg ) const { ecoord p, q, r; CanonicalCoefs ( p, q, r ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); return std::abs(dist1) <= 1 && std::abs(dist2) <= 1; } bool ApproxParallel ( const SEG& aSeg ) const { ecoord p, q, r; CanonicalCoefs ( p, q, r ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); return std::abs(dist1 - dist2) <= 1; } bool Overlaps( const SEG& aSeg ) const { if( aSeg.A == aSeg.B ) // single point corner case Loading Loading @@ -262,6 +291,8 @@ public: return ( A - B ).SquaredEuclideanNorm(); } ecoord TCoef ( const VECTOR2I& aP ) const; /** * Function Index() * Loading @@ -277,7 +308,11 @@ public: bool PointCloserThan( const VECTOR2I& aP, int aDist ) const; // friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg ); void Reverse() { std::swap ( A, B ); } private: bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const; Loading @@ -288,9 +323,18 @@ private: inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const { // fixme: numerical errors for large integers assert( false ); return VECTOR2I( 0, 0 ); VECTOR2I d = B - A; ecoord l_squared = d.Dot( d ); if( l_squared == 0 ) return A; ecoord t = d.Dot( aP - A ); int xp = rescale( t, (ecoord)d.x, l_squared ); int yp = rescale( t, (ecoord)d.y, l_squared ); return A + VECTOR2I( xp, yp ); } Loading @@ -305,6 +349,11 @@ inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const return aDetermineSide ? dist : abs( dist ); } inline SEG::ecoord SEG::TCoef ( const VECTOR2I& aP ) const { VECTOR2I d = B - A; return d.Dot ( aP - A); } inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const { Loading Loading
common/geometry/seg.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const { VECTOR2I d = B - A; ecoord dist_sq = (ecoord) aDist * aDist; ecoord dist_sq_thr = (ecoord) (aDist + 1) * (aDist + 1); SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - A ); Loading @@ -60,6 +61,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const if( num > ( dist_sq + 100 ) ) return false; else if( num < ( dist_sq - 100 ) ) return true; } Loading
include/geometry/seg.h +57 −8 Original line number Diff line number Diff line Loading @@ -206,6 +206,13 @@ public: return sqrt( SquaredDistance( aP ) ); } void CanonicalCoefs ( ecoord& qA, ecoord& qB, ecoord& qC) const { qA = A.y - B.y; qB = B.x - A.x; qC = -qA * A.x - qB * A.y; } /** * Function Collinear() * Loading @@ -215,9 +222,8 @@ public: */ bool Collinear( const SEG& aSeg ) const { ecoord qa = A.y - B.y; ecoord qb = B.x - A.x; ecoord qc = -qa * A.x - qb * A.y; ecoord qa, qb, qc; CanonicalCoefs ( qa, qb, qc ); ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc ); ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc ); Loading @@ -225,6 +231,29 @@ public: return ( d1 <= 1 && d2 <= 1 ); } bool ApproxCollinear( const SEG& aSeg ) const { ecoord p, q, r; CanonicalCoefs ( p, q, r ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); return std::abs(dist1) <= 1 && std::abs(dist2) <= 1; } bool ApproxParallel ( const SEG& aSeg ) const { ecoord p, q, r; CanonicalCoefs ( p, q, r ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); return std::abs(dist1 - dist2) <= 1; } bool Overlaps( const SEG& aSeg ) const { if( aSeg.A == aSeg.B ) // single point corner case Loading Loading @@ -262,6 +291,8 @@ public: return ( A - B ).SquaredEuclideanNorm(); } ecoord TCoef ( const VECTOR2I& aP ) const; /** * Function Index() * Loading @@ -277,7 +308,11 @@ public: bool PointCloserThan( const VECTOR2I& aP, int aDist ) const; // friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg ); void Reverse() { std::swap ( A, B ); } private: bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const; Loading @@ -288,9 +323,18 @@ private: inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const { // fixme: numerical errors for large integers assert( false ); return VECTOR2I( 0, 0 ); VECTOR2I d = B - A; ecoord l_squared = d.Dot( d ); if( l_squared == 0 ) return A; ecoord t = d.Dot( aP - A ); int xp = rescale( t, (ecoord)d.x, l_squared ); int yp = rescale( t, (ecoord)d.y, l_squared ); return A + VECTOR2I( xp, yp ); } Loading @@ -305,6 +349,11 @@ inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const return aDetermineSide ? dist : abs( dist ); } inline SEG::ecoord SEG::TCoef ( const VECTOR2I& aP ) const { VECTOR2I d = B - A; return d.Dot ( aP - A); } inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const { Loading