private static PointClassification ClassifyX(this PointX p, SegmentX s) { var a = s.End - s.Start; var b = p - s.Start; double sa = a.X * b.Y - b.X * a.Y; if (sa > 0.0) { return(PointClassification.LEFT); } if (sa < 0.0) { return(PointClassification.RIGHT); } if ((a.X * b.X < 0.0) || (a.Y * b.Y < 0.0)) { return(PointClassification.BEHIND); } if (a.Length2 < b.Length2) { return(PointClassification.BEYOND); } if (s.Start.Equals(p)) { return(PointClassification.ORIGIN); } if (s.End.Equals(p)) { return(PointClassification.DESTINATION); } return(PointClassification.BETWEEN); }
private static PointToPolygonPositionType GetPositionToPolygon(this PointX p, PolygonX polygon) { var parity = true; for (var i = 0; i < polygon.Vertices.Length; i++) { var v1 = polygon.Vertices[i]; var v2 = polygon.Vertices[(i + 1) % polygon.Vertices.Length]; var segment = new SegmentX(v1, v2); switch (ClassifyEdgeX(p, segment)) { case EdgeType.TOUCHING: return(PointToPolygonPositionType.Boundary); case EdgeType.CROSSING: parity = !parity; break; } } return(parity ? PointToPolygonPositionType.Outside : PointToPolygonPositionType.Inside); }
private static EdgeType ClassifyEdgeX(PointX a, SegmentX e) { var v = e.Start; var w = e.End; switch (a.ClassifyX(e)) { case PointClassification.LEFT: return(((v.Y < a.Y) && (a.Y <= w.Y)) ? EdgeType.CROSSING : EdgeType.INESSENTIAL); case PointClassification.RIGHT: return(((w.Y < a.Y) && (a.Y <= v.Y)) ? EdgeType.CROSSING : EdgeType.INESSENTIAL); case PointClassification.BETWEEN: case PointClassification.ORIGIN: case PointClassification.DESTINATION: return(EdgeType.TOUCHING); default: return(EdgeType.INESSENTIAL); } }