From 33f3aca611cf7142c79c2589274e1a5757853cc4 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Fri, 14 Nov 2014 19:18:31 +0100 Subject: [PATCH] geometry: IsSolid() and Move() methods, segment overlap detection, some improvements in SHAPE_LINE_CHAIN class. --- common/geometry/shape_line_chain.cpp | 7 +++--- include/geometry/seg.h | 34 ++++++++++++++++++++++------ include/geometry/shape.h | 11 +++++++-- include/geometry/shape_circle.h | 9 ++++++++ include/geometry/shape_line_chain.h | 21 +++++++++++++++++ include/geometry/shape_rect.h | 10 ++++++++ include/geometry/shape_segment.h | 11 +++++++++ 7 files changed, 90 insertions(+), 13 deletions(-) diff --git a/common/geometry/shape_line_chain.cpp b/common/geometry/shape_line_chain.cpp index d5b974bb1e..d0437b41e5 100644 --- a/common/geometry/shape_line_chain.cpp +++ b/common/geometry/shape_line_chain.cpp @@ -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; } diff --git a/include/geometry/seg.h b/include/geometry/seg.h index af8161bb80..9c87ff478e 100644 --- a/include/geometry/seg.h +++ b/include/geometry/seg.h @@ -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; } /** diff --git a/include/geometry/shape.h b/include/geometry/shape.h index 7ba77b671b..25f242b054 100644 --- a/include/geometry/shape.h +++ b/include/geometry/shape.h @@ -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; }; diff --git a/include/geometry/shape_circle.h b/include/geometry/shape_circle.h index e4b668b68c..2408c72ba8 100644 --- a/include/geometry/shape_circle.h +++ b/include/geometry/shape_circle.h @@ -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; diff --git a/include/geometry/shape_line_chain.h b/include/geometry/shape_line_chain.h index 8c9c549d98..13ff6cd7c6 100644 --- a/include/geometry/shape_line_chain.h +++ b/include/geometry/shape_line_chain.h @@ -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::iterator i = m_points.begin(); i != m_points.end(); ++i) + (*i) += aVector; + } + + bool IsSolid() const + { + return false; + } private: /// array of vertices std::vector m_points; diff --git a/include/geometry/shape_rect.h b/include/geometry/shape_rect.h index bc3ba44d17..7b16df89e8 100644 --- a/include/geometry/shape_rect.h +++ b/include/geometry/shape_rect.h @@ -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; diff --git a/include/geometry/shape_segment.h b/include/geometry/shape_segment.h index 5f18760bd7..203c8485a2 100644 --- a/include/geometry/shape_segment.h +++ b/include/geometry/shape_segment.h @@ -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;