KiCad PCB EDA Suite
Loading...
Searching...
No Matches
roundrect.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) 2017 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include "geometry/roundrect.h"
27
30
31
32namespace
33{
34
35SHAPE_ARC MakeCornerArcCw90( const SHAPE_RECT& aRect, int aRadius, DIRECTION_45::Directions aDir )
36{
37 const VECTOR2I center = KIGEOM::GetPoint( aRect, aDir );
38 return KIGEOM::MakeArcCw90( center, aRadius, aDir );
39}
40
41
42SHAPE_ARC MakeSideArcCw180( const SHAPE_RECT& aRect, int aRadius, DIRECTION_45::Directions aDir )
43{
44 const VECTOR2I center = KIGEOM::GetPoint( aRect, aDir );
45 return KIGEOM::MakeArcCw180( center, aRadius, aDir );
46}
47
48} // namespace
49
50
51ROUNDRECT::ROUNDRECT( SHAPE_RECT aRect, int aRadius, bool aNormalizeOnCreate ) :
52 m_rect( std::move( aRect ) ),
53 m_radius( aRadius )
54{
55 if( aNormalizeOnCreate )
56 m_rect.Normalize();
57
58 // Ensure radius is compatible with rectangle size:
59 int min_radius = std::abs( m_rect.MinorDimension() )/2;
60
61 if( m_radius > min_radius )
62 m_radius = min_radius;
63
64 if( m_radius < 0 )
65 m_radius = 0;
66}
67
68
69ROUNDRECT ROUNDRECT::OutsetFrom( const SHAPE_RECT& aRect, int aOutset )
70{
71 return ROUNDRECT( aRect.GetInflated( aOutset ), aOutset );
72}
73
74
76{
77 return ROUNDRECT( m_rect.GetInflated( aOutset ), m_radius + aOutset );
78}
79
80
82{
83 const int idx = aBuffer.NewOutline();
84 SHAPE_LINE_CHAIN& outline = aBuffer.Outline( idx );
85
86 const int w = m_rect.GetWidth();
87 const int h = m_rect.GetHeight();
88 const int x_edge = m_rect.GetWidth() - 2 * m_radius;
89 const int y_edge = m_rect.GetHeight() - 2 * m_radius;
90
91 // This is a class invariant
92 wxASSERT( x_edge >= 0 );
93 wxASSERT( y_edge >= 0 );
94 wxASSERT( m_radius >= 0 );
95
96 const VECTOR2I& m_p0 = m_rect.GetPosition();
97
98 if( m_radius == 0 )
99 {
100 // It's just a rectangle
101 outline.Append( m_p0 );
102 outline.Append( m_p0 + VECTOR2I( w, 0 ) );
103 outline.Append( m_p0 + VECTOR2I( w, h ) );
104 outline.Append( m_p0 + VECTOR2I( 0, h ) );
105 }
106 else if( x_edge == 0 && y_edge == 0 )
107 {
108 // It's a circle
109 outline.Append( SHAPE_ARC( m_p0 + VECTOR2I( m_radius, m_radius ),
110 m_p0 + VECTOR2I( -m_radius, 0 ), ANGLE_360 ) );
111 }
112 else
113 {
114 const SHAPE_RECT inner_rect{ m_p0 + VECTOR2I( m_radius, m_radius ), x_edge, y_edge };
115
116 if( x_edge > 0 )
117 {
118 // Either a normal roundrect or an oval with x_edge > 0
119
120 // Start to the right of the top left radius
121 outline.Append( m_p0 + VECTOR2I( m_radius, 0 ) );
122
123 // Top side
124 outline.Append( m_p0 + VECTOR2I( m_radius + x_edge, 0 ) );
125
126 if( y_edge > 0 )
127 {
128 outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NE ) );
129 outline.Append( m_p0 + VECTOR2I( w, m_radius + y_edge ) );
130 outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SE ) );
131 }
132 else
133 {
134 outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::E ) );
135 }
136
137 // Bottom side
138 outline.Append( m_p0 + VECTOR2I( m_radius, h ) );
139
140 if( y_edge > 0 )
141 {
142 outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SW ) );
143 outline.Append( m_p0 + VECTOR2I( 0, m_radius ) );
144 outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NW ) );
145 }
146 else
147 {
148 outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::W ) );
149 }
150 }
151 else
152 {
153 // x_edge is 0 but y_edge is not, so it's an oval the other way up
154 outline.Append( m_p0 + VECTOR2I( 0, m_radius ) );
155 outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::N ) );
156 outline.Append( m_p0 + VECTOR2I( w, m_radius + y_edge ) );
157 outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::S ) );
158 }
159 }
160
161 outline.SetClosed( true );
162}
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition direction45.h:49
int m_radius
Definition roundrect.h:90
SHAPE_RECT m_rect
Definition roundrect.h:89
static ROUNDRECT OutsetFrom(const SHAPE_RECT &aRect, int aOutset)
Definition roundrect.cpp:69
ROUNDRECT GetInflated(int aOutset) const
Get the roundrect with the size increased by aOutset in all directions.
Definition roundrect.cpp:75
void TransformToPolygon(SHAPE_POLY_SET &aBuffer) const
Get the polygonal representation of the roundrect.
Definition roundrect.cpp:81
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
SHAPE_RECT GetInflated(int aOffset) const
Return a rectangle that is larger by aOffset in all directions, but still centered on the original re...
Definition shape_rect.h:120
static constexpr EDA_ANGLE ANGLE_360
Definition eda_angle.h:417
VECTOR2I GetPoint(const SHAPE_RECT &aRect, DIRECTION_45::Directions aDir, int aOutset=0)
Get the point on a rectangle that corresponds to a given direction.
SHAPE_ARC MakeArcCw180(const VECTOR2I &aCenter, int aRadius, DIRECTION_45::Directions aDir)
Get a SHAPE_ARC representing a 180-degree arc in the clockwise direction with the midpoint in the giv...
SHAPE_ARC MakeArcCw90(const VECTOR2I &aCenter, int aRadius, DIRECTION_45::Directions aDir)
Get a SHAPE_ARC representing a 90-degree arc in the clockwise direction with the midpoint in the give...
STL namespace.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
Utility functions for working with shapes.
VECTOR2I center
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695