geometry: IsSolid() and Move() methods, segment overlap detection, some improvements in SHAPE_LINE_CHAIN class.

This commit is contained in:
Tomasz Wlostowski 2014-11-14 19:18:31 +01:00 committed by Maciej Suminski
parent 4e280f065f
commit 33f3aca611
7 changed files with 90 additions and 13 deletions

View File

@ -29,16 +29,15 @@ using boost::optional;
bool SHAPE_LINE_CHAIN::Collide( const VECTOR2I& aP, int aClearance ) const
{
assert( false );
return false;
// fixme: ugly!
SEG s(aP, aP);
return this->Collide(s, aClearance);
}
bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const
{
assert( false );
return false;
}

View File

@ -215,14 +215,34 @@ public:
*/
bool Collinear( const SEG& aSeg ) const
{
ecoord qa1 = A.y - B.y;
ecoord qb1 = B.x - A.x;
ecoord qc1 = -qa1 * A.x - qb1 * A.y;
ecoord qa2 = aSeg.A.y - aSeg.B.y;
ecoord qb2 = aSeg.B.x - aSeg.A.x;
ecoord qc2 = -qa2 * aSeg.A.x - qb2 * aSeg.A.y;
ecoord qa = A.y - B.y;
ecoord qb = B.x - A.x;
ecoord qc = -qa * A.x - qb * A.y;
return ( qa1 == qa2 ) && ( qb1 == qb2 ) && ( qc1 == qc2 );
ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
return ( d1 <= 1 && d2 <= 1 );
}
bool Overlaps ( const SEG& aSeg ) const
{
if( aSeg.A == aSeg.B ) // single point corner case
{
if(A == aSeg.A || B == aSeg.A)
return false;
return Contains(aSeg.A);
}
if( !Collinear (aSeg ))
return false;
if ( Contains (aSeg.A) || Contains(aSeg.B) )
return true;
if ( aSeg.Contains (A) || aSeg.Contains(B) )
return true;
return false;
}
/**

View File

@ -40,7 +40,10 @@ enum SHAPE_TYPE
SH_RECT = 0, ///> axis-aligned rectangle
SH_SEGMENT, ///> line segment
SH_LINE_CHAIN, ///> line chain (polyline)
SH_CIRCLE ///> circle
SH_CIRCLE, ///> circle
SH_CONVEX, ///> convex polygon
SH_POLYGON, ///> any polygon (with holes, etc.)
SH_COMPOUND ///> compound shape, consisting of multiple simple shapes
};
/**
@ -146,7 +149,11 @@ public:
return BBox( 0 ).Centre(); // if nothing better is available....
}
private:
virtual void Move ( const VECTOR2I& aVector ) = 0;
virtual bool IsSolid() const = 0;
protected:
///> type of our shape
SHAPE_TYPE m_type;
};

View File

@ -86,6 +86,15 @@ public:
return m_center;
}
void Move ( const VECTOR2I& aVector )
{
m_center += aVector;
}
bool IsSolid() const
{
return true;
}
private:
int m_radius;
VECTOR2I m_center;

View File

@ -103,6 +103,17 @@ public:
m_points[2] = aC;
}
SHAPE_LINE_CHAIN( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC, const VECTOR2I& aD ) :
SHAPE( SH_LINE_CHAIN ), m_closed( false )
{
m_points.resize( 4 );
m_points[0] = aA;
m_points[1] = aB;
m_points[2] = aC;
m_points[3] = aD;
}
SHAPE_LINE_CHAIN(const VECTOR2I* aV, int aCount ) :
SHAPE( SH_LINE_CHAIN ),
m_closed( false )
@ -553,6 +564,16 @@ public:
bool CompareGeometry( const SHAPE_LINE_CHAIN & aOther ) const;
void Move ( const VECTOR2I& aVector )
{
for(std::vector<VECTOR2I>::iterator i = m_points.begin(); i != m_points.end(); ++i)
(*i) += aVector;
}
bool IsSolid() const
{
return false;
}
private:
/// array of vertices
std::vector<VECTOR2I> m_points;

View File

@ -159,6 +159,16 @@ public:
return m_h;
}
void Move ( const VECTOR2I& aVector )
{
m_p0 += aVector;
}
bool IsSolid() const
{
return true;
}
private:
///> Top-left corner
VECTOR2I m_p0;

View File

@ -82,6 +82,17 @@ public:
return m_width;
}
bool IsSolid() const
{
return true;
}
void Move ( const VECTOR2I& aVector )
{
m_seg.A += aVector;
m_seg.B += aVector;
}
private:
SEG m_seg;
int m_width;