summaryrefslogtreecommitdiffstats
path: root/src/sp-ellipse.cpp
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-10-10 20:16:44 +0000
committerMarkus Engel <markus.engel@tum.de>2013-10-10 20:16:44 +0000
commit6feaa0839ddeb6208690c4c727b9f5681243c6d6 (patch)
tree6e9326c02f4355617e7f9961a398a3d2261adae8 /src/sp-ellipse.cpp
parentextensions. svgcalendar. patch by David Turner for Bug 1237167 (diff)
downloadinkscape-6feaa0839ddeb6208690c4c727b9f5681243c6d6.tar.gz
inkscape-6feaa0839ddeb6208690c4c727b9f5681243c6d6.zip
Fix some more issues with ellipses.
Fixed bugs: - https://launchpad.net/bugs/1237734 - https://launchpad.net/bugs/1235504 (bzr r12677)
Diffstat (limited to 'src/sp-ellipse.cpp')
-rw-r--r--src/sp-ellipse.cpp66
1 files changed, 35 insertions, 31 deletions
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index fa74508e3..8a0a8f233 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -75,6 +75,7 @@ SPGenericEllipse::SPGenericEllipse()
: SPShape()
, start(0)
, end(SP_2PI)
+ , type(SP_GENERIC_ELLIPSE_UNDEFINED)
, _closed(true)
{
}
@@ -416,6 +417,7 @@ void SPGenericEllipse::set_shape()
SPCurve *curve = NULL;
// For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations.
+ Geom::Circle circle(0, 0, 1);
if (this->_isSlice()) {
Geom::Point center(0, 0);
@@ -423,8 +425,7 @@ void SPGenericEllipse::set_shape()
Geom::Point end_point = Geom::Point::polar(end);
Geom::Point middle_point = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor();
- Geom::Ellipse ellipse(0, 0, 1, 1, 0);
- Geom::EllipticalArc *arc = ellipse.arc(start_point, middle_point, end_point);
+ Geom::EllipticalArc *arc = circle.arc(start_point, middle_point, end_point);
Geom::Path path(start_point);
path.append(*arc);
@@ -446,13 +447,33 @@ void SPGenericEllipse::set_shape()
curve = new SPCurve(pb.peek());
} else {
// Full ellipse
- Geom::Circle circle(0, 0, 1);
- Geom::PathVector path;
+ // This code converts the circle to four elliptical arcs explicitly.
+ // Circle::getPath currently creates cubic bezier curves, these are not suitable here
+ // as a circle should have four mid markers at 0, 90, 180, 270 degrees.
+ Geom::Path path;
+ Geom::EllipticalArc* arc;
- circle.getPath(path);
+ arc = circle.arc(Geom::Point::polar(0), Geom::Point::polar(M_PI / 4.0), Geom::Point::polar(M_PI / 2.0));
+ path.append(*arc);
+ delete arc;
+
+ arc = circle.arc(Geom::Point::polar(M_PI / 2.0), Geom::Point::polar(3.0 * M_PI / 4.0), Geom::Point::polar(M_PI));
+ path.append(*arc);
+ delete arc;
+
+ arc = circle.arc(Geom::Point::polar(M_PI), Geom::Point::polar(5.0 * M_PI / 4.0), Geom::Point::polar(3.0 * M_PI / 2.0));
+ path.append(*arc);
+ delete arc;
+
+ arc = circle.arc(Geom::Point::polar(3.0 * M_PI / 2.0), Geom::Point::polar(7.0 * M_PI / 4.0), Geom::Point::polar(2.0 * M_PI));
+ path.append(*arc);
+ delete arc;
- curve = new SPCurve(path);
- curve->closepath();
+ Geom::PathBuilder pb;
+ pb.append(path);
+ pb.closePath();
+
+ curve = new SPCurve(pb.peek());
}
// gchar *str = sp_svg_write_path(curve->get_pathvector());
@@ -639,36 +660,19 @@ Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const
*/
bool SPGenericEllipse::set_elliptical_path_attribute(Inkscape::XML::Node *repr)
{
- Inkscape::SVG::PathString str;
-
- Geom::Point p1 = this->getPointAtAngle(this->start);
- Geom::Point p2 = this->getPointAtAngle(this->end);
- double rx = this->rx.computed;
- double ry = this->ry.computed;
-
- str.moveTo(p1);
+ // Make sure our pathvector is up to date.
+ this->set_shape();
- double dt = fmod(this->end - this->start, SP_2PI);
+ if (this->getCurve() != NULL) {
+ gchar* d = sp_svg_write_path(this->getCurve()->get_pathvector());
- if (fabs(dt) < 1e-6) {
- Geom::Point ph = getPointAtAngle((this->start + this->end) / 2.0);
+ repr->setAttribute("d", d);
- str.arcTo(rx, ry, 0, true, true, ph)
- .arcTo(rx, ry, 0, true, true, p2)
- .closePath();
+ g_free(d);
} else {
- bool fa = (fabs(dt) > M_PI);
- bool fs = (dt > 0);
-
- str.arcTo(rx, ry, 0, fa, fs, p2);
-
- if (this->_closed) {
- Geom::Point center = Geom::Point(this->cx.computed, this->cy.computed);
- str.lineTo(center).closePath();
- }
+ repr->setAttribute("d", NULL);
}
- repr->setAttribute("d", str.c_str());
return true;
}