public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv)
        {
            if (!conv.TrySplitValues(commandString.Substring(1), out var values, false))
            {
                yield break;
            }

            int valuePos = 0;

            while (valuePos < values.Length)
            {
                var start = new Pnt2d();
                if (lastSegment != null)
                {
                    start = lastSegment.End;
                }

                double      rx    = values[0] * conv.Scale;
                double      ry    = values[1] * conv.Scale;
                double      angle = values[2];
                SvgArcSize  size  = values[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                SvgArcSweep sweep = values[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                Pnt2d       end   = new Pnt2d(values[5] * conv.Scale, values[6] * conv.Scale);
                if (char.IsLower(commandString[0]))
                {
                    end += start;
                }
                valuePos += 7;

                lastSegment = new SvgPathSegArc(start, rx, ry, angle, size, sweep, end);
                yield return(lastSegment);
            }
        }
Example #2
0
        private static SvgPath ConvertArc(Arc arc)
        {
            SvgPath svgPath = new SvgPath();

            SvgPathSegmentList svgPathSegmentList = new SvgPathSegmentList();

            svgPathSegmentList.Add(new SvgMoveToSegment(arc.GetEndPoint(0).ConvertToPointF()));

            XYZ a = arc.GetEndPoint(0) - arc.Center;
            XYZ b = arc.GetEndPoint(1) - arc.Center;

            double angleAboutAxis = a.AngleOnPlaneTo(b, arc.Normal);


            SvgArcSweep svgArcSweep = SvgArcSweep.Positive;

            if (angleAboutAxis >= 180)
            {
                svgArcSweep = SvgArcSweep.Negative;
            }

            SvgArcSize svgArcSize = SvgArcSize.Small;

            SvgArcSegment svgArcSegment = new SvgArcSegment(svgPathSegmentList.Last.End, (float)arc.Radius, (float)arc.Radius, (float)angleAboutAxis, svgArcSize, svgArcSweep, arc.GetEndPoint(1).ConvertToPointF());

            svgPathSegmentList.Add(svgArcSegment);
            svgPath.PathData = svgPathSegmentList;

            return(svgPath);
        }
 public SvgArcSegment(PointF start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, PointF end)
     : base(start, end)
 {
     this.RadiusX = Math.Abs(radiusX);
     this.RadiusY = Math.Abs(radiusY);
     this.Angle = angle;
     this.Sweep = sweep;
     this.Size = size;
 }
Example #4
0
 public SvgArcSegment(PointF start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, PointF end)
     : base(start, end)
 {
     this.RadiusX = System.Math.Abs(radiusX);
     this.RadiusY = System.Math.Abs(radiusY);
     this.Angle   = angle;
     this.Sweep   = sweep;
     this.Size    = size;
 }
Example #5
0
 public SvgArcSegment(float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, bool isRelative, PointF end)
     : base(isRelative, end)
 {
     RadiusX = Math.Abs(radiusX);
     RadiusY = Math.Abs(radiusY);
     Angle   = angle;
     Sweep   = sweep;
     Size    = size;
 }
Example #6
0
 public SvgArcSegment(PointF start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, PointF end)
     : base(start, end)
 {
     RadiusX = Math.Abs(radiusX);
     RadiusY = Math.Abs(radiusY);
     Angle   = angle;
     Sweep   = sweep;
     Size    = size;
 }
 public SvgPathSegArc(Pnt2d start, double radiusX, double radiusY, double angle,
                      SvgArcSize size, SvgArcSweep sweep, Pnt2d end)
     : base(start, end)
 {
     RadiusX = radiusX;
     RadiusY = radiusY;
     Angle   = angle;
     Size    = size;
     Sweep   = sweep;
 }
 public SvgArcSegment(Point start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep,
     Point end)
     : base(start, end)
 {
     RadiusX = Math.Abs(radiusX);
     RadiusY = Math.Abs(radiusY);
     Angle = angle;
     Sweep = sweep;
     Size = size;
 }
Example #9
0
 public svgDrawArc(PointF start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, PointF end)
 {
     this.Start   = start;
     this.End     = end;
     this.RadiusX = Math.Abs(radiusX);
     this.RadiusY = Math.Abs(radiusY);
     this.Angle   = angle;
     this.Sweep   = sweep;
     this.Size    = size;
 }
Example #10
0
 public SvgArcSegment(IPoint2F start,
                      Single radiusX,
                      Single radiusY,
                      Single angle,
                      SvgArcSize size,
                      SvgArcSweep sweep,
                      IPoint2F end)
     : base(start, end)
 {
     RadiusX = Math.Abs(radiusX);
     RadiusY = Math.Abs(radiusY);
     Angle   = angle;
     Sweep   = sweep;
     Size    = size;
 }
Example #11
0
        public void Set(float startX, float startY,
                        float radiusX, float radiusY,
                        float angle, SvgArcSize size,
                        SvgArcSweep sweep, float endX, float endY)
        {
            this.StartX = startX;
            this.StartY = startY;
            this.EndX   = endX;
            this.EndY   = endY;

            this.RadiusX = Math.Abs(radiusX);
            this.RadiusY = Math.Abs(radiusY);
            this.Angle   = angle;
            this.Sweep   = sweep;
            this.Size    = size;
        }
Example #12
0
        private static SvgPath ConverPolyCurve(List <Curve> curves)
        {
            SvgPath svgPath = new SvgPath();

            SvgPathSegmentList svgPathSegmentList = new SvgPathSegmentList();

            svgPathSegmentList.Add(new SvgMoveToSegment(curves[0].GetEndPoint(0).ConvertToPointF()));

            foreach (Curve curve in curves)
            {
                if (curve is Arc)
                {
                    Arc arc = (Arc)curve;

                    XYZ a = arc.GetEndPoint(0) - arc.Center;
                    XYZ b = arc.GetEndPoint(1) - arc.Center;

                    double angleAboutAxis = a.AngleOnPlaneTo(b, arc.Normal);

                    SvgArcSweep svgArcSweep = SvgArcSweep.Positive;

                    if (angleAboutAxis >= 180)
                    {
                        svgArcSweep = SvgArcSweep.Negative;
                    }

                    SvgArcSize svgArcSize = SvgArcSize.Small;

                    SvgArcSegment svgArcSegment = new SvgArcSegment(svgPathSegmentList.Last.End, (float)arc.Radius, (float)arc.Radius, (float)angleAboutAxis, svgArcSize, svgArcSweep, arc.GetEndPoint(1).ConvertToPointF());

                    svgPathSegmentList.Add(svgArcSegment);
                }
                else if (curve is Line)
                {
                    SvgLineSegment svgLineSegment = new SvgLineSegment(svgPathSegmentList.Last.End, ((Line)curve).GetEndPoint(1).ConvertToPointF());

                    svgPathSegmentList.Add(svgLineSegment);
                }
            }


            svgPath.PathData = svgPathSegmentList;

            return(svgPath);
        }
    protected void DrawArc(SvgDocument source, PointF center, float radius, PointF startPoint, PointF endPoint, bool largeArc = false)
    {
        SvgPath svgPath = new SvgPath()
        {
            Fill        = new SvgColourServer(Color.Transparent),
            StrokeWidth = MandalaGenerator.StrokeWidth,
            Stroke      = new SvgColourServer(Color.Black)
        };

        svgPath.PathData = new SvgPathSegmentList();

        SvgMoveToSegment svgStartMove = new SvgMoveToSegment(startPoint);

        svgPath.PathData.Add(svgStartMove);

        SvgArcSize size = largeArc ? SvgArcSize.Large : SvgArcSize.Small;

        SvgArcSegment arc = new SvgArcSegment(startPoint, radius, radius, 0, size, SvgArcSweep.Negative, endPoint);

        svgPath.PathData.Add(arc);

        source.Children.Add(svgPath);
    }
Example #14
0
        //---------------------------------------------------------------------
        public void DrawArc(float fromX, float fromY, float endX, float endY,
                            float xaxisRotationAngleDec, float rx, float ry,
                            SvgArcSize arcSize, SvgArcSweep arcSweep)
        {
            //------------------
            //SVG Elliptical arc ...
            //from Apache Batik
            //-----------------

            CenterFormArc centerFormArc = new CenterFormArc();

            ComputeArc2(fromX, fromY, rx, ry,
                        DegToRad(xaxisRotationAngleDec),
                        arcSize == SvgArcSize.Large,
                        arcSweep == SvgArcSweep.Negative,
                        endX, endY, ref centerFormArc);
            arcTool.Init(centerFormArc.cx, centerFormArc.cy, rx, ry,
                         centerFormArc.radStartAngle,
                         (centerFormArc.radStartAngle + centerFormArc.radSweepDiff));

            VertexStore v1       = GetFreeVxs();
            bool        stopLoop = false;

            foreach (VertexData vertexData in arcTool.GetVertexIter())
            {
                switch (vertexData.command)
                {
                case VertexCmd.NoMore:
                    stopLoop = true;
                    break;

                default:
                    v1.AddVertex(vertexData.x, vertexData.y, vertexData.command);
                    //yield return vertexData;
                    break;
                }
                //------------------------------
                if (stopLoop)
                {
                    break;
                }
            }

            double scaleRatio = 1;

            if (centerFormArc.scaleUp)
            {
                int    vxs_count = v1.Count;
                double px0, py0, px_last, py_last;
                v1.GetVertex(0, out px0, out py0);
                v1.GetVertex(vxs_count - 1, out px_last, out py_last);
                double distance1 = Math.Sqrt((px_last - px0) * (px_last - px0) + (py_last - py0) * (py_last - py0));
                double distance2 = Math.Sqrt((endX - fromX) * (endX - fromX) + (endY - fromY) * (endY - fromY));
                if (distance1 < distance2)
                {
                    scaleRatio = distance2 / distance1;
                }
                else
                {
                }
            }

            if (xaxisRotationAngleDec != 0)
            {
                //also  rotate
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
                else
                {
                    //not scalue
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
            }
            else
            {
                //no rotate
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
            }

            _aggStroke.Width = this.StrokeWidth;


            var v3 = _aggStroke.MakeVxs(v1, GetFreeVxs());

            _canvas.DrawGfxPath(_canvas.StrokeColor, InternalGraphicsPath.CreateGraphicsPath(new VertexStoreSnap(v3)));

            ReleaseVxs(ref v3);
            ReleaseVxs(ref v1);
        }
Example #15
0
        public static void AddToPath(GraphicsPath graphicsPath, Vector2 Start, Vector2 End, float RadiusX, float RadiusY, float Angle, SvgArcSize Size, SvgArcSweep Sweep)
        {
            if (Start == End)
            {
                return;
            }

            if (RadiusX == 0.0f && RadiusY == 0.0f)
            {
                graphicsPath.AddElement(new LineElement(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((double)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.AddElement(new BezierElement(
                                            startX, startY,
                                            (float)(startX + dx1), (float)(startY + dy1),
                                            (float)(endpointX + dxe), (float)(endpointY + dye),
                                            (float)endpointX, (float)endpointY));

                theta1 = theta2;
                startX = (float)endpointX;
                startY = (float)endpointY;
            }
        }
Example #16
0
        public void DrawArc(float fromX, float fromY, float endX, float endY,
                            float xaxisRotationAngleDec, float rx, float ry,
                            SvgArcSize arcSize, SvgArcSweep arcSweep)
        {
            //------------------
            //SVG Elliptical arc ...
            //from Apache Batik
            //-----------------

            CenterFormArc centerFormArc = new CenterFormArc();

            ComputeArc2(fromX, fromY, rx, ry,
                        DegToRad(xaxisRotationAngleDec),
                        arcSize == SvgArcSize.Large,
                        arcSweep == SvgArcSweep.Negative,
                        endX, endY, ref centerFormArc);


            arcTool.Init(centerFormArc.cx, centerFormArc.cy, rx, ry,
                         centerFormArc.radStartAngle,
                         (centerFormArc.radStartAngle + centerFormArc.radSweepDiff));

            VertexStore vxs      = new VertexStore();
            bool        stopLoop = false;

            foreach (VertexData vertexData in arcTool.GetVertexIter())
            {
                switch (vertexData.command)
                {
                case VertexCmd.Stop:
                    stopLoop = true;
                    break;

                default:
                    vxs.AddVertex(vertexData.x, vertexData.y, vertexData.command);
                    //yield return vertexData;
                    break;
                }
                //------------------------------
                if (stopLoop)
                {
                    break;
                }
            }


            double scaleRatio = 1;

            if (centerFormArc.scaleUp)
            {
                int    vxs_count = vxs.Count;
                double px0, py0, px_last, py_last;

                vxs.GetVertex(0, out px0, out py0);
                vxs.GetVertex(vxs_count - 1, out px_last, out py_last);

                double distance1 = Math.Sqrt((px_last - px0) * (px_last - px0) + (py_last - py0) * (py_last - py0));
                double distance2 = Math.Sqrt((endX - fromX) * (endX - fromX) + (endY - fromY) * (endY - fromY));

                if (distance1 < distance2)
                {
                    scaleRatio = distance2 / distance1;
                }
                else
                {
                }
            }

            if (xaxisRotationAngleDec != 0)
            {
                //also  rotate
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    vxs = mat.TransformToVxs(vxs);
                }
                else
                {
                    //not scalue
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    vxs = mat.TransformToVxs(vxs);
                }
            }
            else
            {
                //no rotate
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                        new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    vxs = mat.TransformToVxs(vxs);
                }
            }

            vxs = aggStroke.MakeVxs(vxs);
            sclineRas.Reset();
            sclineRas.AddPath(vxs);
            sclineRasToGL.DrawWithColor(sclineRas, sclinePack8, this.strokeColor);
        }
Example #17
0
 public SvgArcSegment(PointF start, float radiusX, float radiusY, float angle, SvgArcSize size, SvgArcSweep sweep, PointF end)
     : this(radiusX, radiusY, angle, size, sweep, false, end)
 {
     Start = start;
 }
Example #18
0
        //---------------------------------------------------------------------
        public void DrawArc(
            float fromX, float fromY, float endX, float endY,
            float xaxisRotationAngleDec, float rx, float ry,
            SvgArcSize arcSize, SvgArcSweep arcSweep)
        {
            //------------------
            //SVG Elliptical arc ...
            //from Apache Batik
            //-----------------

            CenterFormArc centerFormArc = new CenterFormArc();

            ComputeArc2(fromX, fromY, rx, ry,
                        AggMath.deg2rad(xaxisRotationAngleDec),
                        arcSize == SvgArcSize.Large,
                        arcSweep == SvgArcSweep.Negative,
                        endX, endY, ref centerFormArc);

            //
            using (VectorToolBox.Borrow(out Arc arcTool))
                using (VxsTemp.Borrow(out var v1, out var v2, out var v3))
                {
                    arcTool.Init(centerFormArc.cx, centerFormArc.cy, rx, ry,
                                 centerFormArc.radStartAngle,
                                 (centerFormArc.radStartAngle + centerFormArc.radSweepDiff));
                    bool stopLoop = false;
                    foreach (VertexData vertexData in arcTool.GetVertexIter())
                    {
                        switch (vertexData.command)
                        {
                        case VertexCmd.NoMore:
                            stopLoop = true;
                            break;

                        default:
                            v1.AddVertex(vertexData.x, vertexData.y, vertexData.command);
                            //yield return vertexData;
                            break;
                        }
                        //------------------------------
                        if (stopLoop)
                        {
                            break;
                        }
                    }

                    double scaleRatio = 1;
                    if (centerFormArc.scaleUp)
                    {
                        int    vxs_count = v1.Count;
                        double px0, py0, px_last, py_last;
                        v1.GetVertex(0, out px0, out py0);
                        v1.GetVertex(vxs_count - 1, out px_last, out py_last);
                        double distance1 = Math.Sqrt((px_last - px0) * (px_last - px0) + (py_last - py0) * (py_last - py0));
                        double distance2 = Math.Sqrt((endX - fromX) * (endX - fromX) + (endY - fromY) * (endY - fromY));
                        if (distance1 < distance2)
                        {
                            scaleRatio = distance2 / distance1;
                        }
                        else
                        {
                        }
                    }

                    if (xaxisRotationAngleDec != 0)
                    {
                        //also  rotate
                        if (centerFormArc.scaleUp)
                        {
                            //var mat = Affine.NewMatix(
                            //        new AffinePlan(AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                            //        new AffinePlan(AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                            //        new AffinePlan(AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                            //        new AffinePlan(AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                            //mat1.TransformToVxs(v1, v2);
                            //v1 = v2;

                            AffineMat mat = AffineMat.Iden;
                            mat.Translate(-centerFormArc.cx, -centerFormArc.cy);
                            mat.Scale(scaleRatio);
                            mat.RotateDeg(xaxisRotationAngleDec);
                            mat.Translate(centerFormArc.cx, centerFormArc.cy);
                            VertexStoreTransformExtensions.TransformToVxs(ref mat, v1, v2);
                            v1 = v2;
                        }
                        else
                        {
                            //not scale
                            //var mat = Affine.NewMatix(
                            //        AffinePlan.Translate(-centerFormArc.cx, -centerFormArc.cy),
                            //        AffinePlan.RotateDeg(xaxisRotationAngleDec),
                            //        AffinePlan.Translate(centerFormArc.cx, centerFormArc.cy));
                            //mat.TransformToVxs(v1, v2);
                            //v1 = v2;

                            AffineMat mat = AffineMat.Iden;
                            mat.Translate(-centerFormArc.cx, -centerFormArc.cy);
                            mat.RotateDeg(xaxisRotationAngleDec);
                            mat.Translate(centerFormArc.cx, centerFormArc.cy);
                            VertexStoreTransformExtensions.TransformToVxs(ref mat, v1, v2);
                            v1 = v2;
                        }
                    }
                    else
                    {
                        //no rotate
                        if (centerFormArc.scaleUp)
                        {
                            //var mat = Affine.NewMatix(
                            //        new AffinePlan(AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                            //        new AffinePlan(AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                            //        new AffinePlan(AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));

                            //mat.TransformToVxs(v1, v2);
                            //v1 = v2;
                            AffineMat mat = AffineMat.Iden;
                            mat.Translate(-centerFormArc.cx, -centerFormArc.cy);
                            mat.RotateDeg(scaleRatio);
                            mat.Translate(centerFormArc.cx, centerFormArc.cy);
                            //
                            VertexStoreTransformExtensions.TransformToVxs(ref mat, v1, v2);
                            v1 = v2;
                        }
                    }

                    //_stroke.Width = this.StrokeWidth;
                    //_stroke.MakeVxs(v1, v3);
                    //_pcx.DrawGfxPath(_pcx.StrokeColor, _pathRenderVxBuilder.CreatePathRenderVx(v3));
                }
        }
Example #19
0
        internal static void MakeBezierCurveFromArc(ref PointF start,
            ref PointF end,
            float rx,
            float ry,
            float angle,
            SvgArcSize arcSize,
            SvgArcSweep arcSweep,
            out PointF[] bezier4Points)
        {
            double sinPhi = Math.Sin(angle * SvgPathSegArc.RAD_PER_DEG);
            double cosPhi = Math.Cos(angle * SvgPathSegArc.RAD_PER_DEG);
            double x1dash = cosPhi * (start.X - end.X) / 2.0 + sinPhi * (start.Y - end.Y) / 2.0;
            double y1dash = -sinPhi * (start.X - end.X) / 2.0 + cosPhi * (start.Y - end.Y) / 2.0;
            double root;
            double numerator = (rx * rx * ry * ry) - (rx * rx * y1dash * y1dash) - (ry * ry * x1dash * x1dash);
            if (numerator < 0.0)
            {
                float s = (float)Math.Sqrt(1.0 - numerator / (rx * rx * ry * ry));
                rx *= s;
                ry *= s;
                root = 0.0;
            }
            else
            {
                root = ((arcSize == SvgArcSize.Large && arcSweep == SvgArcSweep.Positive)
                    || (arcSize == SvgArcSize.Small && arcSweep == SvgArcSweep.Negative) ? -1.0 : 1.0) * Math.Sqrt(numerator / (rx * rx * y1dash * y1dash + ry * ry * x1dash * x1dash));
            }


            double cxdash = root * rx * y1dash / ry;
            double cydash = -root * ry * x1dash / rx;
            double cx = cosPhi * cxdash - sinPhi * cydash + (start.X + end.X) / 2.0;
            double cy = sinPhi * cxdash + cosPhi * cydash + (start.Y + end.Y) / 2.0;
            double theta1 = SvgPathSegArc.CalculateVectorAngle(1.0, 0.0, (x1dash - cxdash) / rx, (y1dash - cydash) / ry);
            double dtheta = SvgPathSegArc.CalculateVectorAngle((x1dash - cxdash) / rx, (y1dash - cydash) / ry, (-x1dash - cxdash) / rx, (-y1dash - cydash) / ry);
            if (arcSweep == SvgArcSweep.Negative && dtheta > 0)
            {
                dtheta -= 2.0 * Math.PI;
            }
            else if (arcSweep == SvgArcSweep.Positive && dtheta < 0)
            {
                dtheta += 2.0 * Math.PI;
            }

            int nsegments = (int)Math.Ceiling((double)Math.Abs(dtheta / (Math.PI / 2.0)));
            double delta = dtheta / nsegments;
            double t = 8.0 / 3.0 * Math.Sin(delta / 4.0) * Math.Sin(delta / 4.0) / Math.Sin(delta / 2.0);
            double startX = start.X;
            double startY = start.Y;
            bezier4Points = new PointF[nsegments * 4];
            int nn = 0;
            for (int n = 0; n < nsegments; ++n)
            {
                double cosTheta1 = Math.Cos(theta1);
                double sinTheta1 = Math.Sin(theta1);
                double theta2 = theta1 + delta;
                double cosTheta2 = Math.Cos(theta2);
                double sinTheta2 = Math.Sin(theta2);
                double endpointX = cosPhi * rx * cosTheta2 - sinPhi * ry * sinTheta2 + cx;
                double endpointY = sinPhi * rx * cosTheta2 + cosPhi * ry * sinTheta2 + cy;
                double dx1 = t * (-cosPhi * rx * sinTheta1 - sinPhi * ry * cosTheta1);
                double dy1 = t * (-sinPhi * rx * sinTheta1 + cosPhi * ry * cosTheta1);
                double dxe = t * (cosPhi * rx * sinTheta2 + sinPhi * ry * cosTheta2);
                double dye = t * (sinPhi * rx * sinTheta2 - cosPhi * ry * cosTheta2);
                bezier4Points[nn] = new PointF((float)startX, (float)startY);
                bezier4Points[nn + 1] = new PointF((float)(startX + dx1), (float)(startY + dy1));
                bezier4Points[nn + 2] = new PointF((float)(endpointX + dxe), (float)(endpointY + dye));
                bezier4Points[nn + 3] = new PointF((float)endpointX, (float)endpointY);
                nn += 4;
                theta1 = theta2;
                startX = (float)endpointX;
                startY = (float)endpointY;
            }
        }
Example #20
0
        public static void MakeBezierCurveFromArc(ref PointF start,
            ref PointF end,
            float rx,
            float ry,
            float angle,
            SvgArcSize arcSize,
            SvgArcSweep arcSweep,
            out PointF[] bezier4Points)
        {
            double sinPhi = Math.Sin(angle * SvgPathSegArc.RAD_PER_DEG);
            double cosPhi = Math.Cos(angle * SvgPathSegArc.RAD_PER_DEG);
            double x1dash = cosPhi * (start.X - end.X) / 2.0 + sinPhi * (start.Y - end.Y) / 2.0;
            double y1dash = -sinPhi * (start.X - end.X) / 2.0 + cosPhi * (start.Y - end.Y) / 2.0;
            double root;
            double numerator = (rx * rx * ry * ry) - (rx * rx * y1dash * y1dash) - (ry * ry * x1dash * x1dash);
            if (numerator < 0.0)
            {
                float s = (float)Math.Sqrt(1.0 - numerator / (rx * rx * ry * ry));
                rx *= s;
                ry *= s;
                root = 0.0;
            }
            else
            {
                root = ((arcSize == SvgArcSize.Large && arcSweep == SvgArcSweep.Positive)
                    || (arcSize == SvgArcSize.Small && arcSweep == SvgArcSweep.Negative) ? -1.0 : 1.0) * Math.Sqrt(numerator / (rx * rx * y1dash * y1dash + ry * ry * x1dash * x1dash));
            }


            double cxdash = root * rx * y1dash / ry;
            double cydash = -root * ry * x1dash / rx;
            double cx = cosPhi * cxdash - sinPhi * cydash + (start.X + end.X) / 2.0;
            double cy = sinPhi * cxdash + cosPhi * cydash + (start.Y + end.Y) / 2.0;
            double theta1 = SvgPathSegArc.CalculateVectorAngle(1.0, 0.0, (x1dash - cxdash) / rx, (y1dash - cydash) / ry);
            double dtheta = SvgPathSegArc.CalculateVectorAngle((x1dash - cxdash) / rx, (y1dash - cydash) / ry, (-x1dash - cxdash) / rx, (-y1dash - cydash) / ry);
            if (arcSweep == SvgArcSweep.Negative && dtheta > 0)
            {
                dtheta -= 2.0 * Math.PI;
            }
            else if (arcSweep == SvgArcSweep.Positive && dtheta < 0)
            {
                dtheta += 2.0 * Math.PI;
            }

            int nsegments = (int)Math.Ceiling((double)Math.Abs(dtheta / (Math.PI / 2.0)));
            double delta = dtheta / nsegments;
            double t = 8.0 / 3.0 * Math.Sin(delta / 4.0) * Math.Sin(delta / 4.0) / Math.Sin(delta / 2.0);
            double startX = start.X;
            double startY = start.Y;
            bezier4Points = new PointF[nsegments * 4];
            int nn = 0;
            for (int n = 0; n < nsegments; ++n)
            {
                double cosTheta1 = Math.Cos(theta1);
                double sinTheta1 = Math.Sin(theta1);
                double theta2 = theta1 + delta;
                double cosTheta2 = Math.Cos(theta2);
                double sinTheta2 = Math.Sin(theta2);
                double endpointX = cosPhi * rx * cosTheta2 - sinPhi * ry * sinTheta2 + cx;
                double endpointY = sinPhi * rx * cosTheta2 + cosPhi * ry * sinTheta2 + cy;
                double dx1 = t * (-cosPhi * rx * sinTheta1 - sinPhi * ry * cosTheta1);
                double dy1 = t * (-sinPhi * rx * sinTheta1 + cosPhi * ry * cosTheta1);
                double dxe = t * (cosPhi * rx * sinTheta2 + sinPhi * ry * cosTheta2);
                double dye = t * (sinPhi * rx * sinTheta2 - cosPhi * ry * cosTheta2);
                bezier4Points[nn] = new PointF((float)startX, (float)startY);
                bezier4Points[nn + 1] = new PointF((float)(startX + dx1), (float)(startY + dy1));
                bezier4Points[nn + 2] = new PointF((float)(endpointX + dxe), (float)(endpointY + dye));
                bezier4Points[nn + 3] = new PointF((float)endpointX, (float)endpointY);
                nn += 4;
                theta1 = theta2;
                startX = (float)endpointX;
                startY = (float)endpointY;
            }
        }
        //---------------------------------------------------------------------
        public void DrawArc(float fromX, float fromY, float endX, float endY,
         float xaxisRotationAngleDec, float rx, float ry,
         SvgArcSize arcSize, SvgArcSweep arcSweep)
        {
            //------------------
            //SVG Elliptical arc ...
            //from Apache Batik
            //-----------------

            CenterFormArc centerFormArc = new CenterFormArc();
            ComputeArc2(fromX, fromY, rx, ry,
                 DegToRad(xaxisRotationAngleDec),
                 arcSize == SvgArcSize.Large,
                 arcSweep == SvgArcSweep.Negative,
                 endX, endY, ref centerFormArc);
            arcTool.Init(centerFormArc.cx, centerFormArc.cy, rx, ry,
                centerFormArc.radStartAngle,
                (centerFormArc.radStartAngle + centerFormArc.radSweepDiff));

            VertexStore v1 = GetFreeVxs();
            bool stopLoop = false;
            foreach (VertexData vertexData in arcTool.GetVertexIter())
            {
                switch (vertexData.command)
                {
                    case VertexCmd.Stop:
                        stopLoop = true;
                        break;
                    default:
                        v1.AddVertex(vertexData.x, vertexData.y, vertexData.command);
                        //yield return vertexData;
                        break;
                }
                //------------------------------
                if (stopLoop) { break; }
            }

            double scaleRatio = 1;
            if (centerFormArc.scaleUp)
            {
                int vxs_count = v1.Count;
                double px0, py0, px_last, py_last;
                v1.GetVertex(0, out px0, out py0);
                v1.GetVertex(vxs_count - 1, out px_last, out py_last);
                double distance1 = Math.Sqrt((px_last - px0) * (px_last - px0) + (py_last - py0) * (py_last - py0));
                double distance2 = Math.Sqrt((endX - fromX) * (endX - fromX) + (endY - fromY) * (endY - fromY));
                if (distance1 < distance2)
                {
                    scaleRatio = distance2 / distance1;
                }
                else
                {
                }
            }

            if (xaxisRotationAngleDec != 0)
            {
                //also  rotate 
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
                else
                {
                    //not scalue
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
            }
            else
            {
                //no rotate
                if (centerFormArc.scaleUp)
                {
                    var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio),
                            new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy));
                    var v2 = GetFreeVxs();
                    mat.TransformToVxs(v1, v2);
                    ReleaseVxs(ref v1);
                    v1 = v2;
                }
            }

            _aggStroke.Width = this.StrokeWidth;


            var v3 = _aggStroke.MakeVxs(v1, GetFreeVxs());
            _canvas.DrawGfxPath(_canvas.StrokeColor, InternalGraphicsPath.CreateGraphicsPath(new VertexStoreSnap(v3)));

            ReleaseVxs(ref v3);
            ReleaseVxs(ref v1);

        }