KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ellipse.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, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <geometry/ellipse.h>
21
22#include <type_traits>
23
24
25template <typename NumericType>
26ELLIPSE<NumericType>::ELLIPSE( const VECTOR2<NumericType>& aCenter, NumericType aMajorRadius,
27 NumericType aMinorRadius, EDA_ANGLE aRotation, EDA_ANGLE aStartAngle,
28 EDA_ANGLE aEndAngle ) :
29 Center( aCenter ),
30 MajorRadius( aMajorRadius ),
31 MinorRadius( aMinorRadius ),
32 Rotation( aRotation ),
33 StartAngle( aStartAngle ),
34 EndAngle( aEndAngle )
35{
36}
37
38
39template <typename NumericType>
41 const VECTOR2<NumericType>& aMajor, double aRatio,
42 EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle ) :
43 Center( aCenter ),
44 StartAngle( aStartAngle ),
45 EndAngle( aEndAngle )
46{
47 MajorRadius = aMajor.EuclideanNorm();
48 MinorRadius = NumericType( MajorRadius * aRatio );
49 Rotation = EDA_ANGLE( std::atan2( aMajor.y, aMajor.x ), RADIANS_T );
50}
52
53template <typename NumericType>
55{
56 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
57 Center.x = 2 * aRef.x - Center.x;
58 else
59 Center.y = 2 * aRef.y - Center.y;
60
62
63 const EDA_ANGLE oldStart = StartAngle;
64 const EDA_ANGLE oldEnd = EndAngle;
65
66 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
67 {
68 // theta' = pi - theta -> [s, e] -> [pi - e, pi - s]
69 StartAngle = ANGLE_180 - oldEnd;
70 EndAngle = ANGLE_180 - oldStart;
71 }
72 else
73 {
74 // theta' = -theta -> [s, e] -> [-e, -s]
75 StartAngle = -oldEnd;
76 EndAngle = -oldStart;
77 }
78}
79
80
81template <typename NumericType>
84 EDA_ANGLE subtended = EndAngle - StartAngle;
85 return subtended.Normalize();
86}
87
88
89template <typename NumericType>
91{
92 double t = angle.AsRadians();
93 double ex = MajorRadius * std::cos( t );
94 double ey = MinorRadius * std::sin( t );
95
96 double cosR = Rotation.Cos();
97 double sinR = Rotation.Sin();
98 double rx = ex * cosR - ey * sinR;
99 double ry = ex * sinR + ey * cosR;
100
101 if constexpr( std::is_integral_v<NumericType> )
102 return Center + VECTOR2I( KiROUND( rx ), KiROUND( ry ) );
103 else
104 return Center + VECTOR2<NumericType>( rx, ry );
105}
106
107
108template <typename NumericType>
110{
111 const double a = std::max( 1.0, static_cast<double>( MajorRadius ) );
112 const double b = std::max( 1.0, static_cast<double>( MinorRadius ) );
113
114 const double dx = static_cast<double>( aPt.x ) - static_cast<double>( Center.x );
115 const double dy = static_cast<double>( aPt.y ) - static_cast<double>( Center.y );
116
117 const double cosRot = Rotation.Cos();
118 const double sinRot = Rotation.Sin();
119 const double lx = dx * cosRot + dy * sinRot;
120 const double ly = -dx * sinRot + dy * cosRot;
121
122 return EDA_ANGLE( std::atan2( ly / b, lx / a ), RADIANS_T );
123}
124
125
126template class ELLIPSE<double>;
127template class ELLIPSE<int>;
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
EDA_ANGLE Normalize()
Definition eda_angle.h:229
double AsRadians() const
Definition eda_angle.h:120
Plain ellipse / elliptical-arc data.
Definition ellipse.h:32
NumericType MinorRadius
Definition ellipse.h:103
VECTOR2< NumericType > GetPointAtAngle(EDA_ANGLE angle) const
Get the point on the ellipse at a given angle.
Definition ellipse.cpp:90
EDA_ANGLE Rotation
Definition ellipse.h:104
void Mirror(const VECTOR2< NumericType > &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the ellipse along a horizontal or vertical axis passing through aRef.
Definition ellipse.cpp:54
EDA_ANGLE StartAngle
Definition ellipse.h:105
ELLIPSE()
Definition ellipse.h:34
NumericType MajorRadius
Definition ellipse.h:102
EDA_ANGLE EndAngle
Definition ellipse.h:106
EDA_ANGLE GetAngleAtPoint(const VECTOR2< NumericType > &aPt) const
Get the parametric angle of a point on the ellipse.
Definition ellipse.cpp:109
VECTOR2< NumericType > Center
Definition ellipse.h:101
EDA_ANGLE GetSubtendedAngle() const
Get the subtended angle of the ellipse or elliptical arc at the center.
Definition ellipse.cpp:82
Define a general 2D-vector/point.
Definition vector2d.h:67
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:279
@ RADIANS_T
Definition eda_angle.h:32
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:415
FLIP_DIRECTION
Definition mirror.h:23
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Definition mirror.h:24
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683