示例#1
0
        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);
        }