mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
SvgArc fix
git-svn-id: svn://ultimatepp.org/upp/trunk@872 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
ccd96539bf
commit
ffbb807daa
1 changed files with 53 additions and 53 deletions
|
|
@ -1,53 +1,53 @@
|
||||||
#include "Painter.h"
|
#include "Painter.h"
|
||||||
|
|
||||||
NAMESPACE_UPP
|
NAMESPACE_UPP
|
||||||
|
|
||||||
void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
||||||
const Pointf& p1, const Pointf& p0)
|
const Pointf& p1, const Pointf& p0)
|
||||||
{
|
{
|
||||||
Pointf r(fabs(rr.x), fabs(rr.y));
|
Pointf r(fabs(rr.x), fabs(rr.y));
|
||||||
Xform2D m = Xform2D::Rotation(-xangle);
|
Xform2D m = Xform2D::Rotation(-xangle);
|
||||||
Pointf d1 = m.Transform(Mid(p0, p1));
|
Pointf d1 = m.Transform(0.5 * (p0 - p1));
|
||||||
Pointf pr = r * r;
|
Pointf pr = r * r;
|
||||||
Pointf p = d1 * d1;
|
Pointf p = d1 * d1;
|
||||||
double check = p.x / pr.x + p.y / pr.y;
|
double check = p.x / pr.x + p.y / pr.y;
|
||||||
if(check > 1)
|
if(check > 1)
|
||||||
r *= sqrt(check);
|
r *= sqrt(check);
|
||||||
m.x /= r.x;
|
m.x /= r.x;
|
||||||
m.y /= r.y;
|
m.y /= r.y;
|
||||||
Pointf q0 = m.Transform(p0);
|
Pointf q0 = m.Transform(p0);
|
||||||
Pointf q1 = m.Transform(p1);
|
Pointf q1 = m.Transform(p1);
|
||||||
double d = SquaredDistance(q0, q1);
|
double d = SquaredDistance(q0, q1);
|
||||||
double sfactor_sq = 1.0 / d - 0.25;
|
double sfactor_sq = 1.0 / d - 0.25;
|
||||||
if(sfactor_sq < 0)
|
if(sfactor_sq < 0)
|
||||||
sfactor_sq = 0;
|
sfactor_sq = 0;
|
||||||
double sfactor = sqrt(sfactor_sq);
|
double sfactor = sqrt(sfactor_sq);
|
||||||
if(sweep == large)
|
if(sweep == large)
|
||||||
sfactor = -sfactor;
|
sfactor = -sfactor;
|
||||||
Pointf c(0.5 * (q0.x + q1.x) - sfactor * (q1.y - q0.y),
|
Pointf c(0.5 * (q0.x + q1.x) - sfactor * (q1.y - q0.y),
|
||||||
0.5 * (q0.y + q1.y) + sfactor * (q1.x - q0.x));
|
0.5 * (q0.y + q1.y) + sfactor * (q1.x - q0.x));
|
||||||
double theta = Bearing(q0 - c);
|
double theta = Bearing(q0 - c);
|
||||||
double th_sweep = Bearing(q1 - c) - theta;
|
double th_sweep = Bearing(q1 - c) - theta;
|
||||||
if(th_sweep < 0 && sweep)
|
if(th_sweep < 0 && sweep)
|
||||||
th_sweep += 2 * M_PI;
|
th_sweep += 2 * M_PI;
|
||||||
else
|
else
|
||||||
if(th_sweep > 0 && !sweep)
|
if(th_sweep > 0 && !sweep)
|
||||||
th_sweep -= 2 * M_PI;
|
th_sweep -= 2 * M_PI;
|
||||||
int nsegs = int(ceil(fabs(th_sweep / (M_PI * 0.5 + 0.001))));
|
int nsegs = int(ceil(fabs(th_sweep / (M_PI * 0.5 + 0.001))));
|
||||||
m = Xform2D::Rotation(xangle);
|
m = Xform2D::Rotation(xangle);
|
||||||
m.x *= r;
|
m.x *= r;
|
||||||
m.y *= r;
|
m.y *= r;
|
||||||
for(int i = 0; i < nsegs; i++) {
|
for(int i = 0; i < nsegs; i++) {
|
||||||
double th0 = theta + i * th_sweep / nsegs;
|
double th0 = theta + i * th_sweep / nsegs;
|
||||||
double th1 = theta + (i + 1) * th_sweep / nsegs;
|
double th1 = theta + (i + 1) * th_sweep / nsegs;
|
||||||
double thHalf = 0.5 * (th1 - th0);
|
double thHalf = 0.5 * (th1 - th0);
|
||||||
double t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf);
|
double t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf);
|
||||||
double x3 = c.x + cos(th1);
|
double x3 = c.x + cos(th1);
|
||||||
double y3 = c.y + sin(th1);
|
double y3 = c.y + sin(th1);
|
||||||
Cubic(m.Transform(c.x + cos(th0) - t * sin(th0), c.y + sin(th0) + t * cos(th0)),
|
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 + t * sin(th1), y3 - t * cos(th1)),
|
||||||
m.Transform(x3, y3));
|
m.Transform(x3, y3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END_UPP_NAMESPACE
|
END_UPP_NAMESPACE
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue