void AppendArc(bool start, float x, float y, float width, float height, float startAngle, float endAngle)
{
float delta, bcp;
float sin_alpha, sin_beta, cos_alpha, cos_beta;
float rx = width / 2;
float ry = height / 2;
/* center */
float cx = x + rx;
float cy = y + ry;
/* angles in radians */
float alpha = (float)(startAngle * Math.PI / 180);
float beta = (float)(endAngle * Math.PI / 180);
/* adjust angles for ellipses */
alpha = (float) Math.Atan2 (rx * Math.Sin (alpha), ry * Math.Cos (alpha));
beta = (float) Math.Atan2 (rx * Math.Sin (beta), ry * Math.Cos (beta));
if (Math.Abs (beta - alpha) > Math.PI){
if (beta > alpha)
beta -= (float) (2 * Math.PI);
else
alpha -= (float) (2 * Math.PI);
}
delta = beta - alpha;
// http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13)
bcp = (float)(4.0 / 3 * (1 - Math.Cos (delta / 2)) / Math.Sin (delta / 2));
sin_alpha = (float)Math.Sin (alpha);
sin_beta = (float)Math.Sin (beta);
cos_alpha = (float)Math.Cos (alpha);
cos_beta = (float)Math.Cos (beta);
// move to the starting point if we're not continuing a curve
if (start) {
// starting point
float sx = cx + rx * cos_alpha;
float sy = cy + ry * sin_alpha;
Append (sx, sy, PathPointType.Line, false);
}
AppendBezier (cx + rx * (cos_alpha - bcp * sin_alpha),
cy + ry * (sin_alpha + bcp * cos_alpha),
cx + rx * (cos_beta + bcp * sin_beta),
cy + ry * (sin_beta - bcp * cos_beta),
cx + rx * cos_beta,
cy + ry * sin_beta);
}