3
* \brief Elliptical Arc - implementation of the svg elliptical arc path element
6
* MenTaLguY <mental@rydia.net>
7
* Marco Cecchetti <mrcekets at gmail.com>
9
* Copyright 2007-2008 authors
11
* This library is free software; you can redistribute it and/or
12
* modify it either under the terms of the GNU Lesser General Public
13
* License version 2.1 as published by the Free Software Foundation
14
* (the "LGPL") or, at your option, under the terms of the Mozilla
15
* Public License Version 1.1 (the "MPL"). If you do not alter this
16
* notice, a recipient may use your version of this file under either
17
* the MPL or the LGPL.
19
* You should have received a copy of the LGPL along with this library
20
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
* You should have received a copy of the MPL along with this library
23
* in the file COPYING-MPL-1.1
25
* The contents of this file are subject to the Mozilla Public License
26
* Version 1.1 (the "License"); you may not use this file except in
27
* compliance with the License. You may obtain a copy of the License at
28
* http://www.mozilla.org/MPL/
30
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
31
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
32
* the specific language governing rights and limitations.
38
#ifndef _2GEOM_ELLIPTICAL_ARC_H_
39
#define _2GEOM_ELLIPTICAL_ARC_H_
42
#include <2geom/curve.h>
43
#include <2geom/angle.h>
44
#include <2geom/utils.h>
45
#include <2geom/sbasis-curve.h> // for non-native methods
53
class EllipticalArc : public Curve
57
: m_initial_point(Point(0,0)), m_final_point(Point(0,0)),
58
m_rx(0), m_ry(0), m_rot_angle(0),
59
m_large_arc(true), m_sweep(true)
61
m_start_angle = m_end_angle = 0;
62
m_center = Point(0,0);
65
EllipticalArc( Point _initial_point, double _rx, double _ry,
66
double _rot_angle, bool _large_arc, bool _sweep,
69
: m_initial_point(_initial_point), m_final_point(_final_point),
70
m_rx(_rx), m_ry(_ry), m_rot_angle(_rot_angle),
71
m_large_arc(_large_arc), m_sweep(_sweep)
73
calculate_center_and_extreme_angles();
76
void set( Point _initial_point, double _rx, double _ry,
77
double _rot_angle, bool _large_arc, bool _sweep,
81
m_initial_point = _initial_point;
82
m_final_point = _final_point;
85
m_rot_angle = _rot_angle;
86
m_large_arc = _large_arc;
88
calculate_center_and_extreme_angles();
91
Curve* duplicate() const
93
return new EllipticalArc(*this);
96
double center(unsigned int i) const
106
Point initialPoint() const
108
return m_initial_point;
111
Point finalPoint() const
113
return m_final_point;
116
double start_angle() const
118
return m_start_angle;
121
double end_angle() const
126
double ray(unsigned int i) const
128
return (i == 0) ? m_rx : m_ry;
131
bool large_arc_flag() const
136
bool sweep_flag() const
141
double rotation_angle() const
146
void setInitial( const Point _point)
148
m_initial_point = _point;
149
calculate_center_and_extreme_angles();
152
void setFinal( const Point _point)
154
m_final_point = _point;
155
calculate_center_and_extreme_angles();
158
void setExtremes( const Point& _initial_point, const Point& _final_point )
160
m_initial_point = _initial_point;
161
m_final_point = _final_point;
162
calculate_center_and_extreme_angles();
165
bool isDegenerate() const
167
return ( are_near(ray(X), 0) || are_near(ray(Y), 0) );
171
virtual OptRect boundsFast() const
173
return boundsExact();
176
virtual OptRect boundsExact() const;
178
// TODO: native implementation of the following methods
179
virtual OptRect boundsLocal(OptInterval i, unsigned int deg) const
181
return SBasisCurve(toSBasis()).boundsLocal(i, deg);
184
std::vector<double> roots(double v, Dim2 d) const;
187
allNearestPoints( Point const& p, double from = 0, double to = 1 ) const;
189
double nearestPoint( Point const& p, double from = 0, double to = 1 ) const
191
if ( are_near(ray(X), ray(Y)) && are_near(center(), p) )
195
return allNearestPoints(p, from, to).front();
198
// TODO: native implementation of the following methods
199
int winding(Point p) const
201
return SBasisCurve(toSBasis()).winding(p);
204
int degreesOfFreedom() const { return 7;}
206
Curve *derivative() const;
208
// TODO: native implementation of the following methods
209
Curve *transformed(Matrix const &m) const
211
return SBasisCurve(toSBasis()).transformed(m);
214
std::vector<Point> pointAndDerivatives(Coord t, unsigned int n) const;
216
D2<SBasis> toSBasis() const;
218
bool containsAngle(Coord angle) const;
220
double valueAtAngle(Coord t, Dim2 d) const;
222
Point pointAtAngle(Coord t) const
224
double sin_rot_angle = std::sin(rotation_angle());
225
double cos_rot_angle = std::cos(rotation_angle());
226
Matrix m( ray(X) * cos_rot_angle, ray(X) * sin_rot_angle,
227
-ray(Y) * sin_rot_angle, ray(Y) * cos_rot_angle,
228
center(X), center(Y) );
229
Point p( std::cos(t), std::sin(t) );
233
double valueAt(Coord t, Dim2 d) const
235
Coord tt = map_to_02PI(t);
236
return valueAtAngle(tt, d);
239
Point pointAt(Coord t) const
241
Coord tt = map_to_02PI(t);
242
return pointAtAngle(tt);
245
std::pair<EllipticalArc, EllipticalArc>
246
subdivide(Coord t) const
248
EllipticalArc* arc1 = static_cast<EllipticalArc*>(portion(0, t));
249
EllipticalArc* arc2 = static_cast<EllipticalArc*>(portion(t, 1));
250
assert( arc1 != NULL && arc2 != NULL);
251
std::pair<EllipticalArc, EllipticalArc> arc_pair(*arc1, *arc2);
257
Curve* portion(double f, double t) const;
259
// the arc is the same but traversed in the opposite direction
260
Curve* reverse() const
262
EllipticalArc* rarc = new EllipticalArc( *this );
263
rarc->m_sweep = !m_sweep;
264
rarc->m_initial_point = m_final_point;
265
rarc->m_final_point = m_initial_point;
266
rarc->m_start_angle = m_end_angle;
267
rarc->m_end_angle = m_start_angle;
271
double sweep_angle() const
273
Coord d = end_angle() - start_angle();
274
if ( !sweep_flag() ) d = -d;
281
Coord map_to_02PI(Coord t) const;
282
Coord map_to_01(Coord angle) const;
283
void calculate_center_and_extreme_angles();
285
Point m_initial_point, m_final_point;
286
double m_rx, m_ry, m_rot_angle;
287
bool m_large_arc, m_sweep;
288
double m_start_angle, m_end_angle;
291
}; // end class EllipticalArc
294
} // end namespace Geom
296
#endif // _2GEOM_ELLIPTICAL_ARC_H_
304
c-file-style:"stroustrup"
305
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
310
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :