diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2013-09-26 20:53:21 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2013-09-26 20:53:21 +0000 |
| commit | 10388486debb4c9d6482a2c754edebc0ceff3760 (patch) | |
| tree | b0939271566fa26cbf3bc100ca3c7fea624f4354 /src/sp-ellipse.cpp | |
| parent | Compiling problem solved thaks to ~suv (diff) | |
| parent | cppcheck (diff) | |
| download | inkscape-10388486debb4c9d6482a2c754edebc0ceff3760.tar.gz inkscape-10388486debb4c9d6482a2c754edebc0ceff3760.zip | |
update to trunk
(bzr r11950.1.150)
Diffstat (limited to 'src/sp-ellipse.cpp')
| -rw-r--r-- | src/sp-ellipse.cpp | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 2d73ff35f..fc78b9777 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -26,6 +26,7 @@ #include <glibmm/i18n.h> #include <2geom/transforms.h> #include <2geom/pathvector.h> +#include <2geom/svg-path.h> #include "document.h" #include "sp-ellipse.h" #include "preferences.h" @@ -141,6 +142,8 @@ void SPGenericEllipse::update_patheffect(bool write) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } +#include <2geom/ellipse.h> + /* fixme: Think (Lauris) */ /* Can't we use arcto in this method? */ void SPGenericEllipse::set_shape() { @@ -158,12 +161,6 @@ void SPGenericEllipse::set_shape() { return; } - double rx; - double ry; - double s; - double len; - gint slice = FALSE; - if ((this->rx.computed < 1e-18) || (this->ry.computed < 1e-18)) { return; } @@ -174,58 +171,65 @@ void SPGenericEllipse::set_shape() { sp_genericellipse_normalize(this); - rx = this->rx.computed; - ry = this->ry.computed; - // figure out if we have a slice, guarding against rounding errors - len = fmod(this->end - this->start, SP_2PI); + double len = fmod(this->end - this->start, SP_2PI); if (len < 0.0) { len += SP_2PI; } + bool slice = false; + if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) { - slice = FALSE; + slice = false; this->end = this->start + SP_2PI; } else { - slice = TRUE; + slice = true; } - SPCurve * curve = new SPCurve(); - curve->moveto(cos(this->start), sin(this->start)); + SPCurve *curve = NULL; + + // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. + + if (slice) { + Geom::Point startPoint(cos(start), sin(start)); + Geom::Point endPoint(cos(end), sin(end)); + Geom::Point middlePoint = make_angle_bisector_ray(Geom::Ray(Geom::Point(), start), Geom::Ray(Geom::Point(), end)).versor(); - for (s = this->start; s < this->end; s += M_PI_2) { - double e = s + M_PI_2; + Geom::Ellipse ellipse(0, 0, 1, 1, 0); + Geom::EllipticalArc *arc = ellipse.arc(startPoint, middlePoint, endPoint); - if (e > this->end) { - e = this->end; + Geom::Path path(startPoint); + path.append(*arc); + + delete arc; + + Geom::PathBuilder pb; + pb.append(path); + + if (this->closed) { + // "pizza slice" + pb.lineTo(Geom::Point(0, 0)); + pb.closePath(); + } else { + // arc only + pb.finish(); } - len = 4*tan((e - s)/4)/3; - double x0 = cos(s); - double y0 = sin(s); - double x1 = x0 + len * cos(s + M_PI_2); - double y1 = y0 + len * sin(s + M_PI_2); - double x3 = cos(e); - double y3 = sin(e); - double x2 = x3 + len * cos(e - M_PI_2); - double y2 = y3 + len * sin(e - M_PI_2); -#ifdef ELLIPSE_VERBOSE - g_print("step %d s %f e %f coords %f %f %f %f %f %f\n", - i, s, e, x1, y1, x2, y2, x3, y3); -#endif - curve->curveto(x1,y1, x2,y2, x3,y3); - } + curve = new SPCurve(pb.peek()); + } else { + // Full ellipse + Geom::Circle circle(0, 0, 1); + Geom::PathVector path; - if (slice && this->closed) { // TODO: is this check for "ellipse->closed" necessary? - curve->lineto(0., 0.); - } + circle.getPath(path); - if (this->closed) { + curve = new SPCurve(path); curve->closepath(); } - Geom::Affine aff = Geom::Scale(rx, ry) * Geom::Translate(this->cx.computed, this->cy.computed); + // Stretching / moving the calculated shape to fit the actual dimensions. + Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); curve->transform(aff); /* Reset the shape's curve to the "original_curve" @@ -271,8 +275,6 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, double cx = this->cx.computed; double cy = this->cy.computed; - Geom::Point pt; - // Snap to the 4 quadrant points of the this, but only if the arc // spans far enough to include them if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)) { @@ -280,7 +282,7 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, for (angle = 0; angle < SP_2PI; angle += M_PI_2) { if (angle >= this->start && angle <= this->end) { - pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2dt; + Geom::Point pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT, Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)); } } @@ -291,7 +293,7 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, bool c2 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT); if (c1 || c2) { - pt = Geom::Point(cx, cy) * i2dt; + Geom::Point pt = Geom::Point(cx, cy) * i2dt; if (c1) { p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); @@ -306,13 +308,13 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) { // Add the start point, if it's not coincident with a quadrant point if (fmod(this->start, M_PI_2) != 0.0 ) { - pt = Geom::Point(cx + cos(this->start)*rx, cy + sin(this->start)*ry) * i2dt; + Geom::Point pt = Geom::Point(cx + cos(this->start)*rx, cy + sin(this->start)*ry) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } // Add the end point, if it's not coincident with a quadrant point if (fmod(this->end, M_PI_2) != 0.0 ) { - pt = Geom::Point(cx + cos(this->end)*rx, cy + sin(this->end)*ry) * i2dt; + Geom::Point pt = Geom::Point(cx + cos(this->end)*rx, cy + sin(this->end)*ry) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } } |
