Exemple #1
0
        public static void triangulate <T>(Project <T> project, FList <T> poly, FList <TriIdx> result)
        {
            var N = poly.Count;

            result.Clear();
            if (N < 3)
            {
                return;
            }

            result.Capacity = poly.Count - 2;

            if (N == 3)
            {
                result.Add(new TriIdx(0, 1, 2));
                return;
            }

            var vinfo = new vertex_info[N];

            vinfo[0] = new vertex_info(project(poly[0]), 0);
            for (int i = 1; i < N - 1; ++i)
            {
                vinfo[i]          = new vertex_info(project(poly[i]), i);
                vinfo[i].prev     = vinfo[i - 1];
                vinfo[i - 1].next = vinfo[i];
            }
            vinfo[N - 1]      = new vertex_info(project(poly[N - 1]), N - 1);
            vinfo[N - 1].prev = vinfo[N - 2];
            vinfo[N - 1].next = vinfo[0];
            vinfo[0].prev     = vinfo[N - 1];
            vinfo[N - 2].next = vinfo[N - 1];

            for (int i = 0; i < N; ++i)
            {
                vinfo[i].recompute();
            }

            var begin = vinfo[0];

            removeDegeneracies(ref begin, result);

            doTriangulate(begin, result);
        }
Exemple #2
0
 /// <summary>
 /// 全要素を取り除く
 /// </summary>
 public void Clear()
 {
     _List.Clear();
 }
Exemple #3
0
        static bool findDiagonal(vertex_info begin, out vertex_info v1, out vertex_info v2)
        {
            vertex_info t;
            var         heap = new FList <vertex_info>();

            v1 = begin;
            do
            {
                heap.Clear();

                for (v2 = v1.next.next; v2 != v1.prev; v2 = v2.next)
                {
                    if (!internalToAngle(v1.next, v1, v1.prev, v2.p) ||
                        !internalToAngle(v2.next, v2, v2.prev, v1.p))
                    {
                        continue;
                    }

                    PriorityQueue <vertex_info> .PushHeap(heap, v2, new vertex_info_l2norm_inc_ordering(v1));
                }

                while (heap.Count != 0)
                {
                    v2 = PriorityQueue <vertex_info> .PopHeap(heap, new vertex_info_l2norm_inc_ordering(v1));

                    // test whether v1-v2 is a valid diagonal.
                    var v_min_x = Math.Min(v1.p.X, v2.p.X);
                    var v_max_x = Math.Max(v1.p.X, v2.p.X);

                    bool intersected = false;

                    for (t = v1.next; !intersected && t != v1.prev; t = t.next)
                    {
                        vertex_info u = t.next;
                        if (t == v2 || u == v2)
                        {
                            continue;
                        }

                        var l1 = orient2d(v1.p, v2.p, t.p);
                        var l2 = orient2d(v1.p, v2.p, u.p);

                        if ((l1 > 0.0 && l2 > 0.0) || (l1 < 0.0 && l2 < 0.0))
                        {
                            // both on the same side; no intersection
                            continue;
                        }

                        var dx13 = v1.p.X - t.p.X;
                        var dy13 = v1.p.Y - t.p.Y;
                        var dx43 = u.p.X - t.p.X;
                        var dy43 = u.p.Y - t.p.Y;
                        var dx21 = v2.p.X - v1.p.X;
                        var dy21 = v2.p.Y - v1.p.Y;
                        var ua_n = dx43 * dy13 - dy43 * dx13;
                        var ub_n = dx21 * dy13 - dy21 * dx13;
                        var u_d  = dy43 * dx21 - dx43 * dy21;

                        if (Math.Abs(u_d) < element.Epsilon)
                        {
                            // parallel
                            if (Math.Abs(ua_n) < element.Epsilon)
                            {
                                // colinear
                                if (Math.Max(t.p.X, u.p.X) >= v_min_x && Math.Min(t.p.X, u.p.X) <= v_max_x)
                                {
                                    // colinear and intersecting
                                    intersected = true;
                                }
                            }
                        }
                        else
                        {
                            // not parallel
                            var ua = ua_n / u_d;
                            var ub = ub_n / u_d;

                            if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1)
                            {
                                intersected = true;
                            }
                        }
                    }

                    if (!intersected)
                    {
                        // test whether midpoint winding == 1

                        var mid = (v1.p + v2.p) / 2;
                        if (windingNumber(begin, mid) == 1)
                        {
                            // this diagonal is ok
                            return(true);
                        }
                    }
                }

                // couldn't find a diagonal from v1 that was ok.
                v1 = v1.next;
            } while (v1 != begin);
            return(false);
        }