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 The 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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <sstream>
22#include <string>
23
25
26const std::string SHAPE_COMPOUND::Format( bool aCplusPlus ) const
27{
28 std::stringstream ss;
29
30 ss << "compound( ";
31
32 for( auto shape : m_shapes )
33 ss << shape->Format() << " ";
34
35 return ss.str();
36}
37
38SHAPE_COMPOUND::SHAPE_COMPOUND( const std::vector<SHAPE*>& aShapes ) :
40 m_dirty( true ),
41 m_shapes( aShapes )
42{
43
44}
45
46
49{
50 for ( const SHAPE* shape : aOther.Shapes() )
51 m_shapes.push_back( shape->Clone() );
52
53 m_dirty = true;
54}
55
56
57
58
60{
61 for( auto shape : m_shapes )
62 delete shape;
63}
64
65
67{
68 return new SHAPE_COMPOUND( *this );
69}
70
71
72const BOX2I SHAPE_COMPOUND::BBox( int aClearance ) const
73{
74 BOX2I bb;
75
76 if ( m_shapes.size() < 1 )
77 return bb;
78
79 bb = m_shapes[0]->BBox();
80
81 for( size_t i = 1; i < m_shapes.size(); i++ )
82 bb.Merge( m_shapes[i]->BBox() );
83
84 return bb;
85}
86
87void SHAPE_COMPOUND::Move ( const VECTOR2I& aVector )
88{
89 for( auto& item : m_shapes )
90 item->Move( aVector );
91}
92
93
94int SHAPE_COMPOUND::Distance( const SEG& aSeg ) const
95{
96 assert(false);
97 return 0; // Make compiler happy
98}
99
100
101void SHAPE_COMPOUND::Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter )
102{
103 for( auto& item : m_shapes )
104 item->Rotate( aAngle, aCenter );
105}
106
107
109{
110 return true;
111}
112
113
114bool SHAPE_COMPOUND::Collide( const SEG& aSeg, int aClearance, int* aActual,
115 VECTOR2I* aLocation ) const
116{
117 int closest_dist = std::numeric_limits<int>::max();
118 VECTOR2I nearest;
119
120 for( SHAPE* item : m_shapes )
121 {
122 int actual = 0;
123 VECTOR2I pn;
124
125 if( item->Collide( aSeg, aClearance,
126 aActual || aLocation ? &actual : nullptr,
127 aLocation ? &pn : nullptr ) )
128 {
129 if( actual < closest_dist )
130 {
131 nearest = pn;
132 closest_dist = actual;
133
134 if( !aLocation && !aActual )
135 break;
136 }
137 else if( aLocation && actual == closest_dist )
138 {
139 if( ( pn - aSeg.A ).SquaredEuclideanNorm()
140 < ( nearest - aSeg.A ).SquaredEuclideanNorm() )
141 {
142 nearest = pn;
143 }
144 }
145 }
146 }
147
148 if( closest_dist == 0 || closest_dist < aClearance )
149 {
150 if( aLocation )
151 *aLocation = nearest;
152
153 if( aActual )
154 *aActual = closest_dist;
155
156 return true;
157 }
158
159 return false;
160}
161
162
164 ERROR_LOC aErrorLoc ) const
165{
166 for( SHAPE* item : m_shapes )
167 item->TransformToPolygon( aBuffer, aError, aErrorLoc );
168}
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:654
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition box2.h:134
Definition seg.h:38
VECTOR2I A
Definition seg.h:45
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.
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition shape.h:134
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
Definition shape.h:49
int actual
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683