Exemple #1
0
        private static IEnumerable <DoubleCurveTriangle> FuseCurveTriangles(Curve c1, Curve c2)
        {
            // Extract the curve vertices
            var t1 = c1.CurveVertices;
            var t2 = c2.CurveVertices;

            // Pick their extrapolators
            var ext1 = CoordExtrapolator(t1);
            var ext2 = CoordExtrapolator(t2);

            // Now, we are going to pick the convex hull of the polygon
            var hull = GeometricUtils.ConvexHull(t1.Concat(t2).Select(v => v.Position).ToArray());

            // Finally, calculate the new texture coordinates
            var vertices = hull.Select(p => new DoubleCurveVertex(p, ext1(p), ext2(p)));

            // And return the triangle
            return(DoubleCurveVertex.MakeTriangleFan(vertices.ToArray()));
        }
Exemple #2
0
        private static Double2[] FillPolygon(Curve[] contour)
        {
            // "Guess" a capacity for the list, add the first point
            var list = new List <Double2>((int)(1.4 * contour.Length));

            // Check first if the last and first curve aren't joinable
            bool lastFirstJoin = FillFace.AreCurvesFusable(contour[contour.Length - 1], contour[0]);

            if (lastFirstJoin)
            {
                list.Add(contour[0].At(1));
            }

            // Now, scan the curve list for pairs of scannable curves
            var k = lastFirstJoin ? 1 : 0;

            for (int i = k; i < contour.Length - k; i++)
            {
                if (i < contour.Length - 1 && FillFace.AreCurvesFusable(contour[i], contour[i + 1]))
                {
                    // If they describe a positive winding on the plane, add only its endpoint
                    var endp0 = contour[i].At(0);
                    var endp1 = contour[i + 1].At(1);
                    var pth   = (endp0 + endp1) / 2;
                    if (contour[i].WindingRelativeTo(pth) + contour[i + 1].WindingRelativeTo(pth) > 0)
                    {
                        list.Add(endp1);
                    }
                    else
                    {
                        // Else, compute the convex hull and add the correct point sequence
                        var points = contour[i].EnclosingPolygon.Concat(contour[i + 1].EnclosingPolygon).ToArray();
                        var hull   = GeometricUtils.ConvexHull(points);
                        var hl     = hull.Length;

                        // We have to go through the hull clockwise. Find the first point
                        int ik;
                        for (ik = 0; ik < hl; ik++)
                        {
                            if (hull[ik] == endp0)
                            {
                                break;
                            }
                        }

                        // And run through it
                        for (int i0 = ik; i0 != (ik + 1) % hl; i0 = (i0 + hl - 1) % hl)
                        {
                            list.Add(hull[i0]);
                        }
                    }
                    i++;
                }
                else if (contour[i].Type == CurveType.Line || contour[i].IsConvex)
                {
                    list.Add(contour[i].At(1));
                }
                else
                {
                    list.AddRange(contour[i].EnclosingPolygon.Skip(1));
                }
            }

            // Sanitize the list; identical vertices
            var indices = new List <int>();

            for (int i = 0; i < list.Count; i++)
            {
                if (DoubleUtils.RoughlyEquals(list[i], list[(i + 1) % list.Count]))
                {
                    indices.Add(i);
                }
            }

            list.ExtractIndices(indices.ToArray());
            return(list.ToArray());
        }