KiCad PCB EDA Suite
Loading...
Searching...
No Matches
shape_compound.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) 2020-2023 KiCad Developers
5 * @author Tomasz Wlostowski <[email protected]>
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#include <sstream>
26#include <string>
27
29
30const std::string SHAPE_COMPOUND::Format( bool aCplusPlus ) const
31{
32 std::stringstream ss;
33
34 ss << "compound( ";
35
36 for( auto shape : m_shapes )
37 ss << shape->Format() << " ";
38
39 return ss.str();
40}
41
42SHAPE_COMPOUND::SHAPE_COMPOUND( const std::vector<SHAPE*>& aShapes ) :
44 m_dirty( true ),
45 m_shapes( aShapes )
46{
47
48}
49
50
53{
54 for ( const SHAPE* shape : aOther.Shapes() )
55 m_shapes.push_back( shape->Clone() );
56
57 m_dirty = true;
58}
59
60
61
62
64{
65 for( auto shape : m_shapes )
66 delete shape;
67}
68
69
71{
72 return new SHAPE_COMPOUND( *this );
73}
74
75
76const BOX2I SHAPE_COMPOUND::BBox( int aClearance ) const
77{
78 BOX2I bb;
79
80 if ( m_shapes.size() < 1 )
81 return bb;
82
83 bb = m_shapes[0]->BBox();
84
85 for( size_t i = 1; i < m_shapes.size(); i++ )
86 bb.Merge( m_shapes[i]->BBox() );
87
88 return bb;
89}
90
91void SHAPE_COMPOUND::Move ( const VECTOR2I& aVector )
92{
93 for( auto& item : m_shapes )
94 item->Move( aVector );
95}
96
97
98int SHAPE_COMPOUND::Distance( const SEG& aSeg ) const
99{
100 assert(false);
101 return 0; // Make compiler happy
102}
103
104
105void SHAPE_COMPOUND::Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter )
106{
107 assert( false );
108}
109
110
112{
113 return true;
114}
115
116
117bool SHAPE_COMPOUND::Collide( const SEG& aSeg, int aClearance, int* aActual,
118 VECTOR2I* aLocation ) const
119{
120 int closest_dist = std::numeric_limits<int>::max();
121 VECTOR2I nearest;
122
123 for( SHAPE* item : m_shapes )
124 {
125 int actual = 0;
126 VECTOR2I pn;
127
128 if( item->Collide( aSeg, aClearance,
129 aActual || aLocation ? &actual : nullptr,
130 aLocation ? &pn : nullptr ) )
131 {
132 if( actual < closest_dist )
133 {
134 nearest = pn;
135 closest_dist = actual;
136
137 if( !aLocation && !aActual )
138 break;
139 }
140 else if( aLocation && actual == closest_dist )
141 {
142 if( ( pn - aSeg.A ).SquaredEuclideanNorm()
143 < ( nearest - aSeg.A ).SquaredEuclideanNorm() )
144 {
145 nearest = pn;
146 }
147 }
148 }
149 }
150
151 if( closest_dist == 0 || closest_dist < aClearance )
152 {
153 if( aLocation )
154 *aLocation = nearest;
155
156 if( aActual )
157 *aActual = closest_dist;
158
159 return true;
160 }
161
162 return false;
163}
164
165
167 ERROR_LOC aErrorLoc ) const
168{
169 for( SHAPE* item : m_shapes )
170 item->TransformToPolygon( aBuffer, aError, aErrorLoc );
171}
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
bool IsSolid() const override
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
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 std::vector< SHAPE * > & Shapes() const
void TransformToPolygon(SHAPE_POLY_SET &aBuffer, int aError, ERROR_LOC aErrorLoc) const override
Fills a SHAPE_POLY_SET with a polygon representation of this shape.
std::vector< SHAPE * > m_shapes
const std::string Format(bool aCplusPlus=true) const override
SHAPE_COMPOUND * Clone() const override
Return a dynamically allocated copy of the shape.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
int Distance(const SEG &aSeg) const
void Move(const VECTOR2I &aVector) override
Represent a set of closed polygons.
An abstract shape on 2D plane.
Definition: shape.h:126
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
Definition: shape.h:53