internal static BezierPathSegment[] BuildEllipsePath(Vector2 p0, Vector2 p1, float rotation, float rx, float ry, bool largeArc, bool sweep) { if ((p1 - p0).magnitude < ShapeUtils.Epsilon) { return(new BezierPathSegment[0]); } Vector2 c; float theta1; float sweepTheta; float adjustedRx; float adjustedRy; ComputeEllipseParameters(p0, p1, rotation, rx, ry, largeArc, sweep, out c, out theta1, out sweepTheta, out adjustedRx, out adjustedRy); var path = ShapeUtils.MakeArc(Vector2.zero, theta1, sweepTheta, 1.0f); var scaling = new Vector2(adjustedRx, adjustedRy); path = ShapeUtils.TransformBezierPath(path, c, rotation, scaling); return(path); }
/// <summary>Builds a BezierContour from a Rectangle.</summary> /// <param name="rect">The rectangle to build the contour from</param> /// <param name="radiusTL">The top-left radius of the rectangle</param> /// <param name="radiusTR">The top-right radius of the rectangle</param> /// <param name="radiusBR">The bottom-right radius of the rectangle</param> /// <param name="radiusBL">The bottom-left radius of the rectangle</param> /// <returns>A BezierContour that follows the rectangle contour</returns> public static BezierContour BuildRectangleContour(Rect rect, Vector2 radiusTL, Vector2 radiusTR, Vector2 radiusBR, Vector2 radiusBL) { var width = rect.size.x; var height = rect.size.y; var halfSize = new Vector2(width / 2.0f, height / 2.0f); radiusTL = Vector2.Max(Vector2.Min(radiusTL, halfSize), Vector2.zero); radiusTR = Vector2.Max(Vector2.Min(radiusTR, halfSize), Vector2.zero); radiusBR = Vector2.Max(Vector2.Min(radiusBR, halfSize), Vector2.zero); radiusBL = Vector2.Max(Vector2.Min(radiusBL, halfSize), Vector2.zero); var leftSegmentSize = height - (radiusBL.y + radiusTL.y); var topSegmentSize = width - (radiusTL.x + radiusTR.x); var rightSegmentSize = height - (radiusBR.y + radiusTR.y); var bottomSegmentSize = width - (radiusBL.x + radiusBR.x); var segments = new List <BezierPathSegment>(8); BezierPathSegment seg; if (leftSegmentSize > ShapeUtils.Epsilon) { seg = MakePathLine(new Vector2(0.0f, radiusTL.y + leftSegmentSize), new Vector2(0.0f, radiusTL.y))[0]; segments.Add(seg); } if (radiusTL.magnitude > ShapeUtils.Epsilon) { var circleArc = ShapeUtils.MakeArc(Vector2.zero, -Mathf.PI, Mathf.PI / 2.0f, 1.0f); circleArc = ShapeUtils.TransformBezierPath(circleArc, radiusTL, 0.0f, radiusTL); segments.Add(circleArc[0]); } if (topSegmentSize > ShapeUtils.Epsilon) { seg = MakePathLine(new Vector2(radiusTL.x, 0.0f), new Vector2(radiusTL.x + topSegmentSize, 0.0f))[0]; segments.Add(seg); } if (radiusTR.magnitude > ShapeUtils.Epsilon) { var topRight = new Vector2(width - radiusTR.x, radiusTR.y); var circleArc = ShapeUtils.MakeArc(Vector2.zero, -Mathf.PI / 2.0f, Mathf.PI / 2.0f, 1.0f); circleArc = ShapeUtils.TransformBezierPath(circleArc, topRight, 0.0f, radiusTR); segments.Add(circleArc[0]); } if (rightSegmentSize > ShapeUtils.Epsilon) { seg = MakePathLine(new Vector2(width, radiusTR.y), new Vector2(width, radiusTR.y + rightSegmentSize))[0]; segments.Add(seg); } if (radiusBR.magnitude > ShapeUtils.Epsilon) { var bottomRight = new Vector2(width - radiusBR.x, height - radiusBR.y); var circleArc = ShapeUtils.MakeArc(Vector2.zero, 0.0f, Mathf.PI / 2.0f, 1.0f); circleArc = ShapeUtils.TransformBezierPath(circleArc, bottomRight, 0.0f, radiusBR); segments.Add(circleArc[0]); } if (bottomSegmentSize > ShapeUtils.Epsilon) { seg = MakePathLine(new Vector2(width - radiusBR.x, height), new Vector2(width - (radiusBR.x + bottomSegmentSize), height))[0]; segments.Add(seg); } if (radiusBL.magnitude > ShapeUtils.Epsilon) { var bottomLeft = new Vector2(radiusBL.x, height - radiusBL.y); var circleArc = ShapeUtils.MakeArc(Vector2.zero, Mathf.PI / 2.0f, Mathf.PI / 2.0f, 1.0f); circleArc = ShapeUtils.TransformBezierPath(circleArc, bottomLeft, 0.0f, radiusBL); segments.Add(circleArc[0]); } // Offset segments to position for (int i = 0; i < segments.Count; ++i) { var s = segments[i]; s.P0 += rect.position; s.P1 += rect.position; s.P2 += rect.position; segments[i] = s; } return(new BezierContour() { Segments = segments.ToArray(), Closed = true }); }