public static PathGeometry AsPathGeometry(this PathF target) { var geometry = new PathGeometry(); PathFigure figure = null; var pointIndex = 0; var arcAngleIndex = 0; var arcClockwiseIndex = 0; foreach (var operation in target.PathOperations) { if (operation == PathOperation.MoveTo) { figure = new PathFigure(); geometry.Figures.Add(figure); figure.StartPoint = target[pointIndex++].ToPoint(); } else if (operation == PathOperation.Line) { var lineSegment = new LineSegment { Point = target[pointIndex++].ToPoint() }; figure.Segments.Add(lineSegment); } else if (operation == PathOperation.Quad) { var quadSegment = new QuadraticBezierSegment { Point1 = target[pointIndex++].ToPoint(), Point2 = target[pointIndex++].ToPoint() }; figure.Segments.Add(quadSegment); } else if (operation == PathOperation.Cubic) { var cubicSegment = new BezierSegment() { Point1 = target[pointIndex++].ToPoint(), Point2 = target[pointIndex++].ToPoint(), Point3 = target[pointIndex++].ToPoint(), }; figure.Segments.Add(cubicSegment); } else if (operation == PathOperation.Arc) { var topLeft = target[pointIndex++]; var bottomRight = target[pointIndex++]; var startAngle = target.GetArcAngle(arcAngleIndex++); var endAngle = target.GetArcAngle(arcAngleIndex++); var clockwise = target.IsArcClockwise(arcClockwiseIndex++); while (startAngle < 0) { startAngle += 360; } while (endAngle < 0) { endAngle += 360; } var sweep = GraphicsOperations.GetSweep(startAngle, endAngle, clockwise); var absSweep = Math.Abs(sweep); var rectX = topLeft.X; var rectY = topLeft.Y; var rectWidth = bottomRight.X - topLeft.X; var rectHeight = bottomRight.Y - topLeft.Y; var startPoint = GraphicsOperations.OvalAngleToPoint(rectX, rectY, rectWidth, rectHeight, -startAngle); var endPoint = GraphicsOperations.OvalAngleToPoint(rectX, rectY, rectWidth, rectHeight, -endAngle); if (figure == null) { figure = new PathFigure(); geometry.Figures.Add(figure); figure.StartPoint = startPoint.ToPoint(); } else { var lineSegment = new LineSegment() { Point = startPoint.ToPoint() }; figure.Segments.Add(lineSegment); } var arcSegment = new ArcSegment() { Point = endPoint.ToPoint(), Size = new UWPSize(rectWidth / 2, rectHeight / 2), SweepDirection = clockwise ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, IsLargeArc = absSweep >= 180, }; figure.Segments.Add(arcSegment); } else if (operation == PathOperation.Close) { figure.IsClosed = true; } } return(geometry); }
public static CGPath ToCGPath( this PathF target) { var path = new CGPath(); int pointIndex = 0; int arcAngleIndex = 0; int arcClockwiseIndex = 0; foreach (var operation in target.PathOperations) { if (operation == PathOperation.MoveTo) { var point = target[pointIndex++]; path.MoveToPoint(point.X, point.Y); } else if (operation == PathOperation.Line) { var endPoint = target[pointIndex++]; path.AddLineToPoint(endPoint.X, endPoint.Y); } else if (operation == PathOperation.Quad) { var controlPoint = target[pointIndex++]; var endPoint = target[pointIndex++]; path.AddQuadCurveToPoint( controlPoint.X, controlPoint.Y, endPoint.X, endPoint.Y); } else if (operation == PathOperation.Cubic) { var controlPoint1 = target[pointIndex++]; var controlPoint2 = target[pointIndex++]; var endPoint = target[pointIndex++]; path.AddCurveToPoint( controlPoint1.X, controlPoint1.Y, controlPoint2.X, controlPoint2.Y, endPoint.X, endPoint.Y); } else if (operation == PathOperation.Arc) { var topLeft = target[pointIndex++]; var bottomRight = target[pointIndex++]; float startAngle = target.GetArcAngle(arcAngleIndex++); float endAngle = target.GetArcAngle(arcAngleIndex++); var clockwise = target.IsArcClockwise(arcClockwiseIndex++); var startAngleInRadians = GraphicsOperations.DegreesToRadians(-startAngle); var endAngleInRadians = GraphicsOperations.DegreesToRadians(-endAngle); while (startAngleInRadians < 0) { startAngleInRadians += (float)Math.PI * 2; } while (endAngleInRadians < 0) { endAngleInRadians += (float)Math.PI * 2; } var cx = (bottomRight.X + topLeft.X) / 2; var cy = (bottomRight.Y + topLeft.Y) / 2; var width = bottomRight.X - topLeft.X; var height = bottomRight.Y - topLeft.Y; var r = width / 2; var transform = CGAffineTransform.MakeTranslation(cx, cy); transform = CGAffineTransform.Multiply(CGAffineTransform.MakeScale(1, height / width), transform); path.AddArc(transform, 0, 0, r, startAngleInRadians, endAngleInRadians, !clockwise); } else if (operation == PathOperation.Close) { path.CloseSubpath(); } } return(path); }
public static APath AsAndroidPath(this PathF path) { var nativePath = new APath(); int pointIndex = 0; int arcAngleIndex = 0; int arcClockwiseIndex = 0; foreach (var operation in path.PathOperations) { if (operation == PathOperation.MoveTo) { var point = path[pointIndex++]; nativePath.MoveTo(point.X, point.Y); } else if (operation == PathOperation.Line) { var point = path[pointIndex++]; nativePath.LineTo(point.X, point.Y); } else if (operation == PathOperation.Quad) { var controlPoint = path[pointIndex++]; var point = path[pointIndex++]; nativePath.QuadTo(controlPoint.X, controlPoint.Y, point.X, point.Y); } else if (operation == PathOperation.Cubic) { var controlPoint1 = path[pointIndex++]; var controlPoint2 = path[pointIndex++]; var point = path[pointIndex++]; nativePath.CubicTo(controlPoint1.X, controlPoint1.Y, controlPoint2.X, controlPoint2.Y, point.X, point.Y); } else if (operation == PathOperation.Arc) { var topLeft = path[pointIndex++]; var bottomRight = path[pointIndex++]; var startAngle = path.GetArcAngle(arcAngleIndex++); var endAngle = path.GetArcAngle(arcAngleIndex++); var clockwise = path.IsArcClockwise(arcClockwiseIndex++); while (startAngle < 0) { startAngle += 360; } while (endAngle < 0) { endAngle += 360; } var rect = new RectF(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y); var sweep = GraphicsOperations.GetSweep(startAngle, endAngle, clockwise); startAngle *= -1; if (!clockwise) { sweep *= -1; } nativePath.ArcTo(rect, startAngle, sweep); } else if (operation == PathOperation.Close) { nativePath.Close(); } } return(nativePath); }