public static CompiledDrawing FromFace(FillFace face) { var fill = new CompiledDrawing(); // Simplify the face by subdividing overlapping curves var newFace = face.SubdivideOverlapping(); // Build the fill polygons and triangulate them fill.Triangles = Triangulator.YMonotone.Triangulate(newFace.Contours.Select(FillPolygon).ToArray()); // Collect all curve triangles var curves = newFace.Contours.SelectMany(v => v.Where(c => c.Type != CurveType.Line)).ToArray(); var curveTriangles = new List <CurveTriangle>(); var doubleCurveTriangles = new List <DoubleCurveTriangle>(); if (curves.Length > 0) { // Check first if the last and first curve aren't joinable bool lastFirstJoin = curves.Length > 1 && FillFace.AreCurvesFusable(curves[curves.Length - 1], curves[0]); if (lastFirstJoin) { doubleCurveTriangles.AddRange(FuseCurveTriangles(curves[curves.Length - 1], curves[0])); } else { curveTriangles.AddRange(CurveVertex.MakeTriangleFan(curves[0].CurveVertices)); } // Now, scan the curve list for pairs of scannable curves var k = lastFirstJoin ? 1 : 0; for (int i = k; i < curves.Length - k; i++) { if (i < curves.Length - 1 && FillFace.AreCurvesFusable(curves[i], curves[i + 1])) { doubleCurveTriangles.AddRange(FuseCurveTriangles(curves[i], curves[i + 1])); i++; } else { curveTriangles.AddRange(CurveVertex.MakeTriangleFan(curves[i].CurveVertices)); } } } fill.CurveTriangles = curveTriangles.ToArray(); fill.DoubleCurveTriangles = doubleCurveTriangles.ToArray(); return(fill); }
private CurveVertex[] EllipticArc_CurveVertices() { // Apply the Loop-Blinn method to get the texture coordinates // Available on https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf // This case is not described in the paper, but it is easily derived // The texture coordinates are actually, x/a, 1 - y/b, 1 + y/b in local space var sign = IsConvex ? 1 : -1; var localPoints = EllipticArc_EnclosingPolygonLocalSpace(); var vertices = new CurveVertex[localPoints.Length]; for (int i = 0; i < localPoints.Length; i++) { var p = localPoints[i]; var kx = p.X / Radii.X; var ky = p.Y / Radii.Y; // Apply the vertex vertices[i] = new CurveVertex(LocalSpaceToGlobal(p), new Double4(kx, 1 - ky, 1 + ky, sign)); } return(vertices); }