Formatting.
This commit is contained in:
parent
65f9212f46
commit
2c2630ef9e
|
@ -55,5 +55,6 @@ void BuildConvexHull( std::vector<wxPoint>& aResult, const SHAPE_POLY_SET& aPoly
|
||||||
* @param aRotation = the rotation of the convex hull
|
* @param aRotation = the rotation of the convex hull
|
||||||
*/
|
*/
|
||||||
void BuildConvexHull( std::vector<wxPoint>& aResult, const SHAPE_POLY_SET& aPolygons,
|
void BuildConvexHull( std::vector<wxPoint>& aResult, const SHAPE_POLY_SET& aPolygons,
|
||||||
wxPoint aPosition, double aRotation );
|
wxPoint aPosition, double aRotation );
|
||||||
|
|
||||||
#endif // __CONVEX_HULL_H
|
#endif // __CONVEX_HULL_H
|
||||||
|
|
|
@ -59,8 +59,29 @@
|
||||||
|
|
||||||
class POLY_GRID_PARTITION
|
class POLY_GRID_PARTITION
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
|
POLY_GRID_PARTITION( const SHAPE_LINE_CHAIN& aPolyOutline, int gridSize )
|
||||||
|
{
|
||||||
|
build( aPolyOutline, gridSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContainsPoint( const VECTOR2I& aP, int aClearance = 0 ) // const
|
||||||
|
{
|
||||||
|
if( containsPoint(aP) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( aClearance > 0 )
|
||||||
|
return checkClearance ( aP, aClearance );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BOX2I& BBox() const
|
||||||
|
{
|
||||||
|
return m_bbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
enum HASH_FLAG
|
enum HASH_FLAG
|
||||||
{
|
{
|
||||||
LEAD_EDGE = 1,
|
LEAD_EDGE = 1,
|
||||||
|
@ -92,6 +113,111 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int containsPoint( const VECTOR2I& aP, bool debug = false ) const
|
||||||
|
{
|
||||||
|
const auto gridPoint = poly2grid( aP );
|
||||||
|
|
||||||
|
if( !m_bbox.Contains( aP ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SCAN_STATE state;
|
||||||
|
const EDGE_LIST& cell = m_grid[ m_gridSize * gridPoint.y + gridPoint.x ];
|
||||||
|
|
||||||
|
scanCell( state, cell, aP, gridPoint.x, gridPoint.y );
|
||||||
|
|
||||||
|
if( state.nearest < 0 )
|
||||||
|
{
|
||||||
|
state = SCAN_STATE();
|
||||||
|
|
||||||
|
for( int d = 1; d <= m_gridSize; d++ )
|
||||||
|
{
|
||||||
|
int xl = gridPoint.x - d;
|
||||||
|
int xh = gridPoint.x + d;
|
||||||
|
|
||||||
|
if( xl >= 0 )
|
||||||
|
{
|
||||||
|
const EDGE_LIST& cell2 = m_grid[ m_gridSize * gridPoint.y + xl ];
|
||||||
|
scanCell( state, cell2, aP, xl, gridPoint.y );
|
||||||
|
|
||||||
|
if( state.nearest >= 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xh < m_gridSize )
|
||||||
|
{
|
||||||
|
const EDGE_LIST& cell2 = m_grid[ m_gridSize * gridPoint.y + xh ];
|
||||||
|
scanCell( state, cell2, aP, xh, gridPoint.y );
|
||||||
|
|
||||||
|
if( state.nearest >= 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOM_EXTRA_VERBOSE
|
||||||
|
printf("Nearest: %d prev: %d dmax %d\n", state.nearest, state.nearest_prev, state.dist_max );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( state.nearest < 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( state.dist_max == 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
|
// special case for diagonal 'slits', e.g. two segments that partially overlap each other.
|
||||||
|
// Just love handling degeneracy... As I can't find any reliable way of fixing it for the moment,
|
||||||
|
// let's fall back to the good old O(N) point-in-polygon test
|
||||||
|
if( state.nearest_prev >= 0 && state.dist_max == state.dist_prev )
|
||||||
|
{
|
||||||
|
int d = std::abs( state.nearest_prev - state.nearest );
|
||||||
|
|
||||||
|
if( (d == 1) && ( (m_flags[state.nearest_prev] & m_flags[state.nearest]) == 0 ) )
|
||||||
|
{
|
||||||
|
return m_outline.PointInside( aP );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( state.dist_max > 0 )
|
||||||
|
{
|
||||||
|
return m_flags[state.nearest] & LEAD_EDGE ? 1 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_flags[state.nearest] & TRAIL_EDGE ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkClearance( const VECTOR2I& aP, int aClearance )
|
||||||
|
{
|
||||||
|
int gx0 = poly2gridX( aP.x - aClearance - 1);
|
||||||
|
int gx1 = poly2gridX( aP.x + aClearance + 1);
|
||||||
|
int gy0 = poly2gridY( aP.y - aClearance - 1);
|
||||||
|
int gy1 = poly2gridY( aP.y + aClearance + 1);
|
||||||
|
|
||||||
|
using ecoord = VECTOR2I::extended_type;
|
||||||
|
|
||||||
|
ecoord dist = (ecoord) aClearance * aClearance;
|
||||||
|
|
||||||
|
for ( int gx = gx0; gx <= gx1; gx++ )
|
||||||
|
{
|
||||||
|
for ( int gy = gy0; gy <= gy1; gy++ )
|
||||||
|
{
|
||||||
|
const auto& cell = m_grid [ m_gridSize * gy + gx];
|
||||||
|
for ( auto index : cell )
|
||||||
|
{
|
||||||
|
const auto& seg = m_outline.Segment( index );
|
||||||
|
|
||||||
|
if ( seg.SquaredDistance(aP) <= dist )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// convertes grid cell coordinates to the polygon coordinates
|
// convertes grid cell coordinates to the polygon coordinates
|
||||||
const VECTOR2I grid2poly( const VECTOR2I& p ) const
|
const VECTOR2I grid2poly( const VECTOR2I& p ) const
|
||||||
{
|
{
|
||||||
|
@ -405,141 +531,11 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
POLY_GRID_PARTITION( const SHAPE_LINE_CHAIN& aPolyOutline, int gridSize )
|
|
||||||
{
|
|
||||||
build( aPolyOutline, gridSize );
|
|
||||||
}
|
|
||||||
|
|
||||||
int containsPoint( const VECTOR2I& aP, bool debug = false ) const
|
|
||||||
{
|
|
||||||
const auto gridPoint = poly2grid( aP );
|
|
||||||
|
|
||||||
if( !m_bbox.Contains( aP ) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
SCAN_STATE state;
|
|
||||||
const EDGE_LIST& cell = m_grid[ m_gridSize * gridPoint.y + gridPoint.x ];
|
|
||||||
|
|
||||||
scanCell( state, cell, aP, gridPoint.x, gridPoint.y );
|
|
||||||
|
|
||||||
if( state.nearest < 0 )
|
|
||||||
{
|
|
||||||
state = SCAN_STATE();
|
|
||||||
|
|
||||||
for( int d = 1; d <= m_gridSize; d++ )
|
|
||||||
{
|
|
||||||
int xl = gridPoint.x - d;
|
|
||||||
int xh = gridPoint.x + d;
|
|
||||||
|
|
||||||
if( xl >= 0 )
|
|
||||||
{
|
|
||||||
const EDGE_LIST& cell2 = m_grid[ m_gridSize * gridPoint.y + xl ];
|
|
||||||
scanCell( state, cell2, aP, xl, gridPoint.y );
|
|
||||||
|
|
||||||
if( state.nearest >= 0 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( xh < m_gridSize )
|
|
||||||
{
|
|
||||||
const EDGE_LIST& cell2 = m_grid[ m_gridSize * gridPoint.y + xh ];
|
|
||||||
scanCell( state, cell2, aP, xh, gridPoint.y );
|
|
||||||
|
|
||||||
if( state.nearest >= 0 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TOM_EXTRA_VERBOSE
|
|
||||||
printf("Nearest: %d prev: %d dmax %d\n", state.nearest, state.nearest_prev, state.dist_max );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( state.nearest < 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if( state.dist_max == 0 )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
|
||||||
// special case for diagonal 'slits', e.g. two segments that partially overlap each other.
|
|
||||||
// Just love handling degeneracy... As I can't find any reliable way of fixing it for the moment,
|
|
||||||
// let's fall back to the good old O(N) point-in-polygon test
|
|
||||||
if( state.nearest_prev >= 0 && state.dist_max == state.dist_prev )
|
|
||||||
{
|
|
||||||
int d = std::abs( state.nearest_prev - state.nearest );
|
|
||||||
|
|
||||||
if( (d == 1) && ( (m_flags[state.nearest_prev] & m_flags[state.nearest]) == 0 ) )
|
|
||||||
{
|
|
||||||
return m_outline.PointInside( aP );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( state.dist_max > 0 )
|
|
||||||
{
|
|
||||||
return m_flags[state.nearest] & LEAD_EDGE ? 1 : 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return m_flags[state.nearest] & TRAIL_EDGE ? 1 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkClearance( const VECTOR2I& aP, int aClearance )
|
|
||||||
{
|
|
||||||
int gx0 = poly2gridX( aP.x - aClearance - 1);
|
|
||||||
int gx1 = poly2gridX( aP.x + aClearance + 1);
|
|
||||||
int gy0 = poly2gridY( aP.y - aClearance - 1);
|
|
||||||
int gy1 = poly2gridY( aP.y + aClearance + 1);
|
|
||||||
|
|
||||||
using ecoord = VECTOR2I::extended_type;
|
|
||||||
|
|
||||||
ecoord dist = (ecoord) aClearance * aClearance;
|
|
||||||
|
|
||||||
for ( int gx = gx0; gx <= gx1; gx++ )
|
|
||||||
{
|
|
||||||
for ( int gy = gy0; gy <= gy1; gy++ )
|
|
||||||
{
|
|
||||||
const auto& cell = m_grid [ m_gridSize * gy + gx];
|
|
||||||
for ( auto index : cell )
|
|
||||||
{
|
|
||||||
const auto& seg = m_outline.Segment( index );
|
|
||||||
|
|
||||||
if ( seg.SquaredDistance(aP) <= dist )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ContainsPoint( const VECTOR2I& aP, int aClearance = 0 ) // const
|
|
||||||
{
|
|
||||||
if( containsPoint(aP) )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if( aClearance > 0 )
|
|
||||||
return checkClearance ( aP, aClearance );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BOX2I& BBox() const
|
|
||||||
{
|
|
||||||
return m_bbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_gridSize;
|
int m_gridSize;
|
||||||
SHAPE_LINE_CHAIN m_outline;
|
SHAPE_LINE_CHAIN m_outline;
|
||||||
BOX2I m_bbox;
|
BOX2I m_bbox;
|
||||||
std::vector<int> m_flags;
|
std::vector<int> m_flags;
|
||||||
std::vector<EDGE_LIST> m_grid;
|
std::vector<EDGE_LIST> m_grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,18 +58,41 @@
|
||||||
|
|
||||||
class PolygonTriangulation
|
class PolygonTriangulation
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PolygonTriangulation( SHAPE_POLY_SET::TRIANGULATED_POLYGON& aResult ) :
|
PolygonTriangulation( SHAPE_POLY_SET::TRIANGULATED_POLYGON& aResult ) :
|
||||||
m_result( aResult )
|
m_result( aResult )
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
|
||||||
|
{
|
||||||
|
m_bbox = aPoly.BBox();
|
||||||
|
m_result.Clear();
|
||||||
|
|
||||||
|
if( !m_bbox.GetWidth() || !m_bbox.GetHeight() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/// Place the polygon Vertices into a circular linked list
|
||||||
|
/// and check for lists that have only 0, 1 or 2 elements and
|
||||||
|
/// therefore cannot be polygons
|
||||||
|
Vertex* firstVertex = createList( aPoly );
|
||||||
|
if( !firstVertex || firstVertex->prev == firstVertex->next )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
firstVertex->updateList();
|
||||||
|
|
||||||
|
auto retval = earcutList( firstVertex );
|
||||||
|
m_vertices.clear();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
Vertex( size_t aIndex, double aX, double aY, PolygonTriangulation* aParent ) :
|
Vertex( size_t aIndex, double aX, double aY, PolygonTriangulation* aParent ) :
|
||||||
i( aIndex ), x( aX ), y( aY ), parent( aParent )
|
i( aIndex ),
|
||||||
|
x( aX ),
|
||||||
|
y( aY ),
|
||||||
|
parent( aParent )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Vertex& operator=( const Vertex& ) = delete;
|
Vertex& operator=( const Vertex& ) = delete;
|
||||||
|
@ -136,7 +159,6 @@ private:
|
||||||
prevZ = NULL;
|
prevZ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void updateOrder()
|
void updateOrder()
|
||||||
{
|
{
|
||||||
if( !z )
|
if( !z )
|
||||||
|
@ -232,10 +254,6 @@ private:
|
||||||
Vertex* nextZ = nullptr;
|
Vertex* nextZ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOX2I m_bbox;
|
|
||||||
std::deque<Vertex> m_vertices;
|
|
||||||
SHAPE_POLY_SET::TRIANGULATED_POLYGON& m_result;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the Morton code of the Vertex
|
* Calculate the Morton code of the Vertex
|
||||||
* http://www.graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
|
* http://www.graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
|
||||||
|
@ -653,30 +671,10 @@ private:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
public:
|
BOX2I m_bbox;
|
||||||
|
std::deque<Vertex> m_vertices;
|
||||||
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
|
SHAPE_POLY_SET::TRIANGULATED_POLYGON& m_result;
|
||||||
{
|
|
||||||
m_bbox = aPoly.BBox();
|
|
||||||
m_result.Clear();
|
|
||||||
|
|
||||||
if( !m_bbox.GetWidth() || !m_bbox.GetHeight() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/// Place the polygon Vertices into a circular linked list
|
|
||||||
/// and check for lists that have only 0, 1 or 2 elements and
|
|
||||||
/// therefore cannot be polygons
|
|
||||||
Vertex* firstVertex = createList( aPoly );
|
|
||||||
if( !firstVertex || firstVertex->prev == firstVertex->next )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
firstVertex->updateList();
|
|
||||||
|
|
||||||
auto retval = earcutList( firstVertex );
|
|
||||||
m_vertices.clear();
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__POLYGON_TRIANGULATION_H
|
#endif //__POLYGON_TRIANGULATION_H
|
||||||
|
|
|
@ -60,8 +60,8 @@ public:
|
||||||
* Creates a segment between (aX1, aY1) and (aX2, aY2)
|
* Creates a segment between (aX1, aY1) and (aX2, aY2)
|
||||||
*/
|
*/
|
||||||
SEG( int aX1, int aY1, int aX2, int aY2 ) :
|
SEG( int aX1, int aY1, int aX2, int aY2 ) :
|
||||||
A ( VECTOR2I( aX1, aY1 ) ),
|
A( VECTOR2I( aX1, aY1 ) ),
|
||||||
B ( VECTOR2I( aX2, aY2 ) )
|
B( VECTOR2I( aX2, aY2 ) )
|
||||||
{
|
{
|
||||||
m_index = -1;
|
m_index = -1;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,9 @@ public:
|
||||||
* Constructor
|
* Constructor
|
||||||
* Creates a segment between (aA) and (aB)
|
* Creates a segment between (aA) and (aB)
|
||||||
*/
|
*/
|
||||||
SEG( const VECTOR2I& aA, const VECTOR2I& aB ) : A( aA ), B( aB )
|
SEG( const VECTOR2I& aA, const VECTOR2I& aB ) :
|
||||||
|
A( aA ),
|
||||||
|
B( aB )
|
||||||
{
|
{
|
||||||
m_index = -1;
|
m_index = -1;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +84,9 @@ public:
|
||||||
* @param aB reference to the end point in the parent shape
|
* @param aB reference to the end point in the parent shape
|
||||||
* @param aIndex index of the segment within the parent shape
|
* @param aIndex index of the segment within the parent shape
|
||||||
*/
|
*/
|
||||||
SEG( const VECTOR2I& aA, const VECTOR2I& aB, int aIndex ) : A( aA ), B( aB )
|
SEG( const VECTOR2I& aA, const VECTOR2I& aB, int aIndex ) :
|
||||||
|
A( aA ),
|
||||||
|
B( aB )
|
||||||
{
|
{
|
||||||
m_index = aIndex;
|
m_index = aIndex;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +94,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Copy constructor
|
* Copy constructor
|
||||||
*/
|
*/
|
||||||
SEG( const SEG& aSeg ) : A( aSeg.A ), B( aSeg.B ), m_index( aSeg.m_index )
|
SEG( const SEG& aSeg ) :
|
||||||
|
A( aSeg.A ),
|
||||||
|
B( aSeg.B ),
|
||||||
|
m_index( aSeg.m_index )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +296,7 @@ public:
|
||||||
|
|
||||||
if( Contains( aSeg.A ) || Contains( aSeg.B ) )
|
if( Contains( aSeg.A ) || Contains( aSeg.B ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( aSeg.Contains( A ) || aSeg.Contains( B ) )
|
if( aSeg.Contains( A ) || aSeg.Contains( B ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -355,6 +363,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
///> index withing the parent shape (used when m_is_local == false)
|
///> index withing the parent shape (used when m_is_local == false)
|
||||||
int m_index;
|
int m_index;
|
||||||
};
|
};
|
||||||
|
|
|
@ -82,7 +82,8 @@ public:
|
||||||
* Creates an empty shape of type aType
|
* Creates an empty shape of type aType
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SHAPE_BASE( SHAPE_TYPE aType ) : m_type( aType )
|
SHAPE_BASE( SHAPE_TYPE aType ) :
|
||||||
|
m_type( aType )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -121,24 +122,20 @@ protected:
|
||||||
*/
|
*/
|
||||||
class SHAPE : public SHAPE_BASE
|
class SHAPE : public SHAPE_BASE
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
typedef VECTOR2I::extended_type ecoord;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* Creates an empty shape of type aType
|
* Creates an empty shape of type aType
|
||||||
*/
|
*/
|
||||||
|
SHAPE( SHAPE_TYPE aType ) :
|
||||||
SHAPE( SHAPE_TYPE aType ) : SHAPE_BASE( aType )
|
SHAPE_BASE( aType )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~SHAPE()
|
virtual ~SHAPE()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Clone()
|
* Function Clone()
|
||||||
*
|
*
|
||||||
|
@ -173,8 +170,8 @@ public:
|
||||||
* event of a collision.
|
* event of a collision.
|
||||||
* @return true, if there is a collision.
|
* @return true, if there is a collision.
|
||||||
*/
|
*/
|
||||||
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0,
|
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
|
||||||
int* aActual = nullptr, VECTOR2I* aLocation = nullptr ) const
|
VECTOR2I* aLocation = nullptr ) const
|
||||||
{
|
{
|
||||||
return Collide( SEG( aP, aP ), aClearance, aActual, aLocation );
|
return Collide( SEG( aP, aP ), aClearance, aActual, aLocation );
|
||||||
}
|
}
|
||||||
|
@ -248,13 +245,17 @@ 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:
|
||||||
|
typedef VECTOR2I::extended_type ecoord;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SHAPE_LINE_CHAIN_BASE : public SHAPE
|
class SHAPE_LINE_CHAIN_BASE : public SHAPE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SHAPE_LINE_CHAIN_BASE( SHAPE_TYPE aType ) : SHAPE( aType )
|
SHAPE_LINE_CHAIN_BASE( SHAPE_TYPE aType ) :
|
||||||
|
SHAPE( aType )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +274,8 @@ public:
|
||||||
* of a collision.
|
* of a collision.
|
||||||
* @return true, when a collision has been found
|
* @return true, when a collision has been found
|
||||||
*/
|
*/
|
||||||
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0,
|
virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
|
||||||
int* aActual = nullptr, VECTOR2I* aLocation = nullptr ) const override;
|
VECTOR2I* aLocation = nullptr ) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Collide()
|
* Function Collide()
|
||||||
|
@ -287,8 +288,8 @@ public:
|
||||||
* @return true, when a collision has been found
|
* @return true, when a collision has been found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
virtual bool Collide( const SEG& aSeg, int aClearance = 0,
|
virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
|
||||||
int* aActual = nullptr, VECTOR2I* aLocation = nullptr ) const override;
|
VECTOR2I* aLocation = nullptr ) const override;
|
||||||
|
|
||||||
SEG::ecoord SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
SEG::ecoord SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,9 @@ public:
|
||||||
static const int MIN_PRECISION_IU = 4;
|
static const int MIN_PRECISION_IU = 4;
|
||||||
|
|
||||||
SHAPE_ARC() :
|
SHAPE_ARC() :
|
||||||
SHAPE( SH_ARC ), m_width( 0 ) {};
|
SHAPE( SH_ARC ),
|
||||||
|
m_width( 0 )
|
||||||
|
{};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHAPE_ARC ctor.
|
* SHAPE_ARC ctor.
|
||||||
|
@ -50,8 +52,8 @@ public:
|
||||||
* @param aCenterAngle is the arc angle in degrees
|
* @param aCenterAngle is the arc angle in degrees
|
||||||
* @param aWidth is the arc line thickness
|
* @param aWidth is the arc line thickness
|
||||||
*/
|
*/
|
||||||
SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
|
SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, double aCenterAngle,
|
||||||
double aCenterAngle, int aWidth = 0 );
|
int aWidth = 0 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHAPE_ARC ctor.
|
* SHAPE_ARC ctor.
|
||||||
|
@ -60,8 +62,8 @@ public:
|
||||||
* @param aArcMid is the arc mid point
|
* @param aArcMid is the arc mid point
|
||||||
* @param aWidth is the arc line thickness
|
* @param aWidth is the arc line thickness
|
||||||
*/
|
*/
|
||||||
SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid,
|
SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid, const VECTOR2I& aArcEnd,
|
||||||
const VECTOR2I& aArcEnd, int aWidth );
|
int aWidth );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHAPE_ARC ctor.
|
* SHAPE_ARC ctor.
|
||||||
|
@ -145,7 +147,6 @@ public:
|
||||||
const SHAPE_LINE_CHAIN ConvertToPolyline( double aAccuracy = 0.005 * PCB_IU_PER_MM ) const;
|
const SHAPE_LINE_CHAIN ConvertToPolyline( double aAccuracy = 0.005 * PCB_IU_PER_MM ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ) const
|
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ) const
|
||||||
{
|
{
|
||||||
return ( ecoord{ aC.y } - aA.y ) * ( ecoord{ aB.x } - aA.x ) >
|
return ( ecoord{ aC.y } - aA.y ) * ( ecoord{ aB.x } - aA.x ) >
|
||||||
|
@ -154,13 +155,13 @@ private:
|
||||||
|
|
||||||
void update_bbox();
|
void update_bbox();
|
||||||
|
|
||||||
|
private:
|
||||||
VECTOR2I m_start;
|
VECTOR2I m_start;
|
||||||
VECTOR2I m_mid;
|
VECTOR2I m_mid;
|
||||||
VECTOR2I m_end;
|
VECTOR2I m_end;
|
||||||
|
|
||||||
int m_width;
|
int m_width;
|
||||||
BOX2I m_bbox;
|
BOX2I m_bbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,11 +35,14 @@ class SHAPE_CIRCLE : public SHAPE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SHAPE_CIRCLE() :
|
SHAPE_CIRCLE() :
|
||||||
SHAPE( SH_CIRCLE ), m_radius( 0 )
|
SHAPE( SH_CIRCLE ),
|
||||||
|
m_radius( 0 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ) :
|
SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ) :
|
||||||
SHAPE( SH_CIRCLE ), m_radius( aRadius ), m_center( aCenter )
|
SHAPE( SH_CIRCLE ),
|
||||||
|
m_radius( aRadius ),
|
||||||
|
m_center( aCenter )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHAPE_CIRCLE( const SHAPE_CIRCLE& aOther ) :
|
SHAPE_CIRCLE( const SHAPE_CIRCLE& aOther ) :
|
||||||
|
@ -122,8 +125,9 @@ public:
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_radius;
|
int m_radius;
|
||||||
VECTOR2I m_center;
|
VECTOR2I m_center;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Collide( const SHAPE* aShape, int aClearance = 0, int* aActual = nullptr,
|
bool Collide( const SHAPE* aShape, int aClearance = 0, int* aActual = nullptr,
|
||||||
VECTOR2I* aLocation = nullptr ) const override
|
VECTOR2I* aLocation = nullptr ) const override
|
||||||
{
|
{
|
||||||
return SHAPE::Collide( aShape, aClearance, aActual, aLocation );
|
return SHAPE::Collide( aShape, aClearance, aActual, aLocation );
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,7 +39,9 @@ public:
|
||||||
* Creates an empty (0-sized) rectangle
|
* Creates an empty (0-sized) rectangle
|
||||||
*/
|
*/
|
||||||
SHAPE_RECT() :
|
SHAPE_RECT() :
|
||||||
SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 )
|
SHAPE( SH_RECT ),
|
||||||
|
m_w( 0 ),
|
||||||
|
m_h( 0 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +49,10 @@ public:
|
||||||
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
|
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
|
||||||
*/
|
*/
|
||||||
SHAPE_RECT( int aX0, int aY0, int aW, int aH ) :
|
SHAPE_RECT( int aX0, int aY0, int aW, int aH ) :
|
||||||
SHAPE( SH_RECT ), m_p0( aX0, aY0 ), m_w( aW ), m_h( aH )
|
SHAPE( SH_RECT ),
|
||||||
|
m_p0( aX0, aY0 ),
|
||||||
|
m_w( aW ),
|
||||||
|
m_h( aH )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +60,10 @@ public:
|
||||||
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
|
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
|
||||||
*/
|
*/
|
||||||
SHAPE_RECT( const VECTOR2I& aP0, int aW, int aH ) :
|
SHAPE_RECT( const VECTOR2I& aP0, int aW, int aH ) :
|
||||||
SHAPE( SH_RECT ), m_p0( aP0 ), m_w( aW ), m_h( aH )
|
SHAPE( SH_RECT ),
|
||||||
|
m_p0( aP0 ),
|
||||||
|
m_w( aW ),
|
||||||
|
m_h( aH )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHAPE_RECT( const SHAPE_RECT& aOther ) :
|
SHAPE_RECT( const SHAPE_RECT& aOther ) :
|
||||||
|
@ -188,14 +196,9 @@ public:
|
||||||
virtual const std::string Format( ) const override;
|
virtual const std::string Format( ) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///> Top-left corner
|
VECTOR2I m_p0; ///> Top-left corner
|
||||||
VECTOR2I m_p0;
|
int m_w; ///> Width
|
||||||
|
int m_h; ///> Height
|
||||||
///> Width
|
|
||||||
int m_w;
|
|
||||||
|
|
||||||
///> Height
|
|
||||||
int m_h;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __SHAPE_RECT_H
|
#endif // __SHAPE_RECT_H
|
||||||
|
|
Loading…
Reference in New Issue