geometry: derive SHAPE_LINE_CHAIN, SHAPE_SIMPLE and SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI from a common base class allowing to simplify collision detection
This commit is contained in:
parent
eb6e1c4f90
commit
74623b8c98
|
@ -30,6 +30,7 @@
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <math/box2.h>
|
#include <math/box2.h>
|
||||||
|
|
||||||
|
class SHAPE_LINE_CHAIN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum SHAPE_TYPE
|
* Enum SHAPE_TYPE
|
||||||
|
@ -46,7 +47,8 @@ enum SHAPE_TYPE
|
||||||
SH_POLY_SET, ///> set of polygons (with holes, etc.)
|
SH_POLY_SET, ///> set of polygons (with holes, etc.)
|
||||||
SH_COMPOUND, ///> compound shape, consisting of multiple simple shapes
|
SH_COMPOUND, ///> compound shape, consisting of multiple simple shapes
|
||||||
SH_ARC, ///> circular arc
|
SH_ARC, ///> circular arc
|
||||||
SH_NULL ///> empty shape (no shape...)
|
SH_NULL, ///> empty shape (no shape...),
|
||||||
|
SH_POLY_SET_TRIANGLE ///> a single triangle belonging to a POLY_SET triangulation
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline wxString SHAPE_TYPE_asString( SHAPE_TYPE a )
|
static inline wxString SHAPE_TYPE_asString( SHAPE_TYPE a )
|
||||||
|
@ -62,22 +64,15 @@ static inline wxString SHAPE_TYPE_asString( SHAPE_TYPE a )
|
||||||
case SH_COMPOUND: return "SH_COMPOUND";
|
case SH_COMPOUND: return "SH_COMPOUND";
|
||||||
case SH_ARC: return "SH_ARC";
|
case SH_ARC: return "SH_ARC";
|
||||||
case SH_NULL: return "SH_NULL";
|
case SH_NULL: return "SH_NULL";
|
||||||
|
case SH_POLY_SET_TRIANGLE: return "SH_POLY_SET_TRIANGLE";
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxEmptyString; // Just to quiet GCC.
|
return wxEmptyString; // Just to quiet GCC.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
class SHAPE_BASE
|
||||||
* SHAPE
|
|
||||||
*
|
|
||||||
* Represents an abstract shape on 2D plane.
|
|
||||||
*/
|
|
||||||
class SHAPE
|
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
typedef VECTOR2I::extended_type ecoord;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -85,11 +80,11 @@ public:
|
||||||
* Creates an empty shape of type aType
|
* Creates an empty shape of type aType
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SHAPE( SHAPE_TYPE aType ) : m_type( aType )
|
SHAPE_BASE( SHAPE_TYPE aType ) : m_type( aType )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~SHAPE()
|
virtual ~SHAPE_BASE()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,6 +98,45 @@ public:
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool HasIndexableSubshapes() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t GetIndexableSubshapeCount() { return 0; }
|
||||||
|
|
||||||
|
virtual void GetIndexableSubshape( SHAPE_BASE& aSubshape ) const {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///> type of our shape
|
||||||
|
SHAPE_TYPE m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHAPE
|
||||||
|
*
|
||||||
|
* Represents an abstract shape on 2D plane.
|
||||||
|
*/
|
||||||
|
class SHAPE : public SHAPE_BASE
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef VECTOR2I::extended_type ecoord;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* Creates an empty shape of type aType
|
||||||
|
*/
|
||||||
|
|
||||||
|
SHAPE( SHAPE_TYPE aType ) : SHAPE_BASE( aType )
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~SHAPE()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Clone()
|
* Function Clone()
|
||||||
*
|
*
|
||||||
|
@ -202,11 +236,82 @@ public:
|
||||||
virtual bool Parse( std::stringstream& aStream );
|
virtual bool Parse( std::stringstream& aStream );
|
||||||
|
|
||||||
virtual const std::string Format( ) const;
|
virtual const std::string Format( ) const;
|
||||||
|
|
||||||
protected:
|
|
||||||
///> type of our shape
|
|
||||||
SHAPE_TYPE m_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SHAPE_LINE_CHAIN_BASE : public SHAPE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHAPE_LINE_CHAIN_BASE( SHAPE_TYPE aType ) : SHAPE( aType )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~SHAPE_LINE_CHAIN_BASE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Collide()
|
||||||
|
*
|
||||||
|
* Checks if point aP lies closer to us than aClearance.
|
||||||
|
* @param aP the point to check for collisions with
|
||||||
|
* @param aClearance minimum distance that does not qualify as a collision.
|
||||||
|
* @param aActual an optional pointer to an int to store the actual distance in the event
|
||||||
|
* of a collision.
|
||||||
|
* @return true, when a collision has been found
|
||||||
|
*/
|
||||||
|
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr ) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Collide()
|
||||||
|
*
|
||||||
|
* Checks if segment aSeg lies closer to us than aClearance.
|
||||||
|
* @param aSeg the segment to check for collisions with
|
||||||
|
* @param aClearance minimum distance that does not qualify as a collision.
|
||||||
|
* @param aActual an optional pointer to an int to store the actual distance in the event
|
||||||
|
* of a collision.
|
||||||
|
* @return true, when a collision has been found
|
||||||
|
*/
|
||||||
|
|
||||||
|
virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr ) const override;
|
||||||
|
SEG::ecoord SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PointInside()
|
||||||
|
*
|
||||||
|
* Checks if point aP lies inside a polygon (any type) defined by the line chain.
|
||||||
|
* For closed shapes only.
|
||||||
|
* @param aPt point to check
|
||||||
|
* @param aUseBBoxCache gives better peformance if the bounding box caches have been
|
||||||
|
* generated.
|
||||||
|
* @return true if the point is inside the shape (edge is not treated as being inside).
|
||||||
|
*/
|
||||||
|
bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0, bool aUseBBoxCache = false ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PointOnEdge()
|
||||||
|
*
|
||||||
|
* Checks if point aP lies on an edge or vertex of the line chain.
|
||||||
|
* @param aP point to check
|
||||||
|
* @return true if the point lies on the edge.
|
||||||
|
*/
|
||||||
|
bool PointOnEdge( const VECTOR2I& aP, int aAccuracy = 0 ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function EdgeContainingPoint()
|
||||||
|
*
|
||||||
|
* Checks if point aP lies on an edge or vertex of the line chain.
|
||||||
|
* @param aP point to check
|
||||||
|
* @return index of the first edge containing the point, otherwise negative
|
||||||
|
*/
|
||||||
|
int EdgeContainingPoint( const VECTOR2I& aP, int aAccuracy = 0 ) const;
|
||||||
|
|
||||||
|
virtual const VECTOR2I GetPoint( int aIndex ) const = 0;
|
||||||
|
virtual const SEG GetSegment( int aIndex ) const = 0;
|
||||||
|
virtual size_t GetPointCount() const = 0;
|
||||||
|
virtual size_t GetSegmentCount() const = 0;
|
||||||
|
virtual bool IsClosed() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __SHAPE_H
|
#endif // __SHAPE_H
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
*
|
*
|
||||||
* SHAPE_LINE_CHAIN class shall not be used for polygons!
|
* SHAPE_LINE_CHAIN class shall not be used for polygons!
|
||||||
*/
|
*/
|
||||||
class SHAPE_LINE_CHAIN : public SHAPE
|
class SHAPE_LINE_CHAIN : public SHAPE_LINE_CHAIN_BASE
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::vector<VECTOR2I>::iterator point_iter;
|
typedef std::vector<VECTOR2I>::iterator point_iter;
|
||||||
|
@ -99,7 +99,7 @@ public:
|
||||||
* Constructor
|
* Constructor
|
||||||
* Initializes an empty line chain.
|
* Initializes an empty line chain.
|
||||||
*/
|
*/
|
||||||
SHAPE_LINE_CHAIN() : SHAPE( SH_LINE_CHAIN ), m_closed( false ), m_width( 0 )
|
SHAPE_LINE_CHAIN() : SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( false ), m_width( 0 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN( const SHAPE_LINE_CHAIN& aShape )
|
SHAPE_LINE_CHAIN( const SHAPE_LINE_CHAIN& aShape )
|
||||||
: SHAPE( SH_LINE_CHAIN ),
|
: SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ),
|
||||||
m_points( aShape.m_points ),
|
m_points( aShape.m_points ),
|
||||||
m_shapes( aShape.m_shapes ),
|
m_shapes( aShape.m_shapes ),
|
||||||
m_arcs( aShape.m_arcs ),
|
m_arcs( aShape.m_arcs ),
|
||||||
|
@ -119,7 +119,7 @@ public:
|
||||||
SHAPE_LINE_CHAIN( const std::vector<int>& aV);
|
SHAPE_LINE_CHAIN( const std::vector<int>& aV);
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN( const std::vector<wxPoint>& aV, bool aClosed = false )
|
SHAPE_LINE_CHAIN( const std::vector<wxPoint>& aV, bool aClosed = false )
|
||||||
: SHAPE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
|
: SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
|
||||||
{
|
{
|
||||||
m_points.reserve( aV.size() );
|
m_points.reserve( aV.size() );
|
||||||
|
|
||||||
|
@ -130,14 +130,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN( const std::vector<VECTOR2I>& aV, bool aClosed = false )
|
SHAPE_LINE_CHAIN( const std::vector<VECTOR2I>& aV, bool aClosed = false )
|
||||||
: SHAPE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
|
: SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
|
||||||
{
|
{
|
||||||
m_points = aV;
|
m_points = aV;
|
||||||
m_shapes = std::vector<ssize_t>( aV.size(), ssize_t( SHAPE_IS_PT ) );
|
m_shapes = std::vector<ssize_t>( aV.size(), ssize_t( SHAPE_IS_PT ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false )
|
SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false )
|
||||||
: SHAPE( SH_LINE_CHAIN ),
|
: SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ),
|
||||||
m_closed( aClosed ),
|
m_closed( aClosed ),
|
||||||
m_width( 0 )
|
m_width( 0 )
|
||||||
{
|
{
|
||||||
|
@ -147,7 +147,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath ) :
|
SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath ) :
|
||||||
SHAPE( SH_LINE_CHAIN ),
|
SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ),
|
||||||
m_closed( true ),
|
m_closed( true ),
|
||||||
m_width( 0 )
|
m_width( 0 )
|
||||||
{
|
{
|
||||||
|
@ -194,7 +194,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return aClosed: true, when our line is closed.
|
* @return aClosed: true, when our line is closed.
|
||||||
*/
|
*/
|
||||||
bool IsClosed() const
|
bool IsClosed() const override
|
||||||
{
|
{
|
||||||
return m_closed;
|
return m_closed;
|
||||||
}
|
}
|
||||||
|
@ -372,30 +372,6 @@ public:
|
||||||
return m_bbox;
|
return m_bbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Collide()
|
|
||||||
*
|
|
||||||
* Checks if point aP lies closer to us than aClearance.
|
|
||||||
* @param aP the point to check for collisions with
|
|
||||||
* @param aClearance minimum distance that does not qualify as a collision.
|
|
||||||
* @param aActual an optional pointer to an int to store the actual distance in the event
|
|
||||||
* of a collision.
|
|
||||||
* @return true, when a collision has been found
|
|
||||||
*/
|
|
||||||
bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr ) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Collide()
|
|
||||||
*
|
|
||||||
* Checks if segment aSeg lies closer to us than aClearance.
|
|
||||||
* @param aSeg the segment to check for collisions with
|
|
||||||
* @param aClearance minimum distance that does not qualify as a collision.
|
|
||||||
* @param aActual an optional pointer to an int to store the actual distance in the event
|
|
||||||
* of a collision.
|
|
||||||
* @return true, when a collision has been found
|
|
||||||
*/
|
|
||||||
bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr ) const override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Distance()
|
* Function Distance()
|
||||||
*
|
*
|
||||||
|
@ -404,7 +380,6 @@ public:
|
||||||
* @return minimum distance.
|
* @return minimum distance.
|
||||||
*/
|
*/
|
||||||
int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||||
SEG::ecoord SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Reverse()
|
* Function Reverse()
|
||||||
|
@ -600,37 +575,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int PathLength( const VECTOR2I& aP ) const;
|
int PathLength( const VECTOR2I& aP ) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function PointInside()
|
|
||||||
*
|
|
||||||
* Checks if point aP lies inside a polygon (any type) defined by the line chain.
|
|
||||||
* For closed shapes only.
|
|
||||||
* @param aPt point to check
|
|
||||||
* @param aUseBBoxCache gives better peformance if the bounding box caches have been
|
|
||||||
* generated.
|
|
||||||
* @return true if the point is inside the shape (edge is not treated as being inside).
|
|
||||||
*/
|
|
||||||
bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0, bool aUseBBoxCache = false ) const;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function PointOnEdge()
|
|
||||||
*
|
|
||||||
* Checks if point aP lies on an edge or vertex of the line chain.
|
|
||||||
* @param aP point to check
|
|
||||||
* @return true if the point lies on the edge.
|
|
||||||
*/
|
|
||||||
bool PointOnEdge( const VECTOR2I& aP, int aAccuracy = 0 ) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function EdgeContainingPoint()
|
|
||||||
*
|
|
||||||
* Checks if point aP lies on an edge or vertex of the line chain.
|
|
||||||
* @param aP point to check
|
|
||||||
* @return index of the first edge containing the point, otherwise negative
|
|
||||||
*/
|
|
||||||
int EdgeContainingPoint( const VECTOR2I& aP, int aAccuracy = 0 ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CheckClearance()
|
* Function CheckClearance()
|
||||||
*
|
*
|
||||||
|
@ -775,6 +719,11 @@ public:
|
||||||
return aSegment < m_shapes.size() && m_shapes[aSegment] != SHAPE_IS_PT;
|
return aSegment < m_shapes.size() && m_shapes[aSegment] != SHAPE_IS_PT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
|
||||||
|
virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
|
||||||
|
virtual size_t GetPointCount() const override { return PointCount(); }
|
||||||
|
virtual size_t GetSegmentCount() const override { return SegmentCount(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
constexpr static ssize_t SHAPE_IS_PT = -1;
|
constexpr static ssize_t SHAPE_IS_PT = -1;
|
||||||
|
|
|
@ -71,13 +71,64 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
class TRIANGULATED_POLYGON
|
class TRIANGULATED_POLYGON
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TRI
|
struct TRI : public SHAPE_LINE_CHAIN_BASE
|
||||||
{
|
{
|
||||||
TRI( int _a = 0, int _b = 0, int _c = 0 ) : a( _a ), b( _b ), c( _c )
|
TRI( int _a = 0, int _b = 0, int _c = 0, TRIANGULATED_POLYGON* aParent = nullptr ) :
|
||||||
|
SHAPE_LINE_CHAIN_BASE( SH_POLY_SET_TRIANGLE ),
|
||||||
|
a( _a ), b( _b ), c( _c ), parent( aParent )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void Rotate( double aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override {};
|
||||||
|
|
||||||
|
virtual void Move( const VECTOR2I& aVector ) override {};
|
||||||
|
|
||||||
|
virtual bool IsSolid() const override { return true; }
|
||||||
|
|
||||||
|
virtual bool IsClosed() const override { return true; }
|
||||||
|
|
||||||
|
virtual const BOX2I BBox( int aClearance = 0 ) const override
|
||||||
|
{
|
||||||
|
BOX2I bbox( parent->m_vertices[a] );
|
||||||
|
bbox.Merge( parent->m_vertices[b] );
|
||||||
|
bbox.Merge( parent->m_vertices[c] );
|
||||||
|
|
||||||
|
if( aClearance != 0 )
|
||||||
|
bbox.Inflate( aClearance );
|
||||||
|
|
||||||
|
return bbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const VECTOR2I GetPoint( int aIndex ) const override
|
||||||
|
{
|
||||||
|
switch(aIndex)
|
||||||
|
{
|
||||||
|
case 0: return parent->m_vertices[a];
|
||||||
|
case 1: return parent->m_vertices[b];
|
||||||
|
case 2: return parent->m_vertices[c];
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
return VECTOR2I(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const SEG GetSegment( int aIndex ) const override
|
||||||
|
{
|
||||||
|
switch(aIndex)
|
||||||
|
{
|
||||||
|
case 0: return SEG( parent->m_vertices[a], parent->m_vertices[b] );
|
||||||
|
case 1: return SEG( parent->m_vertices[b], parent->m_vertices[c] );
|
||||||
|
case 2: return SEG( parent->m_vertices[c], parent->m_vertices[a] );
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
return SEG();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t GetPointCount() const override { return 3; }
|
||||||
|
virtual size_t GetSegmentCount() const override { return 3; }
|
||||||
|
|
||||||
|
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
TRIANGULATED_POLYGON* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
|
@ -101,7 +152,7 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
|
|
||||||
void AddTriangle( int a, int b, int c )
|
void AddTriangle( int a, int b, int c )
|
||||||
{
|
{
|
||||||
m_triangles.emplace_back( a, b, c );
|
m_triangles.emplace_back( a, b, c, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVertex( const VECTOR2I& aP )
|
void AddVertex( const VECTOR2I& aP )
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
* Internally the vertices are held in a SHAPE_LINE_CHAIN, please note that
|
* Internally the vertices are held in a SHAPE_LINE_CHAIN, please note that
|
||||||
* there is a "virtual" line segment between the last and first vertex.
|
* there is a "virtual" line segment between the last and first vertex.
|
||||||
*/
|
*/
|
||||||
class SHAPE_SIMPLE : public SHAPE
|
|
||||||
|
class SHAPE_SIMPLE : public SHAPE_LINE_CHAIN_BASE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -47,20 +48,20 @@ public:
|
||||||
* Creates an empty polygon
|
* Creates an empty polygon
|
||||||
*/
|
*/
|
||||||
SHAPE_SIMPLE() :
|
SHAPE_SIMPLE() :
|
||||||
SHAPE( SH_SIMPLE )
|
SHAPE_LINE_CHAIN_BASE( SH_SIMPLE )
|
||||||
{
|
{
|
||||||
m_points.SetClosed( true );
|
m_points.SetClosed( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_SIMPLE( const SHAPE_LINE_CHAIN& aPoly ) :
|
SHAPE_SIMPLE( const SHAPE_LINE_CHAIN& aPoly ) :
|
||||||
SHAPE( SH_SIMPLE ),
|
SHAPE_LINE_CHAIN_BASE( SH_SIMPLE ),
|
||||||
m_points( aPoly )
|
m_points( aPoly )
|
||||||
{
|
{
|
||||||
m_points.SetClosed( true );
|
m_points.SetClosed( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_SIMPLE( const SHAPE_SIMPLE& aOther ) :
|
SHAPE_SIMPLE( const SHAPE_SIMPLE& aOther ) :
|
||||||
SHAPE( SH_SIMPLE ), m_points( aOther.m_points )
|
SHAPE_LINE_CHAIN_BASE( SH_SIMPLE ), m_points( aOther.m_points )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHAPE* Clone() const override
|
SHAPE* Clone() const override
|
||||||
|
@ -179,6 +180,16 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const VECTOR2I GetPoint( int aIndex ) const override { return m_points.CPoint(aIndex); }
|
||||||
|
virtual const SEG GetSegment( int aIndex ) const override { return m_points.CSegment(aIndex); }
|
||||||
|
virtual size_t GetPointCount() const override { return m_points.PointCount(); }
|
||||||
|
virtual size_t GetSegmentCount() const override { return m_points.SegmentCount(); }
|
||||||
|
|
||||||
|
bool IsClosed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// vertices
|
// vertices
|
||||||
SHAPE_LINE_CHAIN m_points;
|
SHAPE_LINE_CHAIN m_points;
|
||||||
|
|
|
@ -162,15 +162,15 @@ static VECTOR2I pushoutForce( const SHAPE_CIRCLE& aA, const SEG& aB, int aCleara
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
bool collided = false;
|
bool collided = false;
|
||||||
|
|
||||||
for( int s = 0; s < aB.SegmentCount(); s++ )
|
for( int s = 0; s < aB.GetSegmentCount(); s++ )
|
||||||
{
|
{
|
||||||
if( aA.Collide( aB.CSegment( s ), aClearance, aActual ) )
|
if( aA.Collide( aB.GetSegment( s ), aClearance, aActual ) )
|
||||||
{
|
{
|
||||||
collided = true;
|
collided = true;
|
||||||
break;
|
break;
|
||||||
|
@ -185,9 +185,9 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB,
|
||||||
SHAPE_CIRCLE cmoved( aA );
|
SHAPE_CIRCLE cmoved( aA );
|
||||||
VECTOR2I f_total( 0, 0 );
|
VECTOR2I f_total( 0, 0 );
|
||||||
|
|
||||||
for( int s = 0; s < aB.SegmentCount(); s++ )
|
for( int s = 0; s < aB.GetSegmentCount(); s++ )
|
||||||
{
|
{
|
||||||
VECTOR2I f = pushoutForce( cmoved, aB.CSegment( s ), aClearance );
|
VECTOR2I f = pushoutForce( cmoved, aB.GetSegment( s ), aClearance );
|
||||||
cmoved.SetCenter( cmoved.GetCenter() + f );
|
cmoved.SetCenter( cmoved.GetCenter() + f );
|
||||||
f_total += f;
|
f_total += f;
|
||||||
}
|
}
|
||||||
|
@ -197,13 +197,13 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance,
|
||||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SIMPLE& aB, int aClearance,
|
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
int min_dist = aClearance + aA.GetRadius();
|
int min_dist = aClearance + aA.GetRadius();
|
||||||
ecoord dist_sq = aB.Vertices().SquaredDistance( aA.GetCenter() );
|
ecoord dist_sq = aB.SquaredDistance( aA.GetCenter() );
|
||||||
|
|
||||||
if( dist_sq > (ecoord) min_dist * min_dist )
|
if( dist_sq > (ecoord) min_dist * min_dist )
|
||||||
return false;
|
return false;
|
||||||
|
@ -216,9 +216,9 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SIMPLE& aB, int
|
||||||
SHAPE_CIRCLE cmoved( aA );
|
SHAPE_CIRCLE cmoved( aA );
|
||||||
VECTOR2I f_total( 0, 0 );
|
VECTOR2I f_total( 0, 0 );
|
||||||
|
|
||||||
for( int s = 0; s < aB.Vertices().SegmentCount(); s++ )
|
for( int s = 0; s < aB.GetSegmentCount(); s++ )
|
||||||
{
|
{
|
||||||
VECTOR2I f = pushoutForce( cmoved, aB.Vertices().CSegment( s ), aClearance );
|
VECTOR2I f = pushoutForce( cmoved, aB.GetSegment( s ), aClearance );
|
||||||
cmoved.SetCenter( cmoved.GetCenter() + f );
|
cmoved.SetCenter( cmoved.GetCenter() + f );
|
||||||
f_total += f;
|
f_total += f;
|
||||||
}
|
}
|
||||||
|
@ -242,14 +242,15 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SEGMENT& aSeg, i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
static inline bool Collide( const SHAPE_LINE_CHAIN_BASE& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
// TODO: why doesn't this handle MTV?
|
// TODO: why doesn't this handle MTV?
|
||||||
|
// TODO: worse, why this doesn't handle closed shapes?
|
||||||
|
|
||||||
for( int i = 0; i < aB.SegmentCount(); i++ )
|
for( int i = 0; i < aB.GetSegmentCount(); i++ )
|
||||||
{
|
{
|
||||||
if( aA.Collide( aB.CSegment( i ), aClearance, aActual ) )
|
if( aA.Collide( aB.GetSegment( i ), aClearance, aActual ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,29 +258,15 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SIMPLE& aB, int aClearance,
|
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
|
||||||
{
|
|
||||||
return Collide( aA, aB.Vertices(), aClearance, aActual, aMTV );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_SIMPLE& aA, const SHAPE_SIMPLE& aB, int aClearance,
|
|
||||||
int* aActual, VECTOR2I* aMTV )
|
|
||||||
{
|
|
||||||
return Collide( aA.Vertices(), aB.Vertices(), aClearance, aActual, aMTV );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
int minActual = INT_MAX;
|
int minActual = INT_MAX;
|
||||||
int actual;
|
int actual;
|
||||||
|
|
||||||
for( int s = 0; s < aB.SegmentCount(); s++ )
|
for( int s = 0; s < aB.GetSegmentCount(); s++ )
|
||||||
{
|
{
|
||||||
if( aA.Collide( aB.CSegment( s ), aClearance, &actual ) )
|
if( aA.Collide( aB.GetSegment( s ), aClearance, &actual ) )
|
||||||
{
|
{
|
||||||
minActual = std::min( minActual, actual );
|
minActual = std::min( minActual, actual );
|
||||||
|
|
||||||
|
@ -298,13 +285,6 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SIMPLE& aB, int aClearance,
|
|
||||||
int* aActual, VECTOR2I* aMTV )
|
|
||||||
{
|
|
||||||
return Collide( aA, aB.Vertices(), aClearance, aActual, aMTV );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SEGMENT& aSeg, int aClearance,
|
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
|
@ -343,7 +323,7 @@ static inline bool Collide( const SHAPE_SEGMENT& aA, const SHAPE_SEGMENT& aB, in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB, int aClearance,
|
static inline bool Collide( const SHAPE_LINE_CHAIN_BASE& aA, const SHAPE_SEGMENT& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
int actual;
|
int actual;
|
||||||
|
@ -362,12 +342,6 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_SIMPLE& aA, const SHAPE_SEGMENT& aB, int aClearance,
|
|
||||||
int* aActual, VECTOR2I* aMTV )
|
|
||||||
{
|
|
||||||
return Collide( aA.Vertices(), aB, aClearance, aActual, aMTV );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_RECT& aB, int aClearance,
|
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_RECT& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
|
@ -407,12 +381,12 @@ static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SEGMENT& aB, int aC
|
||||||
return Collide( lc, aB, aClearance, aActual, aMTV );
|
return Collide( lc, aB, aClearance, aActual, aMTV );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SIMPLE& aB, int aClearance,
|
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
const auto lc = aA.ConvertToPolyline();
|
const auto lc = aA.ConvertToPolyline();
|
||||||
|
|
||||||
return Collide( lc, aB.Vertices(), aClearance, aActual, aMTV );
|
return Collide( lc, aB, aClearance, aActual, aMTV );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_ARC& aB, int aClearance,
|
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_ARC& aB, int aClearance,
|
||||||
|
@ -454,6 +428,7 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
{
|
{
|
||||||
case SH_NULL:
|
case SH_NULL:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case SH_RECT:
|
case SH_RECT:
|
||||||
switch( aB->Type() )
|
switch( aB->Type() )
|
||||||
{
|
{
|
||||||
|
@ -470,7 +445,8 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
return CollCase<SHAPE_RECT, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_RECT, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aA, aB, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_RECT, SHAPE_LINE_CHAIN_BASE>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCaseReversed<SHAPE_RECT, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCaseReversed<SHAPE_RECT, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
@ -499,7 +475,8 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
return CollCase<SHAPE_CIRCLE, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_CIRCLE, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aA, aB, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_CIRCLE, SHAPE_LINE_CHAIN_BASE>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCaseReversed<SHAPE_CIRCLE, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCaseReversed<SHAPE_CIRCLE, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
@ -528,7 +505,8 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aA, aB, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_LINE_CHAIN, SHAPE_LINE_CHAIN_BASE>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCaseReversed<SHAPE_LINE_CHAIN, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCaseReversed<SHAPE_LINE_CHAIN, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
@ -557,7 +535,8 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
return CollCase<SHAPE_SEGMENT, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_SEGMENT, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aB, aA, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_LINE_CHAIN_BASE, SHAPE_SEGMENT>( aB, aA, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCaseReversed<SHAPE_SEGMENT, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCaseReversed<SHAPE_SEGMENT, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
@ -571,25 +550,27 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
|
case SH_POLY_SET_TRIANGLE:
|
||||||
switch( aB->Type() )
|
switch( aB->Type() )
|
||||||
{
|
{
|
||||||
case SH_RECT:
|
case SH_RECT:
|
||||||
return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aB, aA, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_RECT, SHAPE_LINE_CHAIN_BASE>( aB, aA, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_CIRCLE:
|
case SH_CIRCLE:
|
||||||
return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aB, aA, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_CIRCLE, SHAPE_LINE_CHAIN_BASE>( aB, aA, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_LINE_CHAIN:
|
case SH_LINE_CHAIN:
|
||||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aB, aA, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_LINE_CHAIN, SHAPE_LINE_CHAIN_BASE>( aB, aA, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SEGMENT:
|
case SH_SEGMENT:
|
||||||
return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_LINE_CHAIN_BASE, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_SIMPLE, SHAPE_SIMPLE>( aA, aB, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_LINE_CHAIN_BASE, SHAPE_LINE_CHAIN_BASE>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCaseReversed<SHAPE_SIMPLE, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCaseReversed<SHAPE_LINE_CHAIN_BASE, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_NULL:
|
case SH_NULL:
|
||||||
return false;
|
return false;
|
||||||
|
@ -615,7 +596,8 @@ static bool collideSingleShapes( const SHAPE* aA, const SHAPE* aB, int aClearanc
|
||||||
return CollCase<SHAPE_ARC, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_ARC, SHAPE_SEGMENT>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_SIMPLE:
|
case SH_SIMPLE:
|
||||||
return CollCase<SHAPE_ARC, SHAPE_SIMPLE>( aA, aB, aClearance, aActual, aMTV );
|
case SH_POLY_SET_TRIANGLE:
|
||||||
|
return CollCase<SHAPE_ARC, SHAPE_LINE_CHAIN_BASE>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
||||||
case SH_ARC:
|
case SH_ARC:
|
||||||
return CollCase<SHAPE_ARC, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
return CollCase<SHAPE_ARC, SHAPE_ARC>( aA, aB, aClearance, aActual, aMTV );
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
class SHAPE;
|
class SHAPE;
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const std::vector<int>& aV)
|
SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const std::vector<int>& aV)
|
||||||
: SHAPE( SH_LINE_CHAIN ), m_closed( false ), m_width( 0 )
|
: SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( false ), m_width( 0 )
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < aV.size(); i+= 2 )
|
for(size_t i = 0; i < aV.size(); i+= 2 )
|
||||||
{
|
{
|
||||||
|
@ -85,14 +85,16 @@ void SHAPE_LINE_CHAIN::convertArc( ssize_t aArcIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_LINE_CHAIN::Collide( const VECTOR2I& aP, int aClearance, int* aActual ) const
|
bool SHAPE_LINE_CHAIN_BASE::Collide( const VECTOR2I& aP, int aClearance, int* aActual ) const
|
||||||
{
|
{
|
||||||
SEG::ecoord dist_sq = VECTOR2I::ECOORD_MAX;
|
SEG::ecoord dist_sq = VECTOR2I::ECOORD_MAX;
|
||||||
SEG::ecoord clearance_sq = SEG::Square( aClearance );
|
SEG::ecoord clearance_sq = SEG::Square( aClearance );
|
||||||
|
|
||||||
for( int i = 0; i < SegmentCount(); i++ )
|
// fixme: why this only checks open curves?
|
||||||
|
|
||||||
|
for( int i = 0; i < GetSegmentCount(); i++ )
|
||||||
{
|
{
|
||||||
const SEG& s = CSegment( i );
|
const SEG& s = GetSegment( i );
|
||||||
dist_sq = std::min( dist_sq, s.SquaredDistance( aP ) );
|
dist_sq = std::min( dist_sq, s.SquaredDistance( aP ) );
|
||||||
|
|
||||||
if( ( dist_sq == 0 || dist_sq < clearance_sq ) && !aActual )
|
if( ( dist_sq == 0 || dist_sq < clearance_sq ) && !aActual )
|
||||||
|
@ -125,14 +127,14 @@ void SHAPE_LINE_CHAIN::Rotate( double aAngle, const VECTOR2I& aCenter )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance, int* aActual ) const
|
bool SHAPE_LINE_CHAIN_BASE::Collide( const SEG& aSeg, int aClearance, int* aActual ) const
|
||||||
{
|
{
|
||||||
SEG::ecoord dist_sq = VECTOR2I::ECOORD_MAX;
|
SEG::ecoord dist_sq = VECTOR2I::ECOORD_MAX;
|
||||||
SEG::ecoord clearance_sq = SEG::Square( aClearance );
|
SEG::ecoord clearance_sq = SEG::Square( aClearance );
|
||||||
|
|
||||||
for( int i = 0; i < SegmentCount(); i++ )
|
for( int i = 0; i < GetSegmentCount(); i++ )
|
||||||
{
|
{
|
||||||
const SEG& s = CSegment( i );
|
const SEG& s = GetSegment( i );
|
||||||
dist_sq = std::min( dist_sq, s.SquaredDistance( aSeg ) );
|
dist_sq = std::min( dist_sq, s.SquaredDistance( aSeg ) );
|
||||||
|
|
||||||
if( ( dist_sq == 0 || dist_sq < clearance_sq ) && !aActual )
|
if( ( dist_sq == 0 || dist_sq < clearance_sq ) && !aActual )
|
||||||
|
@ -292,15 +294,15 @@ int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SEG::ecoord SHAPE_LINE_CHAIN::SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
SEG::ecoord SHAPE_LINE_CHAIN_BASE::SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||||
{
|
{
|
||||||
ecoord d = VECTOR2I::ECOORD_MAX;
|
ecoord d = VECTOR2I::ECOORD_MAX;
|
||||||
|
|
||||||
if( IsClosed() && PointInside( aP ) && !aOutlineOnly )
|
if( IsClosed() && PointInside( aP ) && !aOutlineOnly )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for( int s = 0; s < SegmentCount(); s++ )
|
for( int s = 0; s < GetSegmentCount(); s++ )
|
||||||
d = std::min( d, CSegment( s ).SquaredDistance( aP ) );
|
d = std::min( d, GetSegment( s ).SquaredDistance( aP ) );
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -601,16 +603,18 @@ int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUseBBoxCache ) const
|
bool SHAPE_LINE_CHAIN_BASE::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUseBBoxCache ) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't check the bounding box unless it's cached. Building it is about the same speed as
|
* Don't check the bounding box unless it's cached. Building it is about the same speed as
|
||||||
* the rigorous test below and so just slows things down by doing potentially two tests.
|
* the rigorous test below and so just slows things down by doing potentially two tests.
|
||||||
*/
|
*/
|
||||||
if( aUseBBoxCache && !m_bbox.Contains( aPt ) )
|
//if( aUseBBoxCache && !m_bbox.Contains( aPt ) )
|
||||||
return false;
|
//return false;
|
||||||
|
|
||||||
if( !m_closed || PointCount() < 3 )
|
// fixme: bbox cache...
|
||||||
|
|
||||||
|
if( !IsClosed() || GetPointCount() < 3 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool inside = false;
|
bool inside = false;
|
||||||
|
@ -626,13 +630,12 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUs
|
||||||
* Note: we open-code CPoint() here so that we don't end up calculating the size of the
|
* Note: we open-code CPoint() here so that we don't end up calculating the size of the
|
||||||
* vector number-of-points times. This has a non-trivial impact on zone fill times.
|
* vector number-of-points times. This has a non-trivial impact on zone fill times.
|
||||||
*/
|
*/
|
||||||
const std::vector<VECTOR2I>& points = CPoints();
|
int pointCount = GetPointCount();
|
||||||
int pointCount = points.size();
|
|
||||||
|
|
||||||
for( int i = 0; i < pointCount; )
|
for( int i = 0; i < pointCount; )
|
||||||
{
|
{
|
||||||
const auto p1 = points[ i++ ];
|
const auto p1 = GetPoint( i++ );
|
||||||
const auto p2 = points[ i == pointCount ? 0 : i ];
|
const auto p2 = GetPoint( i == pointCount ? 0 : i );
|
||||||
const auto diff = p2 - p1;
|
const auto diff = p2 - p1;
|
||||||
|
|
||||||
if( diff.y != 0 )
|
if( diff.y != 0 )
|
||||||
|
@ -653,25 +656,25 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aPt, int aAccuracy ) const
|
bool SHAPE_LINE_CHAIN_BASE::PointOnEdge( const VECTOR2I& aPt, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
return EdgeContainingPoint( aPt, aAccuracy ) >= 0;
|
return EdgeContainingPoint( aPt, aAccuracy ) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aPt, int aAccuracy ) const
|
int SHAPE_LINE_CHAIN_BASE::EdgeContainingPoint( const VECTOR2I& aPt, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
if( !PointCount() )
|
if( !GetPointCount() )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
else if( PointCount() == 1 )
|
else if( GetPointCount() == 1 )
|
||||||
{
|
{
|
||||||
VECTOR2I dist = m_points[0] - aPt;
|
VECTOR2I dist = GetPoint(0) - aPt;
|
||||||
return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1;
|
return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = 0; i < SegmentCount(); i++ )
|
for( int i = 0; i < GetSegmentCount(); i++ )
|
||||||
{
|
{
|
||||||
const SEG s = CSegment( i );
|
const SEG s = GetSegment( i );
|
||||||
|
|
||||||
if( s.A == aPt || s.B == aPt )
|
if( s.A == aPt || s.B == aPt )
|
||||||
return i;
|
return i;
|
||||||
|
|
Loading…
Reference in New Issue