Manual cherry-pick of 6ed3618ce5
.
This commit is contained in:
parent
914e396e2e
commit
56f58cf53f
|
@ -276,34 +276,9 @@ 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, int aDistanceThreshold = 1 ) 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 ) <= aDistanceThreshold;
|
||||
}
|
||||
|
||||
bool ApproxPerpendicular( const SEG& aSeg ) const
|
||||
{
|
||||
SEG perp = PerpendicularSeg( A );
|
||||
|
||||
return aSeg.ApproxParallel( perp );
|
||||
}
|
||||
bool ApproxCollinear( const SEG& aSeg, int aDistanceThreshold = 1 ) const;
|
||||
bool ApproxParallel( const SEG& aSeg, int aDistanceThreshold = 1 ) const;
|
||||
bool ApproxPerpendicular( const SEG& aSeg ) const;
|
||||
|
||||
bool Overlaps( const SEG& aSeg ) const
|
||||
{
|
||||
|
@ -394,6 +369,8 @@ private:
|
|||
bool intersects( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false,
|
||||
VECTOR2I* aPt = nullptr ) const;
|
||||
|
||||
bool mutualDistance( const SEG& aSeg, ecoord& aD1, ecoord& aD2 ) const;
|
||||
|
||||
private:
|
||||
///< index within the parent shape (used when m_is_local == false)
|
||||
int m_index;
|
||||
|
|
|
@ -349,3 +349,63 @@ int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
|||
return aDetermineSide ? dist : std::abs( dist );
|
||||
}
|
||||
|
||||
|
||||
bool SEG::mutualDistance( const SEG& aSeg, ecoord& aD1, ecoord& aD2 ) const
|
||||
{
|
||||
SEG a( *this );
|
||||
SEG b( aSeg );
|
||||
|
||||
if( a.SquaredLength() < b.SquaredLength() )
|
||||
{
|
||||
std::swap(a, b);
|
||||
}
|
||||
|
||||
ecoord p = ecoord{ a.A.y } - a.B.y;
|
||||
ecoord q = ecoord{ a.B.x } - a.A.x;
|
||||
ecoord r = -p * a.A.x - q * a.A.y;
|
||||
|
||||
ecoord l = p * p + q * q;
|
||||
|
||||
if( l == 0 )
|
||||
return false;
|
||||
|
||||
ecoord det1 = p * b.A.x + q * b.A.y + r;
|
||||
ecoord det2 = p * b.B.x + q * b.B.y + r;
|
||||
|
||||
ecoord dsq1 = rescale( det1, det1, l );
|
||||
ecoord dsq2 = rescale( det2, det2, l );
|
||||
|
||||
aD1 = sgn( det1 ) * isqrt( dsq1 );
|
||||
aD2 = sgn( det2 ) * isqrt( dsq2 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SEG::ApproxCollinear( const SEG& aSeg, int aDistanceThreshold ) const
|
||||
{
|
||||
ecoord d1, d2;
|
||||
|
||||
if( ! mutualDistance( aSeg, d1, d2 ) )
|
||||
return false;
|
||||
|
||||
return std::abs( d1 ) <= aDistanceThreshold && std::abs( d2 ) <= aDistanceThreshold;
|
||||
}
|
||||
|
||||
|
||||
bool SEG::ApproxParallel( const SEG& aSeg, int aDistanceThreshold ) const
|
||||
{
|
||||
ecoord d1, d2;
|
||||
|
||||
if( ! mutualDistance( aSeg, d1, d2 ) )
|
||||
return false;
|
||||
|
||||
return std::abs( d1 - d2 ) <= (ecoord) aDistanceThreshold;
|
||||
}
|
||||
|
||||
|
||||
bool SEG::ApproxPerpendicular( const SEG& aSeg ) const
|
||||
{
|
||||
SEG perp = PerpendicularSeg( A );
|
||||
|
||||
return aSeg.ApproxParallel( perp );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue