/// <summary> /// 判断点是否在线上 /// </summary> /// <param name="p">点</param> /// <param name="line">线</param> /// <returns>在线上则返回true否则返回false</returns> /// 公式:Point on the Line of the Segment:(P - A)×(B - A) = 0 public static bool PointOnTheLine(Point p, LineSegment line) { if (!Rectangle.PointInRectangle(p, new Rectangle(line))) return false; double cross = Point.CrossProduct(p - line.A, line.B - line.A); return Math.Abs(cross) < Polygon.DeviationValue; }
public Rectangle(LineSegment line) { X = Math.Min(line.A.X, line.B.X); Y = Math.Min(line.A.Y, line.B.Y); Width = Math.Max(line.A.X, line.B.X) - X; Height = Math.Max(line.A.Y, line.B.Y) - Y; }
/// <summary> /// 判断点在线的哪一边 /// </summary> /// <param name="p">点</param> /// <param name="line">线</param> /// <returns>小于0则左边,大于0则右边,等于0则在线上</returns> public static LineSideType PointOnTheLineWhichSide(Point p, LineSegment line) { double cross = Point.CrossProduct(p - line.A, line.B - line.A); bool result = Math.Abs(cross) < Polygon.DeviationValue; if (result) return LineSideType.On; result = cross < 0; if (result) return LineSideType.Left; else return LineSideType.Right; }
/// <summary> /// 判断两条线是否相交 /// </summary> /// <param name="line1">线1</param> /// <param name="line2">线2</param> /// <returns>有相交返回true,否则返回false</returns> public static bool LineSegmentIntersection(LineSegment line1, LineSegment line2) { if (!Rectangle.CheckTwoRectanglesIntersect(new Rectangle(line1), new Rectangle(line2))) return false; LineSideType line1ASideType = PointOnTheLineWhichSide(line1.A, line2); LineSideType line1BSideType = PointOnTheLineWhichSide(line1.B, line2); if (!Check(line1ASideType, line1BSideType)) return false; line1ASideType = PointOnTheLineWhichSide(line2.A, line1); line1BSideType = PointOnTheLineWhichSide(line2.B, line1); if (!Check(line1ASideType, line1BSideType)) return false; return true; }
public static bool PointInTheMaxRectangle(Point p, Polygon polygon) { double maxX = polygon.Points.Max(u => u.X); double minX = polygon.Points.Min(u => u.X); double maxY = polygon.Points.Max(u => u.Y); double minY = polygon.Points.Min(u => u.Y); LineSegment line = new LineSegment(new Point(maxX, maxY), new Point(minX, minY)); Rectangle rec = new Rectangle(line); return Rectangle.PointInRectangle(p, rec); }
private static bool LineSegmentIntersectionInPolygonLine(Point p, Polygon polygon) { int intersectionCount = 0; double maxX = GetMaxPointX(polygon.Points); if (p.X > maxX) { maxX = p.X + 1; } else { maxX += 1; } LineSegment mainLine = new LineSegment(p, new Point(maxX, p.Y)); for (int i = 0, j = 1; j < polygon.Points.Count; i++, j++) { LineSegment line = new LineSegment(polygon.Points[i], polygon.Points[j]); bool result = LineSegment.LineSegmentIntersection(mainLine, line); if (result) intersectionCount++; } LineSegment lastLine = new LineSegment(polygon.Points[polygon.Points.Count - 1], polygon.Points[0]); bool lastResult = LineSegment.LineSegmentIntersection(mainLine, lastLine); if (lastResult) intersectionCount++; if ((intersectionCount % 2) == 0) return false; return true; }
private static bool CheckPointOnPolygonLine(Point p, Polygon polygon) { for (int i = 0, j = 1; j < polygon.Points.Count; i++, j++) { LineSegment line = new LineSegment(polygon.Points[i], polygon.Points[j]); if (LineSegment.PointOnTheLine(p, line)) return true; } LineSegment lastLine = new LineSegment(polygon.Points[polygon.Points.Count - 1], polygon.Points[0]); if (LineSegment.PointOnTheLine(p, lastLine)) return true; return false; }