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; } } } } }