const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance, int aWalkaroundThickness ) { int d = aSeg.GetWidth() / 2 + aClearance + aWalkaroundThickness / 2 + HULL_MARGIN; int x = (int)( 2.0 / ( 1.0 + M_SQRT2 ) * d ); const VECTOR2I a = aSeg.GetSeg().A; const VECTOR2I b = aSeg.GetSeg().B; VECTOR2I dir = b - a; VECTOR2I p0 = dir.Perpendicular().Resize( d ); VECTOR2I ds = dir.Perpendicular().Resize( x / 2 ); VECTOR2I pd = dir.Resize( x / 2 ); VECTOR2I dp = dir.Resize( d ); SHAPE_LINE_CHAIN s; s.SetClosed( true ); s.Append( b + p0 + pd ); s.Append( b + dp + ds ); s.Append( b + dp - ds ); s.Append( b - p0 + pd ); s.Append( a - p0 - pd ); s.Append( a - dp - ds ); s.Append( a - dp + ds ); s.Append( a + p0 - pd ); // make sure the hull outline is always clockwise if( s.CSegment( 0 ).Side( a ) < 0 ) return s.Reverse(); else return s; }
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { if( aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ) ) return true; return false; }
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg ) { SHAPE_RECT r; VECTOR2I delta( aSeg.GetWidth() / 2, aSeg.GetWidth() / 2 ); VECTOR2I p0( aSeg.GetSeg().A - delta ); VECTOR2I p1( aSeg.GetSeg().B + delta ); return SHAPE_RECT( std::min( p0.x, p1.x ), std::min( p0.y, p1.y ), std::abs( p1.x - p0.x ), std::abs( p1.y - p0.y ) ); }
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SEGMENT& aSeg, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { bool col = aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2); if( col && aNeedMTV ) { aMTV = -pushoutForce( aA, aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2); } return col; }
static inline bool Collide( const SHAPE_SEGMENT& aA, const SHAPE_SEGMENT& aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { return aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ); }