diff --git a/common/geometry/shape_arc.cpp b/common/geometry/shape_arc.cpp index 17ab18422c..d71b4e9f98 100644 --- a/common/geometry/shape_arc.cpp +++ b/common/geometry/shape_arc.cpp @@ -220,7 +220,7 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy ) const } else { - n = GetArcToSegmentCount( r, From_User_Unit( MILLIMETRES, aAccuracy ), m_centralAngle ); + n = GetArcToSegmentCount( r, aAccuracy, m_centralAngle ); } for( int i = 0; i <= n ; i++ ) diff --git a/common/geometry/shape_collisions.cpp b/common/geometry/shape_collisions.cpp index c614dc97db..90d63e866c 100644 --- a/common/geometry/shape_collisions.cpp +++ b/common/geometry/shape_collisions.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -300,6 +301,53 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_RECT& aB, int aCle return Collide( aA.Outline(), aB.Outline(), aClearance, aNeedMTV, aMTV ); } +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_RECT& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lc = aA.ConvertToPolyline(); + return Collide( lc, aB.Outline(), aClearance, aNeedMTV, aMTV ); +} + +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_CIRCLE& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lc = aA.ConvertToPolyline(); + bool rv = Collide( aB, lc, aClearance, aNeedMTV, aMTV ); + + if( rv && aNeedMTV ) + aMTV = -aMTV; + + return rv; +} + +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_LINE_CHAIN& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lc = aA.ConvertToPolyline(); + return Collide( lc, aB, aClearance, aNeedMTV, aMTV ); +} + +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SEGMENT& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lc = aA.ConvertToPolyline(); + return Collide( lc, aB, aClearance, aNeedMTV, aMTV ); +} + +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SIMPLE& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lc = aA.ConvertToPolyline(); + return Collide( lc, aB.Vertices(), aClearance, aNeedMTV, aMTV ); +} + +static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_ARC& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) +{ + const auto lcA = aA.ConvertToPolyline(); + const auto lcB = aB.ConvertToPolyline(); + return Collide( lcA, lcB, aClearance, aNeedMTV, aMTV ); +} template inline bool CollCase( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) @@ -343,6 +391,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed case SH_SIMPLE: return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_ARC: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); + default: break; } @@ -366,6 +417,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed case SH_SIMPLE: return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_ARC: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); + default: break; } @@ -389,6 +443,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed case SH_SIMPLE: return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_ARC: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); + default: break; } @@ -412,6 +469,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed case SH_SIMPLE: return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + case SH_ARC: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); + default: break; } @@ -435,6 +495,35 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed case SH_SIMPLE: return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_ARC: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); + + default: + break; + } + break; + + case SH_ARC: + switch( aB->Type() ) + { + case SH_RECT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_CIRCLE: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_LINE_CHAIN: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_SEGMENT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_SIMPLE: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_ARC: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + default: break; } @@ -453,17 +542,17 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed } -bool SHAPE::Collide( const SHAPE* aShape, int aClerance, VECTOR2I& aMTV ) const +bool SHAPE::Collide( const SHAPE* aShape, int aClearance, VECTOR2I& aMTV ) const { - return CollideShapes( this, aShape, aClerance, true, aMTV ); + return CollideShapes( this, aShape, aClearance, true, aMTV ); } -bool SHAPE::Collide( const SHAPE* aShape, int aClerance ) const +bool SHAPE::Collide( const SHAPE* aShape, int aClearance ) const { VECTOR2I dummy; - return CollideShapes( this, aShape, aClerance, false, dummy ); + return CollideShapes( this, aShape, aClearance, false, dummy ); } diff --git a/include/geometry/shape_arc.h b/include/geometry/shape_arc.h index 8cf3482438..3ecb0ef3fe 100644 --- a/include/geometry/shape_arc.h +++ b/include/geometry/shape_arc.h @@ -111,7 +111,18 @@ public: double aCenterAngle, double aRadius ); */ - const SHAPE_LINE_CHAIN ConvertToPolyline( double aAccuracy = 0.02f ) const; + + /** + * Constructs a SHAPE_LINE_CHAIN of segments from a given arc + * @param aAccuracy maximum divergence from true arc given in internal units + * ** Note that the default of 500.0 here is given using ARC_DEF_HIGH_ACCURACY + * for pcbnew units. This is to allow common geometry collision functions + * Other programs should call this using explicit accuracy values + * TODO: unify KiCad internal units + * + * @return a SHAPE_LINE_CHAIN + */ + const SHAPE_LINE_CHAIN ConvertToPolyline( double aAccuracy = 500.0 ) const; private: