1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 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_ARC_H
26 #define __SHAPE_ARC_H
27 
28 #include <geometry/shape.h>
29 #include <geometry/seg.h>
30 
31 class SHAPE_LINE_CHAIN;
32 
33 class SHAPE_ARC : public SHAPE
34 {
35 public:
SHAPE_ARC()36     SHAPE_ARC() :
37         SHAPE( SH_ARC ), m_centralAngle( 0.0 ), m_width( 0 ) {};
38 
39     SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
40                double aCenterAngle, int aWidth = 0 ) :
SHAPE(SH_ARC)41         SHAPE( SH_ARC ), m_p0( aArcStartPoint ), m_pc( aArcCenter ), m_centralAngle( aCenterAngle ),
42         m_width( aWidth )
43     {
44     }
45 
SHAPE_ARC(const SHAPE_ARC & aOther)46     SHAPE_ARC( const SHAPE_ARC& aOther )
47         : SHAPE( SH_ARC )
48     {
49         m_p0 = aOther.m_p0;
50         m_pc = aOther.m_pc;
51         m_centralAngle = aOther.m_centralAngle;
52         m_width = aOther.m_width;
53     }
54 
~SHAPE_ARC()55     ~SHAPE_ARC() {}
56 
Clone()57     SHAPE* Clone() const override
58     {
59         return new SHAPE_ARC( *this );
60     }
61 
GetP0()62     const VECTOR2I& GetP0() const { return m_p0; }
63     const VECTOR2I GetP1() const;
GetCenter()64     const VECTOR2I& GetCenter() const { return m_pc; }
65 
66     const BOX2I BBox( int aClearance = 0 ) const override;
67 
68     bool Collide( const SEG& aSeg, int aClearance = 0 ) const override;
69     bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const override;
70 
SetWidth(int aWidth)71     void SetWidth( int aWidth )
72     {
73         m_width = aWidth;
74     }
75 
GetWidth()76     int GetWidth() const
77     {
78         return m_width;
79     }
80 
IsSolid()81     bool IsSolid() const override
82     {
83         return true;
84     }
85 
Move(const VECTOR2I & aVector)86     void Move( const VECTOR2I& aVector ) override
87     {
88         m_p0 += aVector;
89         m_pc += aVector;
90     }
91 
92     int GetRadius() const;
93 
GetChord()94     SEG GetChord() const
95     {
96         return SEG( m_p0, GetP1() );
97     }
98 
99     double  GetCentralAngle() const;
100     double  GetStartAngle() const;
101     double  GetEndAngle() const;
102 
103 /*
104     bool ConstructFromCorners( VECTOR2I aP0, VECTOR2I aP1, double aCenterAngle );
105     bool ConstructFromCircle( VECTOR2I aP0, double aRadius );
106 
107     bool ConstructFromCenterAndAngles( VECTOR2I aCenter, double aRadius, double aStartAngle, double aCenterAngle );
108 
109     bool ConstructFromCornerAndAngles( VECTOR2I aP0,
110             double aStartAngle,
111             double aCenterAngle,
112             double aRadius );
113 */
114 
115     /**
116      * Constructs a SHAPE_LINE_CHAIN of segments from a given arc
117      * @param aAccuracy maximum divergence from true arc given in internal units
118      *   ** Note that the default of 500.0 here is given using ARC_DEF_HIGH_ACCURACY
119      *      for pcbnew units.  This is to allow common geometry collision functions
120      *      Other programs should call this using explicit accuracy values
121      *      TODO: unify KiCad internal units
122      *
123      * @return a SHAPE_LINE_CHAIN
124      */
125     const SHAPE_LINE_CHAIN ConvertToPolyline( double aAccuracy = 500.0 ) const;
126 
127 private:
128 
ccw(const VECTOR2I & aA,const VECTOR2I & aB,const VECTOR2I & aC)129     bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I& aC ) const
130     {
131         return (ecoord) ( aC.y - aA.y ) * ( aB.x - aA.x ) >
132                (ecoord) ( aB.y - aA.y ) * ( aC.x - aA.x );
133     }
134 
135 
136     VECTOR2I m_p0, m_pc;
137     double m_centralAngle;
138 
139     int m_width;
140 };
141 
142 #endif
143