public override void AddToPath(Path graphicsPath) { if (Start == End) { return; } if (RadiusX == 0.0f && RadiusY == 0.0f) { graphicsPath.LineTo(Start, End); return; } var sinPhi = Math.Sin(Angle*RadiansPerDegree); var cosPhi = Math.Cos(Angle*RadiansPerDegree); var x1dash = cosPhi*(Start.X - End.X)/2.0 + sinPhi*(Start.Y - End.Y)/2.0; var y1dash = -sinPhi*(Start.X - End.X)/2.0 + cosPhi*(Start.Y - End.Y)/2.0; double root; var numerator = RadiusX*RadiusX*RadiusY*RadiusY - RadiusX*RadiusX*y1dash*y1dash - RadiusY*RadiusY*x1dash*x1dash; var rx = RadiusX; var ry = RadiusY; if (numerator < 0.0) { var s = (float) Math.Sqrt(1.0 - numerator/(RadiusX*RadiusX*RadiusY*RadiusY)); rx *= s; ry *= s; root = 0.0; } else { root = ((Size == SvgArcSize.Large && Sweep == SvgArcSweep.Positive) || (Size == SvgArcSize.Small && Sweep == SvgArcSweep.Negative) ? -1.0 : 1.0)*Math.Sqrt(numerator/(RadiusX*RadiusX*y1dash*y1dash + RadiusY*RadiusY*x1dash*x1dash)); } var cxdash = root*rx*y1dash/ry; var cydash = -root*ry*x1dash/rx; var cx = cosPhi*cxdash - sinPhi*cydash + (Start.X + End.X)/2.0; var cy = sinPhi*cxdash + cosPhi*cydash + (Start.Y + End.Y)/2.0; var theta1 = CalculateVectorAngle(1.0, 0.0, (x1dash - cxdash)/rx, (y1dash - cydash)/ry); var dtheta = CalculateVectorAngle((x1dash - cxdash)/rx, (y1dash - cydash)/ry, (-x1dash - cxdash)/rx, (-y1dash - cydash)/ry); if (Sweep == SvgArcSweep.Negative && dtheta > 0) { dtheta -= 2.0*Math.PI; } else if (Sweep == SvgArcSweep.Positive && dtheta < 0) { dtheta += 2.0*Math.PI; } var segments = (int) Math.Ceiling(Math.Abs(dtheta/(Math.PI/2.0))); var delta = dtheta/segments; var t = 8.0/3.0*Math.Sin(delta/4.0)*Math.Sin(delta/4.0)/Math.Sin(delta/2.0); var startX = Start.X; var startY = Start.Y; for (var i = 0; i < segments; ++i) { var cosTheta1 = Math.Cos(theta1); var sinTheta1 = Math.Sin(theta1); var theta2 = theta1 + delta; var cosTheta2 = Math.Cos(theta2); var sinTheta2 = Math.Sin(theta2); var endpointX = cosPhi*rx*cosTheta2 - sinPhi*ry*sinTheta2 + cx; var endpointY = sinPhi*rx*cosTheta2 + cosPhi*ry*sinTheta2 + cy; var dx1 = t*(-cosPhi*rx*sinTheta1 - sinPhi*ry*cosTheta1); var dy1 = t*(-sinPhi*rx*sinTheta1 + cosPhi*ry*cosTheta1); var dxe = t*(cosPhi*rx*sinTheta2 + sinPhi*ry*cosTheta2); var dye = t*(sinPhi*rx*sinTheta2 - cosPhi*ry*cosTheta2); graphicsPath.CurveTo(new Point(startX, startY), new Point((startX + dx1), (startY + dy1)), new Point((endpointX + dxe), (endpointY + dye)), new Point(endpointX, endpointY)); theta1 = theta2; startX = (float) endpointX; startY = (float) endpointY; } }
public override void AddToPath(Path graphicsPath) { graphicsPath.CurveTo(Start, FirstControlPoint, SecondControlPoint, End); }