예제 #1
0
        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;
            }
        }
예제 #2
0
 public override void AddToPath(Path graphicsPath)
 {
     graphicsPath.LineTo(Start, End);
 }