KiCad PCB EDA Suite
shape_segment.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #ifndef __SHAPE_SEGMENT_H
26 #define __SHAPE_SEGMENT_H
27 
28 #include <geometry/seg.h>
29 #include <geometry/shape.h>
30 #include <math/box2.h>
31 #include <math/vector2d.h>
32 
33 #include <algorithm>
34 
35 class SHAPE_SEGMENT : public SHAPE
36 {
37 public:
39  SHAPE( SH_SEGMENT ),
40  m_width( 0 )
41  {};
42 
43  SHAPE_SEGMENT( const VECTOR2I& aA, const VECTOR2I& aB, int aWidth = 0 ) :
44  SHAPE( SH_SEGMENT ),
45  m_seg( aA, aB ),
46  m_width( aWidth )
47  {};
48 
49  SHAPE_SEGMENT( const SEG& aSeg, int aWidth = 0 ) :
50  SHAPE( SH_SEGMENT ),
51  m_seg( aSeg ),
52  m_width( aWidth )
53  {};
54 
56 
57  SHAPE* Clone() const override
58  {
59  return new SHAPE_SEGMENT( m_seg, m_width );
60  }
61 
62  const BOX2I BBox( int aClearance = 0 ) const override
63  {
64  return BOX2I( m_seg.A, m_seg.B - m_seg.A ).Inflate( aClearance + ( m_width + 1 ) / 2 );
65  }
66 
67  bool Collide( const SHAPE* aShape, int aClearance, VECTOR2I* aMTV ) const override
68  {
69  return SHAPE::Collide( aShape, aClearance, aMTV );
70  }
71 
72  bool Collide( const SHAPE* aShape, int aClearance = 0, int* aActual = nullptr,
73  VECTOR2I* aLocation = nullptr ) const override
74  {
75  return SHAPE::Collide( aShape, aClearance, aActual, aLocation );
76  }
77 
78  bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
79  VECTOR2I* aLocation = nullptr ) const override
80  {
81  int min_dist = ( m_width + 1 ) / 2 + aClearance;
82  ecoord dist_sq = m_seg.SquaredDistance( aSeg );
83 
84  if( dist_sq == 0 || dist_sq < SEG::Square( min_dist ) )
85  {
86  if( aLocation )
87  *aLocation = m_seg.NearestPoint( aSeg );
88 
89  if( aActual )
90  *aActual = std::max( 0, (int) sqrt( dist_sq ) - ( m_width + 1 ) / 2 );
91 
92  return true;
93  }
94 
95  return false;
96  }
97 
98  bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
99  VECTOR2I* aLocation = nullptr ) const override
100  {
101  int min_dist = ( m_width + 1 ) / 2 + aClearance;
102  ecoord dist_sq = m_seg.SquaredDistance( aP );
103 
104  if( dist_sq == 0 || dist_sq < SEG::Square( min_dist ) )
105  {
106  if( aLocation )
107  *aLocation = m_seg.NearestPoint( aP );
108 
109  if( aActual )
110  *aActual = std::max( 0, (int) sqrt( dist_sq ) - ( m_width + 1 ) / 2 );
111 
112  return true;
113  }
114 
115  return false;
116  }
117 
118  void SetSeg( const SEG& aSeg )
119  {
120  m_seg = aSeg;
121  }
122 
123  const SEG& GetSeg() const
124  {
125  return m_seg;
126  }
127 
128  void SetWidth( int aWidth )
129  {
130  m_width = aWidth;
131  }
132 
133  int GetWidth() const
134  {
135  return m_width;
136  }
137 
138  bool IsSolid() const override
139  {
140  return true;
141  }
142 
143  void Rotate( double aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override
144  {
145  m_seg.A -= aCenter;
146  m_seg.B -= aCenter;
147 
148  m_seg.A = m_seg.A.Rotate( aAngle );
149  m_seg.B = m_seg.B.Rotate( aAngle );
150 
151  m_seg.A += aCenter;
152  m_seg.B += aCenter;
153  }
154 
155  void Move( const VECTOR2I& aVector ) override
156  {
157  m_seg.A += aVector;
158  m_seg.B += aVector;
159  }
160 
161  virtual const std::string Format( ) const override;
162 
163 private:
165  int m_width;
166 };
167 
168 #endif
BOX2< VECTOR2I > BOX2I
Definition: box2.h:522
void SetSeg(const SEG &aSeg)
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Definition: shape_segment.h:72
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Definition: shape_segment.h:62
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:38
static SEG::ecoord Square(int a)
Definition: seg.h:123
virtual const std::string Format() const override
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,...
Definition: shape.h:165
const SEG & GetSeg() const
void Move(const VECTOR2I &aVector) override
bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape_segment.h:98
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.h:422
An abstract shape on 2D plane.
Definition: shape.h:116
SHAPE_SEGMENT(const SEG &aSeg, int aWidth=0)
Definition: shape_segment.h:49
Definition: seg.h:41
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,...
Definition: shape_segment.h:78
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371
SHAPE * Clone() const override
Return a dynamically allocated copy of the shape.
Definition: shape_segment.h:57
VECTOR2I::extended_type ecoord
Definition: shape.h:236
VECTOR2I A
Definition: seg.h:49
int GetWidth() const
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,...
Definition: shape_segment.h:67
SHAPE_SEGMENT(const VECTOR2I &aA, const VECTOR2I &aB, int aWidth=0)
Definition: shape_segment.h:43
bool IsSolid() const override
void SetWidth(int aWidth)
line segment
Definition: shape.h:44
VECTOR2I B
Definition: seg.h:50