Lift some point-vs-shape APIs into SHAPE base class
Also provide a virtual method for conversion to polygon
This commit is contained in:
parent
d02e4f3254
commit
bf0592ad53
|
@ -30,11 +30,13 @@
|
|||
#include <vector>
|
||||
#include <geometry/seg.h>
|
||||
#include <geometry/eda_angle.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <math/vector2d.h>
|
||||
#include <math/box2.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class SHAPE_LINE_CHAIN;
|
||||
class SHAPE_POLY_SET;
|
||||
|
||||
/**
|
||||
* Lists all supported shapes.
|
||||
|
@ -232,6 +234,39 @@ public:
|
|||
return BBox( 0 ).Centre(); // if nothing better is available....
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum distance from a given point to this shape.
|
||||
* Always returns zero if the point is inside a closed shape and aOutlineOnly is false.
|
||||
*
|
||||
* @param aP is the point to test
|
||||
* @param aOutlineOnly can be set to true to measure the distance to the outline of the shape
|
||||
* @return the distance from the shape to aP
|
||||
*/
|
||||
virtual int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||
|
||||
/**
|
||||
* @see SHAPE::Distance
|
||||
*/
|
||||
virtual SEG::ecoord SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||
|
||||
/**
|
||||
* Check if point \a aP lies inside a closed shape. Always returns false if this shape is not closed.
|
||||
*
|
||||
* @param aPt point to check
|
||||
* @param aUseBBoxCache gives better performance if the bounding box caches have been
|
||||
* generated.
|
||||
* @return true if the point is inside the shape (edge is not treated as being inside).
|
||||
*/
|
||||
virtual bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0, bool aUseBBoxCache = false ) const;
|
||||
|
||||
/**
|
||||
* Fills a SHAPE_POLY_SET with a polygon representation of this shape.
|
||||
* @param aBuffer [out] will be filled with the polygonal representation of this shape.
|
||||
* @param aError controls the maximum allowed deviation when converting rounded shapes to segments
|
||||
* @param aErrorLoc controls where the error is placed when approximating rounded shapes
|
||||
*/
|
||||
virtual void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError, ERROR_LOC aErrorLoc ) const = 0;
|
||||
|
||||
/**
|
||||
* @param aCenter is the rotation center.
|
||||
* @param aAngle rotation angle.
|
||||
|
@ -288,18 +323,9 @@ public:
|
|||
virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
|
||||
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 override;
|
||||
|
||||
/**
|
||||
* Check if point \a 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 performance 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;
|
||||
bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0, bool aUseBBoxCache = false ) const override;
|
||||
|
||||
/**
|
||||
* Check if point \a aP lies on an edge or vertex of the line chain.
|
||||
|
@ -324,6 +350,10 @@ public:
|
|||
virtual bool IsClosed() const = 0;
|
||||
|
||||
virtual BOX2I* GetCachedBBox() const { return nullptr; }
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // __SHAPE_H
|
||||
|
|
|
@ -244,6 +244,9 @@ public:
|
|||
&& ( aArc.m_width == m_width );
|
||||
}
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ) const
|
||||
{
|
||||
|
|
|
@ -137,6 +137,9 @@ public:
|
|||
|
||||
virtual const std::string Format( bool aCplusPlus = true ) const override;
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
CIRCLE m_circle;
|
||||
};
|
||||
|
|
|
@ -154,7 +154,8 @@ public:
|
|||
std::copy( m_shapes.begin(), m_shapes.end(), std::back_inserter( aSubshapes ) );
|
||||
}
|
||||
|
||||
bool ConvertToSimplePolygon( SHAPE_SIMPLE* aOut ) const;
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
BOX2I m_cachedBBox;
|
||||
|
|
|
@ -456,14 +456,6 @@ public:
|
|||
return &m_bbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the minimum distance between the line chain and a point \a aP.
|
||||
*
|
||||
* @param aP the point.
|
||||
* @return minimum distance.
|
||||
*/
|
||||
int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
|
||||
|
||||
/**
|
||||
* Reverse point order in the line chain.
|
||||
*
|
||||
|
@ -875,6 +867,9 @@ public:
|
|||
virtual size_t GetPointCount() const override { return PointCount(); }
|
||||
virtual size_t GetSegmentCount() const override { return SegmentCount(); }
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
protected:
|
||||
friend class SHAPE_POLY_SET;
|
||||
|
||||
|
|
|
@ -75,6 +75,9 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1203,6 +1203,9 @@ public:
|
|||
bool CollideEdge( const VECTOR2I& aPoint, VERTEX_INDEX* aClosestVertex = nullptr,
|
||||
int aClearance = 0 ) const;
|
||||
|
||||
bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0,
|
||||
bool aUseBBoxCache = false ) const override;
|
||||
|
||||
/**
|
||||
* Construct BBoxCaches for Contains(), below.
|
||||
*
|
||||
|
@ -1403,6 +1406,12 @@ public:
|
|||
*/
|
||||
static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false );
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override
|
||||
{
|
||||
aBuffer.Append( *this );
|
||||
}
|
||||
|
||||
private:
|
||||
enum DROP_TRIANGULATION_FLAG { SINGLETON };
|
||||
|
||||
|
|
|
@ -190,6 +190,9 @@ public:
|
|||
|
||||
virtual const std::string Format( bool aCplusPlus = true ) const override;
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
VECTOR2I m_p0; ///< Top-left corner
|
||||
int m_w; ///< Width
|
||||
|
|
|
@ -161,6 +161,9 @@ public:
|
|||
|
||||
virtual const std::string Format( bool aCplusPlus = true ) const override;
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
SEG m_seg;
|
||||
int m_width;
|
||||
|
|
|
@ -180,6 +180,9 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const override;
|
||||
|
||||
private:
|
||||
// vertices
|
||||
SHAPE_LINE_CHAIN m_points;
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <geometry/shape_simple.h>
|
||||
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
|
||||
bool SHAPE::Parse( std::stringstream& aStream )
|
||||
{
|
||||
|
@ -75,3 +80,40 @@ int SHAPE::GetClearance( const SHAPE* aOther ) const
|
|||
|
||||
return actual_clearance;
|
||||
}
|
||||
|
||||
|
||||
int SHAPE::Distance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||
{
|
||||
return sqrt( SquaredDistance( aP, aOutlineOnly ) );
|
||||
}
|
||||
|
||||
|
||||
SEG::ecoord SHAPE::SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||
{
|
||||
SHAPE_POLY_SET buffer;
|
||||
TransformToPolygon( buffer, 0, ERROR_INSIDE );
|
||||
|
||||
if( buffer.OutlineCount() < 1 )
|
||||
return VECTOR2I::ECOORD_MAX;
|
||||
|
||||
return buffer.COutline( 0 ).SquaredDistance( aP, aOutlineOnly );
|
||||
}
|
||||
|
||||
|
||||
bool SHAPE::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUseBBoxCache ) const
|
||||
{
|
||||
SHAPE_POLY_SET buffer;
|
||||
TransformToPolygon( buffer, aAccuracy, ERROR_INSIDE );
|
||||
|
||||
if( buffer.OutlineCount() < 1 )
|
||||
return false;
|
||||
|
||||
return buffer.COutline( 0 ).PointInside( aPt, aAccuracy, aUseBBoxCache );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_SIMPLE::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
aBuffer.AddOutline( m_points );
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <geometry/seg.h> // for SEG
|
||||
#include <geometry/shape_arc.h>
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <trigo.h>
|
||||
|
||||
|
||||
|
@ -610,3 +611,9 @@ bool SHAPE_ARC::sliceContainsPoint( const VECTOR2I& p ) const
|
|||
|
||||
return alg::within_wrapped_range( phi.AsDegrees(), sa.AsDegrees(), ea.AsDegrees(), 360.0 );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_ARC::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError, ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
TransformArcToPolygon( aBuffer, m_start, m_mid, m_end, m_width, aError, aErrorLoc );
|
||||
}
|
||||
|
|
|
@ -155,7 +155,9 @@ bool SHAPE_COMPOUND::Collide( const SEG& aSeg, int aClearance, int* aActual,
|
|||
}
|
||||
|
||||
|
||||
bool SHAPE_COMPOUND::ConvertToSimplePolygon( SHAPE_SIMPLE* aOut ) const
|
||||
void SHAPE_COMPOUND::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
return false;
|
||||
for( SHAPE* item : m_shapes )
|
||||
item->TransformToPolygon( aBuffer, aError, aErrorLoc );
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <core/kicad_algo.h> // for alg::run_on_pair
|
||||
#include <geometry/seg.h> // for SEG, OPT_VECTOR2I
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <math/box2.h> // for BOX2I
|
||||
#include <math/util.h> // for rescale
|
||||
#include <math/vector2d.h> // for VECTOR2, VECTOR2I
|
||||
|
@ -875,12 +876,6 @@ void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex )
|
|||
}
|
||||
|
||||
|
||||
int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||
{
|
||||
return sqrt( SquaredDistance( aP, aOutlineOnly ) );
|
||||
}
|
||||
|
||||
|
||||
SEG::ecoord SHAPE_LINE_CHAIN_BASE::SquaredDistance( const VECTOR2I& aP, bool aOutlineOnly ) const
|
||||
{
|
||||
ecoord d = VECTOR2I::ECOORD_MAX;
|
||||
|
@ -2133,6 +2128,13 @@ double SHAPE_LINE_CHAIN::Area( bool aAbsolute ) const
|
|||
}
|
||||
|
||||
|
||||
void SHAPE_LINE_CHAIN::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
aBuffer.AddOutline( *this );
|
||||
}
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN::POINT_INSIDE_TRACKER::POINT_INSIDE_TRACKER( const VECTOR2I& aPoint ) :
|
||||
m_point( aPoint ),
|
||||
m_finished( false ),
|
||||
|
|
|
@ -3065,3 +3065,15 @@ SHAPE_POLY_SET::BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAI
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool SHAPE_POLY_SET::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUseBBoxCache ) const
|
||||
{
|
||||
for( int idx = 0; idx < OutlineCount(); idx++ )
|
||||
{
|
||||
if( COutline( idx ).PointInside( aPt, aAccuracy, aUseBBoxCache ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual, VECTOR2I* aLocation ) const
|
||||
{
|
||||
|
@ -107,3 +108,17 @@ const std::string SHAPE_RECT::Format( bool aCplusPlus ) const
|
|||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_RECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
int idx = aBuffer.NewOutline();
|
||||
SHAPE_LINE_CHAIN& outline = aBuffer.Outline( idx );
|
||||
|
||||
outline.Append( m_p0 );
|
||||
outline.Append( { m_p0.x + m_w, m_p0.y } );
|
||||
outline.Append( { m_p0.x + m_w, m_p0.y + m_h } );
|
||||
outline.Append( { m_p0.x, m_p0.y + m_h } );
|
||||
outline.SetClosed( true );
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/shape_circle.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
const std::string SHAPE_SEGMENT::Format( bool aCplusPlus ) const
|
||||
{
|
||||
|
@ -87,6 +88,14 @@ const std::string SHAPE_CIRCLE::Format( bool aCplusPlus ) const
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_CIRCLE::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
TransformCircleToPolygon( aBuffer, m_circle.Center, m_circle.Radius, aError, aErrorLoc );
|
||||
}
|
||||
|
||||
|
||||
bool SHAPE_SEGMENT::Is45Degree( EDA_ANGLE aTollerance ) const
|
||||
{
|
||||
EDA_ANGLE mag = EDA_ANGLE( m_seg.A - m_seg.B ).Normalize180();
|
||||
|
@ -102,3 +111,9 @@ bool SHAPE_SEGMENT::Is45Degree( EDA_ANGLE aTollerance ) const
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_SEGMENT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
|
||||
ERROR_LOC aErrorLoc ) const
|
||||
{
|
||||
TransformOvalToPolygon( aBuffer, m_seg.A, m_seg.B, m_width, aError, aErrorLoc );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue