From ffbb807daa38ef9c3d89d4c9e285a6ef130d76b1 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 16 Feb 2009 16:36:11 +0000 Subject: [PATCH] SvgArc fix git-svn-id: svn://ultimatepp.org/upp/trunk@872 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Painter/SvgArc.cpp | 106 +++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/uppsrc/Painter/SvgArc.cpp b/uppsrc/Painter/SvgArc.cpp index f21f36aa2..8f4a7025e 100644 --- a/uppsrc/Painter/SvgArc.cpp +++ b/uppsrc/Painter/SvgArc.cpp @@ -1,53 +1,53 @@ -#include "Painter.h" - -NAMESPACE_UPP - -void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep, - const Pointf& p1, const Pointf& p0) -{ - Pointf r(fabs(rr.x), fabs(rr.y)); - Xform2D m = Xform2D::Rotation(-xangle); - Pointf d1 = m.Transform(Mid(p0, p1)); - Pointf pr = r * r; - Pointf p = d1 * d1; - double check = p.x / pr.x + p.y / pr.y; - if(check > 1) - r *= sqrt(check); - m.x /= r.x; - m.y /= r.y; - Pointf q0 = m.Transform(p0); - Pointf q1 = m.Transform(p1); - double d = SquaredDistance(q0, q1); - double sfactor_sq = 1.0 / d - 0.25; - if(sfactor_sq < 0) - sfactor_sq = 0; - double sfactor = sqrt(sfactor_sq); - if(sweep == large) - sfactor = -sfactor; - Pointf c(0.5 * (q0.x + q1.x) - sfactor * (q1.y - q0.y), - 0.5 * (q0.y + q1.y) + sfactor * (q1.x - q0.x)); - double theta = Bearing(q0 - c); - double th_sweep = Bearing(q1 - c) - theta; - if(th_sweep < 0 && sweep) - th_sweep += 2 * M_PI; - else - if(th_sweep > 0 && !sweep) - th_sweep -= 2 * M_PI; - int nsegs = int(ceil(fabs(th_sweep / (M_PI * 0.5 + 0.001)))); - m = Xform2D::Rotation(xangle); - m.x *= r; - m.y *= r; - for(int i = 0; i < nsegs; i++) { - double th0 = theta + i * th_sweep / nsegs; - double th1 = theta + (i + 1) * th_sweep / nsegs; - double thHalf = 0.5 * (th1 - th0); - double t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf); - double x3 = c.x + cos(th1); - double y3 = c.y + sin(th1); - Cubic(m.Transform(c.x + cos(th0) - t * sin(th0), c.y + sin(th0) + t * cos(th0)), - m.Transform(x3 + t * sin(th1), y3 - t * cos(th1)), - m.Transform(x3, y3)); - } -} - -END_UPP_NAMESPACE +#include "Painter.h" + +NAMESPACE_UPP + +void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep, + const Pointf& p1, const Pointf& p0) +{ + Pointf r(fabs(rr.x), fabs(rr.y)); + Xform2D m = Xform2D::Rotation(-xangle); + Pointf d1 = m.Transform(0.5 * (p0 - p1)); + Pointf pr = r * r; + Pointf p = d1 * d1; + double check = p.x / pr.x + p.y / pr.y; + if(check > 1) + r *= sqrt(check); + m.x /= r.x; + m.y /= r.y; + Pointf q0 = m.Transform(p0); + Pointf q1 = m.Transform(p1); + double d = SquaredDistance(q0, q1); + double sfactor_sq = 1.0 / d - 0.25; + if(sfactor_sq < 0) + sfactor_sq = 0; + double sfactor = sqrt(sfactor_sq); + if(sweep == large) + sfactor = -sfactor; + Pointf c(0.5 * (q0.x + q1.x) - sfactor * (q1.y - q0.y), + 0.5 * (q0.y + q1.y) + sfactor * (q1.x - q0.x)); + double theta = Bearing(q0 - c); + double th_sweep = Bearing(q1 - c) - theta; + if(th_sweep < 0 && sweep) + th_sweep += 2 * M_PI; + else + if(th_sweep > 0 && !sweep) + th_sweep -= 2 * M_PI; + int nsegs = int(ceil(fabs(th_sweep / (M_PI * 0.5 + 0.001)))); + m = Xform2D::Rotation(xangle); + m.x *= r; + m.y *= r; + for(int i = 0; i < nsegs; i++) { + double th0 = theta + i * th_sweep / nsegs; + double th1 = theta + (i + 1) * th_sweep / nsegs; + double thHalf = 0.5 * (th1 - th0); + double t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf); + double x3 = c.x + cos(th1); + double y3 = c.y + sin(th1); + Cubic(m.Transform(c.x + cos(th0) - t * sin(th0), c.y + sin(th0) + t * cos(th0)), + m.Transform(x3 + t * sin(th1), y3 - t * cos(th1)), + m.Transform(x3, y3)); + } +} + +END_UPP_NAMESPACE