Add SH_ARC collisions

This commit is contained in:
Seth Hillbrand 2018-05-16 13:06:44 -07:00
parent 65d72e1c11
commit 840ad7f680
3 changed files with 106 additions and 6 deletions

View File

@ -220,7 +220,7 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy ) const
} }
else else
{ {
n = GetArcToSegmentCount( r, From_User_Unit( MILLIMETRES, aAccuracy ), m_centralAngle ); n = GetArcToSegmentCount( r, aAccuracy, m_centralAngle );
} }
for( int i = 0; i <= n ; i++ ) for( int i = 0; i <= n ; i++ )

View File

@ -26,6 +26,7 @@
#include <math.h> #include <math.h>
#include <geometry/shape.h> #include <geometry/shape.h>
#include <geometry/shape_arc.h>
#include <geometry/shape_line_chain.h> #include <geometry/shape_line_chain.h>
#include <geometry/shape_circle.h> #include <geometry/shape_circle.h>
#include <geometry/shape_rect.h> #include <geometry/shape_rect.h>
@ -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 ); 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<class ShapeAType, class ShapeBType> template<class ShapeAType, class ShapeBType>
inline bool CollCase( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) 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: case SH_SIMPLE:
return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV ); return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCaseReversed<SHAPE_RECT, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default: default:
break; break;
} }
@ -366,6 +417,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SIMPLE: case SH_SIMPLE:
return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV ); return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCaseReversed<SHAPE_CIRCLE, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default: default:
break; break;
} }
@ -389,6 +443,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SIMPLE: case SH_SIMPLE:
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV ); return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCaseReversed<SHAPE_LINE_CHAIN, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default: default:
break; break;
} }
@ -412,6 +469,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SIMPLE: case SH_SIMPLE:
return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aB, aA, aClearance, aNeedMTV, aMTV ); return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aB, aA, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCaseReversed<SHAPE_SEGMENT, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default: default:
break; break;
} }
@ -435,6 +495,35 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SIMPLE: case SH_SIMPLE:
return CollCase<SHAPE_SIMPLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV ); return CollCase<SHAPE_SIMPLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCaseReversed<SHAPE_SIMPLE, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default:
break;
}
break;
case SH_ARC:
switch( aB->Type() )
{
case SH_RECT:
return CollCase<SHAPE_ARC, SHAPE_RECT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CIRCLE:
return CollCase<SHAPE_ARC, SHAPE_CIRCLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
return CollCase<SHAPE_ARC, SHAPE_LINE_CHAIN>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SEGMENT:
return CollCase<SHAPE_ARC, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_ARC, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_ARC:
return CollCase<SHAPE_ARC, SHAPE_ARC>( aA, aB, aClearance, aNeedMTV, aMTV );
default: default:
break; 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; VECTOR2I dummy;
return CollideShapes( this, aShape, aClerance, false, dummy ); return CollideShapes( this, aShape, aClearance, false, dummy );
} }

View File

@ -111,7 +111,18 @@ public:
double aCenterAngle, double aCenterAngle,
double aRadius ); 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: private: