예제 #1
0
        public Edge Locate(Vector2 point, Edge edgeHint)
        {
            var e = edgeHint;
            var t = GeometryHelpers.TriArea(point, e.Dest, e.Orig);

            //  DPrev------>d----->RPrev
            //              ^
            //              |
            //             e|     .P
            //              |
            //  ONext<------o<-----RNext
            // point is to the right of e
            if (t > 0)
            {
                // Switch search to the left side
                t *= -1;
                e  = e.Sym;
            }

            while (true)
            {
                var eo = e.ONext;
                var ed = e.DPrev;

                // Notice that we're reversing the point order
                // this tests that the point is TO THE RIGHT OF the edge
                var to = GeometryHelpers.TriArea(point, eo.Dest, eo.Orig);
                var td = GeometryHelpers.TriArea(point, ed.Dest, ed.Orig);

                // point is below ed (to the right of ed)
                if (td > 0)
                {
                    // point is to the right of eo (interior)
                    // or is e.Orig
                    if (to > 0 || (to == 0 && t == 0))
                    {
                        //  DPrev------>d----->RPrev
                        //              ^
                        //              |
                        //    .P       e|
                        //              |
                        //  ONext<------o<-----RNext
                        startingEdge = e;
                        return(e);
                    }
                    else
                    {
                        // point is below ed and below eo
                        // move the search to eo
                        //  DPrev------>d----->RPrev
                        //              ^
                        //              |
                        //             e|
                        //              |
                        //  ONext<------o<-----RNext
                        //          .P
                        t = to;
                        e = eo;
                    }
                }
                else
                {
                    // point is on or above ed
                    // point is above eo
                    if (to > 0)
                    {
                        // point is e.Dest
                        if (td == 0 && t == 0)
                        {
                            startingEdge = e;
                            return(e);
                        }
                        else
                        {
                            // point is above eo and above ed
                            // move the search to ed
                            //          .P
                            //  DPrev------>d----->RPrev
                            //              ^
                            //              |
                            //             e|
                            //              |
                            //  ONext<------o<-----RNext
                            t = td;
                            e = ed;
                        }
                    }
                    else
                    {
                        // point is on or to the left of eo
                        // point is on e, but the subdivision is to the right
                        if (t == 0 && !Edge.IsLeftOf(eo.Dest, e))
                        {
                            e = e.Sym;
                        }

                        // point is on or above ed and on or below eo (what the ...)
                        // step randomly
                        else if ((rand.Next() & 1) > 0)
                        {
                            t = to;
                            e = eo;
                        }
                        else
                        {
                            t = td;
                            e = ed;
                        }
                    }
                }
            }
        }