47    ecoord min_dist_sq = min_dist * min_dist;
 
   52    if( dist_sq == 0 || dist_sq < min_dist_sq )
 
   61            *aMTV = 
delta.Resize( min_dist - sqrt( dist_sq ) + 3 );  
 
 
   75        wxASSERT_MSG( !aMTV, wxT( 
"MTV not implemented for SHAPE_RECT to SHAPE_CIRCLE collisions when rect " 
   76                                  "has rounded corners" ) );
 
   79        return outline.SHAPE::Collide( &aB, aClearance, aActual, aLocation );
 
   86    const int      min_dist = aClearance + r;
 
  101    bool inside = c.
x >= p0.
x && c.
x <= ( p0.
x + size.
x )
 
  102                  && c.
y >= p0.
y && c.
y <= ( p0.
y + size.
y );
 
  105    if( inside && !aActual && !aLocation && !aMTV )
 
  108    for( 
int i = 0; i < 4; i++ )
 
  110        const SEG side( vts[i], vts[ i + 1] );
 
  113        ecoord side_dist_sq = ( pn - c ).SquaredEuclideanNorm();
 
  115        if( side_dist_sq < nearest_side_dist_sq )
 
  118            nearest_side_dist_sq = side_dist_sq;
 
  123            if( nearest_side_dist_sq == 0 )
 
  127            if( nearest_side_dist_sq < min_dist_sq && !aActual )
 
  132    if( inside || nearest_side_dist_sq == 0 || nearest_side_dist_sq < min_dist_sq )
 
  135            *aLocation = nearest;
 
  138            *aActual = std::max( 0, (
int) sqrt( nearest_side_dist_sq ) - r );
 
  145                *aMTV = -
delta.Resize( abs( min_dist + 1 + sqrt( nearest_side_dist_sq ) ) + 1 );
 
  147                *aMTV = 
delta.Resize( abs( min_dist + 1 - sqrt( nearest_side_dist_sq ) ) + 1 );
 
 
  166    int dist = ( nearest - c ).EuclideanNorm();
 
  167    int min_dist = aClearance + r;
 
  169    if( dist < min_dist )
 
  171        for( 
int corr = 0; corr < 5; corr++ )
 
  175            if( aB.
Distance( c + f ) >= min_dist )
 
 
  187    int closest_dist = std::numeric_limits<int>::max();
 
  188    int closest_mtv_dist = std::numeric_limits<int>::max();
 
  190    int closest_mtv_seg = -1;
 
  203                if( dist < closest_mtv_dist )
 
  205                    closest_mtv_dist = dist;
 
  216            int collision_dist = 0;
 
  220                            aActual || aLocation ? &collision_dist : 
nullptr,
 
  221                            aLocation ? &pn : 
nullptr ) )
 
  223                if( collision_dist < closest_dist )
 
  226                    closest_dist = collision_dist;
 
  229                if( closest_dist == 0 )
 
  239    if( closest_dist == 0 || closest_dist < aClearance )
 
  242            *aLocation = nearest;
 
  245            *aActual = closest_dist;
 
  254            if (closest_mtv_seg >= 0)
 
 
  290            *aActual = std::max( 0, *aActual - aSeg.
GetWidth() / 2 );
 
 
  302    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  306    int closest_dist = std::numeric_limits<int>::max();
 
  321        std::vector<SEG> a_segs;
 
  322        std::vector<SEG> b_segs;
 
  342        auto seg_sort = []( 
const SEG& a, 
const SEG& b )
 
  344            return a.
A.
x < b.A.x || ( a.
A.
x == b.A.x && a.
A.
y < b.A.y );
 
  347        std::sort( a_segs.begin(), a_segs.end(), seg_sort );
 
  348        std::sort( b_segs.begin(), b_segs.end(), seg_sort );
 
  350        for( 
const SEG& a_seg : a_segs )
 
  352            for( 
const SEG& b_seg : b_segs )
 
  356                if( a_seg.Collide( b_seg, aClearance, aActual || aLocation ? &dist : 
nullptr ) )
 
  358                    if( dist < closest_dist )
 
  360                        nearest = a_seg.NearestPoint( b_seg );
 
  364                    if( closest_dist == 0 )
 
  375    if( (!aActual && !aLocation ) || closest_dist > 0 )
 
  377        std::vector<const SHAPE_LINE_CHAIN*> chains = {
 
  382        std::vector<const SHAPE*> shapes = { &aA, &aB };
 
  384        for( 
int ii = 0; ii < 2; ii++ )
 
  387            const SHAPE* other = shapes[( ii + 1 ) % 2];
 
  392            for( 
size_t jj = 0; jj < 
chain->ArcCount(); jj++ )
 
  396                if( arc.
Collide( other, aClearance, aActual, aLocation ) )
 
  402    if( closest_dist == 0 || closest_dist < aClearance )
 
  405            *aLocation = nearest;
 
  408            *aActual = closest_dist;
 
 
  421        return Collide( aA.
Outline(), aB, aClearance, aActual, aLocation, aMTV );
 
  423    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  427    int closest_dist = std::numeric_limits<int>::max();
 
  439            int collision_dist = 0;
 
  443                            aActual || aLocation ? &collision_dist : 
nullptr,
 
  444                            aLocation ? &pn : 
nullptr ) )
 
  446                if( collision_dist < closest_dist )
 
  449                    closest_dist = collision_dist;
 
  452                if( closest_dist == 0 )
 
  462    if( closest_dist == 0 || closest_dist < aClearance )
 
  465            *aLocation = nearest;
 
  468            *aActual = closest_dist;
 
 
  480    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  487        *aActual = std::max( 0, *aActual - aB.
GetWidth() / 2 );
 
 
  496    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  503        *aActual = std::max( 0, *aActual - aB.
GetWidth() / 2 );
 
 
  513        return Collide( aA.
Outline(), aB, aClearance, aActual, aLocation, aMTV );
 
  515    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  522        *aActual = std::max( 0, *aActual - aB.
GetWidth() / 2 );
 
 
  531    if( aClearance || aActual || aLocation || aMTV || aA.
GetRadius() > 0 || aB.
GetRadius() > 0 )
 
 
  551        bool retval = 
Collide( aB, tmp, aClearance, aActual, aLocation, aMTV );
 
  560    int64_t  dist_sq = std::numeric_limits<int64_t>::max();
 
  563    if( dist_sq == 0 || dist_sq < 
SEG::Square( aClearance ) )
 
  566            *aLocation = ( ptA + ptB ) / 2;
 
  569            *aActual = std::max( 0, 
KiROUND( std::sqrt( dist_sq ) ) );
 
  574            *aMTV = 
delta.Resize( aClearance - std::sqrt( dist_sq ) + 3 );
 
 
  587    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  591    int      closest_dist = std::numeric_limits<int>::max();
 
  597        nearest = aA.
GetP0();
 
  601        int      collision_dist = 0;
 
  611                            aActual || aLocation ? &collision_dist : 
nullptr,
 
  612                            aLocation ? &pn : 
nullptr ) )
 
  614                if( collision_dist < closest_dist )
 
  617                    closest_dist = collision_dist;
 
  620                if( closest_dist == 0 )
 
  629        for( 
size_t i = 0; i < aB.
ArcCount(); i++ )
 
  634            wxASSERT_MSG( arc.
GetWidth() == 0, wxT( 
"Invalid arc width - should be zero" ) );
 
  636            if( aA.
Collide( &arc, aClearance, aActual || aLocation ? &collision_dist : 
nullptr,
 
  637                            aLocation ? &pn : 
nullptr ) )
 
  639                if( collision_dist < closest_dist )
 
  642                    closest_dist = collision_dist;
 
  645                if( closest_dist == 0 )
 
  654    if( closest_dist == 0 || closest_dist < aClearance )
 
  657            *aLocation = nearest;
 
  660            *aActual = closest_dist;
 
 
  673        return Collide( aA, aB.
Outline(), aClearance, aActual, aLocation, aMTV );
 
  678        bool retval = 
Collide( aB, tmp, aClearance, aActual, aLocation, aMTV );
 
  687    int64_t  dist_sq = std::numeric_limits<int64_t>::max();
 
  690    if( dist_sq == 0 || dist_sq < 
SEG::Square( aClearance ) )
 
  693            *aLocation = ( ptA + ptB ) / 2;
 
  696            *aActual = std::max( 0, 
KiROUND( std::sqrt( dist_sq ) ) );
 
  701            *aMTV = 
delta.Resize( aClearance - std::sqrt( dist_sq ) + 3 );
 
 
  714    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  722        return Collide( tmp, aB, aClearance, aActual, aLocation, aMTV );
 
  728        *aActual = std::max( 0, *aActual - aB.
GetWidth() / 2 );
 
 
  741        return Collide( aB, tmp, aClearance, aActual, aLocation, aMTV );
 
  744    wxASSERT_MSG( !aMTV, wxString::Format( wxT( 
"MTV not implemented for %s : %s collisions" ),
 
  748    int      closest_dist = std::numeric_limits<int>::max();
 
  754        nearest = aA.
GetP0();
 
  760            int      collision_dist = 0;
 
  764                            aActual || aLocation ? &collision_dist : 
nullptr,
 
  765                            aLocation ? &pn : 
nullptr ) )
 
  767                if( collision_dist < closest_dist )
 
  770                    closest_dist = collision_dist;
 
  773                if( closest_dist == 0 )
 
  783    if( closest_dist == 0 || closest_dist < aClearance )
 
  786            *aLocation = nearest;
 
  789            *aActual = closest_dist;
 
 
  804        bool retval = 
Collide( aB, tmp, aClearance, aActual, aLocation, aMTV );
 
  815        return Collide( aA, tmp, aClearance, aActual, aLocation, aMTV );
 
  819    int64_t  dist_sq = std::numeric_limits<int64_t>::max();
 
  822    if( dist_sq == 0 || dist_sq < 
SEG::Square( aClearance ) )
 
  825            *aLocation = ( ptA + ptB ) / 2;
 
  828            *aActual = std::max( 0, 
KiROUND( std::sqrt( dist_sq ) ) );
 
  833            *aMTV = 
delta.Resize( aClearance - std::sqrt( dist_sq ) + 3 );
 
 
  843template<
class T_a, 
class T_b>
 
  848    return Collide( *
static_cast<const T_a*
>( aA ), *
static_cast<const T_b*
>( aB ),
 
  849                    aClearance, aActual, aLocation, aMTV);
 
 
  853template<
class T_a, 
class T_b>
 
  857    bool rv = 
Collide( *
static_cast<const T_b*
>( aB ), *
static_cast<const T_a*
>( aA ),
 
  858                       aClearance, aActual, aLocation, aMTV);
 
 
  875        return polySetA->
Collide( aB, aClearance, aActual, aLocation );
 
  882        return polySetB->
Collide( aA, aClearance, aActual, aLocation );
 
 1012        switch( aB->
Type() )
 
 1042        switch( aB->
Type() )
 
 1075    wxFAIL_MSG( wxString::Format( wxT( 
"Unsupported collision: %s with %s" ),
 
 
 1085    int currentActual = std::numeric_limits<int>::max();
 
 1088    bool colliding = 
false;
 
 1096                if( aActual && currentActual > 0 )
 
 1105    auto collideCompoundSubshapes =
 
 1113                                         aActual || aLocation ? &
actual : 
nullptr,
 
 1115                                         aMTV ? &mtv : 
nullptr ) )
 
 1117                    if( 
actual < currentActual )
 
 1143                if( collideCompoundSubshapes( elemA, elemB, aClearance ) )
 
 1162            if( collideCompoundSubshapes( elemA, aB, aClearance ) )
 
 1177            if( collideCompoundSubshapes( aA, elemB, aClearance ) )
 
 1194            *aLocation = currentLocation;
 
 1197            *aActual = currentActual;
 
 
 1209    return collideShapes( 
this, aShape, aClearance, 
nullptr, 
nullptr, aMTV );
 
 
 1215    return collideShapes( 
this, aShape, aClearance, aActual, aLocation, 
nullptr );
 
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
constexpr bool Intersects(const BOX2< Vec > &aRect) const
 
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
 
static SEG::ecoord Square(int a)
 
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
 
int GetWidth() const override
 
const VECTOR2I & GetP1() const
 
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
 
bool IsEffectiveLine() const
 
bool NearestPoints(const SHAPE_ARC &aArc, VECTOR2I &aPtA, VECTOR2I &aPtB, int64_t &aDistSq) const
Compute closest points between this arc and aArc.
 
const VECTOR2I & GetP0() const
 
wxString TypeName() const
 
SHAPE_TYPE Type() const
Return the type of the shape.
 
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
 
const VECTOR2I GetCenter() const
 
void SetCenter(const VECTOR2I &aCenter)
 
const std::vector< SHAPE * > & Shapes() const
 
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if point aP lies closer to us than aClearance.
 
virtual size_t GetPointCount() const =0
 
virtual size_t GetSegmentCount() const =0
 
virtual const VECTOR2I GetPoint(int aIndex) const =0
 
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
 
virtual bool IsClosed() const =0
 
virtual const SEG GetSegment(int aIndex) const =0
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
const SHAPE_ARC & Arc(size_t aArc) const
 
bool IsClosed() const override
 
virtual const SEG GetSegment(int aIndex) const override
 
virtual size_t GetSegmentCount() const override
 
bool IsArcSegment(size_t aSegment) const
 
Represent a set of closed polygons.
 
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
 
bool Collide(const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
 
const SHAPE_LINE_CHAIN Outline() const
 
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
 
const VECTOR2I & GetPosition() const
 
const VECTOR2I GetSize() const
 
const SEG & GetSeg() const
 
int GetWidth() const override
 
bool Collide(const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
 
An abstract shape on 2D plane.
 
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
 
virtual VECTOR2I Centre() const
Compute a center-of-mass of the shape.
 
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
 
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
 
static constexpr extended_type ECOORD_MAX
 
VECTOR2_TRAITS< int32_t >::extended_type extended_type
 
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
 
@ SH_POLY_SET
set of polygons (with holes, etc.)
 
@ SH_RECT
axis-aligned rectangle
 
@ SH_SIMPLE
simple polygon
 
@ SH_NULL
empty shape (no shape...),
 
@ SH_POLY_SET_TRIANGLE
a single triangle belonging to a POLY_SET triangulation
 
@ SH_LINE_CHAIN
line chain (polyline)
 
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
 
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
 
static bool collideSingleShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
 
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
 
bool CollCaseReversed(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
 
static VECTOR2I pushoutForce(const SHAPE_CIRCLE &aA, const SEG &aB, int aClearance)
 
bool CollCase(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
 
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
 
VECTOR2I::extended_type ecoord
 
const SHAPE_LINE_CHAIN chain
 
VECTOR2< int32_t > VECTOR2I