private VoronoiCell FindCircumferencePolygon(Point point, out PointPolygonRelation relation) { for (int i = 0; i < polygons.Count; i++) { VoronoiCell result = GetPolygon(polygons[i].GetHashCode()); PointPolygonRelation tempValue = result.GetRelationTo(point); if (tempValue == PointPolygonRelation.Out) { continue; } else { relation = tempValue; return(result); } } throw new NotImplementedException(); }
public static PointPolygonRelation CalcPointPolygonRelation(double x, double y, IList polygon) { if (polygon.Count < 3) { return(PointPolygonRelation.OutOfPolygon); } IVector start = (IVector)polygon[polygon.Count - 2]; if (start == null) { return(PointPolygonRelation.OutOfPolygon); } IVector middle = (IVector)polygon[polygon.Count - 1]; IVector end; PointPolygonRelation result = PointPolygonRelation.OutOfPolygon; int num = 0; double minX, minY, maxX, maxY; for (int i = 0; i < polygon.Count; i++, start = middle, middle = end) { end = (IVector)polygon[i]; //如果点刚好在顶点上,则直接返回 if ((x == start.X && y == start.Y) || (x == middle.X && y == middle.Y) || (x == end.X && y == end.Y)) { result = PointPolygonRelation.OnPolygonVertex; goto Return; } if (middle.X == end.X && middle.Y == end.Y) { continue; } minX = Math.Min(middle.X, end.X); maxX = Math.Max(middle.X, end.X); //如果X不落在最大X值和最小X值之间,则跳过 if (x > maxX || x < minX) { continue; } minY = Math.Min(middle.Y, end.Y); maxY = Math.Max(middle.Y, end.Y); //如果Y大于最大Y值则跳过,因为向上做射线不可能相交 if (y > maxY) { continue; } if (minX == maxX)//需要判断相交的线段为Y轴平行线 { if (y > minY && y < maxY) { result = PointPolygonRelation.OnPolygonBorder; goto Return; } else if (y < minY)//如果在最小的Y之下,因为目标线段为Y轴平行线,所以记为1次 { num++; } } else { double k = (middle.Y - end.Y) / (middle.X - end.X); double b = middle.Y - k * middle.X; double crossY = k * x + b; if (crossY < y) { continue; //如果交点小于y则跳过,因为我们是向上做射线 } if (crossY == y) { result = PointPolygonRelation.OnPolygonBorder; goto Return; } if (x == maxX || x == minX) { if ((start.X > middle.X && end.X < middle.X) || (start.X < middle.X && end.X > middle.X)) { num++; } } else { num++; } } } if (num % 2 != 0) { result = PointPolygonRelation.InPolygon; } Return: return(result); }