KiCad PCB EDA Suite
shape_rect.cpp
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) 2015 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 
26 #include <geometry/shape_rect.h>
27 
28 bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual,
29  VECTOR2I* aLocation ) const
30 {
31  if( BBox( 0 ).Contains( aSeg.A ) )
32  {
33  if( aLocation )
34  *aLocation = aSeg.A;
35 
36  if( aActual )
37  *aActual = 0;
38 
39  return true;
40  }
41 
42  if( BBox( 0 ).Contains( aSeg.B ) )
43  {
44  if( aLocation )
45  *aLocation = aSeg.B;
46 
47  if( aActual )
48  *aActual = 0;
49 
50  return true;
51  }
52 
53  VECTOR2I corners[] = { VECTOR2I( m_p0.x, m_p0.y ),
54  VECTOR2I( m_p0.x, m_p0.y + m_h ),
55  VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),
56  VECTOR2I( m_p0.x + m_w, m_p0.y ),
57  VECTOR2I( m_p0.x, m_p0.y ) };
58 
59  SEG::ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
60  VECTOR2I nearest;
61 
62  for( int i = 0; i < 4; i++ )
63  {
64  SEG side( corners[i], corners[ i + 1] );
65  SEG::ecoord dist_sq = side.SquaredDistance( aSeg );
66 
67  if( dist_sq < closest_dist_sq )
68  {
69  if ( aLocation )
70  {
71  nearest = side.NearestPoint( aSeg );
72  }
73 
74  closest_dist_sq = dist_sq;
75  }
76  }
77 
78  if( closest_dist_sq == 0 || closest_dist_sq < SEG::Square( aClearance ) )
79  {
80  if( aActual )
81  *aActual = sqrt( closest_dist_sq );
82 
83  if( aLocation )
84  *aLocation = nearest;
85 
86  return true;
87  }
88 
89  return false;
90 }
91 
92 const std::string SHAPE_RECT::Format( ) const
93 {
94  std::stringstream ss;
95 
96  ss << "SHAPE_RECT( ";
97  ss << m_p0.x;
98  ss << ", ";
99  ss << m_p0.y;
100  ss << ", ";
101  ss << m_w;
102  ss << ", ";
103  ss << m_h;
104  ss << ");";
105 
106  return ss.str();
107 }
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_rect.h:98
VECTOR2I::extended_type ecoord
Definition: seg.h:44
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:38
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
static SEG::ecoord Square(int a)
Definition: seg.h:123
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
VECTOR2I m_p0
Top-left corner.
Definition: shape_rect.h:185
virtual const std::string Format() const override
Definition: shape_rect.cpp:92
int m_h
Height.
Definition: shape_rect.h:187
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.h:422
int m_w
Width.
Definition: shape_rect.h:186
Definition: seg.h:41
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Definition: shape_rect.h:81
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50