public static List<float[]> BezierArc(float x1, float y1, float x2, float y2, float startAng, float extent)
{
float tmp;
if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (y2 > y1) {
tmp = y1;
y1 = y2;
y2 = tmp;
}
float fragAngle;
int Nfrag;
if (Math.Abs(extent) <= 90f) {
fragAngle = extent;
Nfrag = 1;
}
else {
Nfrag = (int)(Math.Ceiling(Math.Abs(extent)/90f));
fragAngle = extent / Nfrag;
}
float x_cen = (x1+x2)/2f;
float y_cen = (y1+y2)/2f;
float rx = (x2-x1)/2f;
float ry = (y2-y1)/2f;
float halfAng = (float)(fragAngle * Math.PI / 360.0);
float kappa = (float)(Math.Abs(4.0 / 3.0 * (1.0 - Math.Cos(halfAng)) / Math.Sin(halfAng)));
List<float[]> pointList = new List<float[]>();
for (int i = 0; i < Nfrag; ++i) {
float theta0 = (float)((startAng + i*fragAngle) * Math.PI / 180.0);
float theta1 = (float)((startAng + (i+1)*fragAngle) * Math.PI / 180.0);
float cos0 = (float)Math.Cos(theta0);
float cos1 = (float)Math.Cos(theta1);
float sin0 = (float)Math.Sin(theta0);
float sin1 = (float)Math.Sin(theta1);
if (fragAngle > 0f) {
pointList.Add(new float[]{x_cen + rx * cos0,
y_cen - ry * sin0,
x_cen + rx * (cos0 - kappa * sin0),
y_cen - ry * (sin0 + kappa * cos0),
x_cen + rx * (cos1 + kappa * sin1),
y_cen - ry * (sin1 - kappa * cos1),
x_cen + rx * cos1,
y_cen - ry * sin1});
}
else {
pointList.Add(new float[]{x_cen + rx * cos0,
y_cen - ry * sin0,
x_cen + rx * (cos0 + kappa * sin0),
y_cen - ry * (sin0 - kappa * cos0),
x_cen + rx * (cos1 - kappa * sin1),
y_cen - ry * (sin1 + kappa * cos1),
x_cen + rx * cos1,
y_cen - ry * sin1});
}
}
return pointList;
}