//一个c#程序,用来检查一个给定的点
//位于给定多边形内
// 引用https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/
//对于函数onSegment()的解释
//定位()和doIntersect()
using System;
namespace CadForJP
{
public class Point
{
public double x;
public double y;
public Point(double x, double y)
{
this.x = x;
this.y = y;
}
};
public static class AR
{
// Define Infinite (Using INT_MAX
// caused overflow problems)
static int INF = 10000;
// 已知三个共线点p q r,
// 这个函数检查点q是否存在线pr上
static bool onSegment(Point p, Point q, Point r)
{
if (q.x <= Math.Max(p.x, r.x) &&
q.x >= Math.Min(p.x, r.x) &&
q.y <= Math.Max(p.y, r.y) &&
q.y >= Math.Min(p.y, r.y))
{
return true;
}
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
static double orientation(Point p, Point q, Point r)
{
double val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0)
{
return 0; // collinear
}
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
//返回true的函数
//线段p1q1与p2q2相交。
static bool doIntersect(Point p1, Point q1,
Point p2, Point q2)
{
// Find the four orientations needed for
// general and special cases
double o1 = orientation(p1, q1, p2);
double o2 = orientation(p1, q1, q2);
double o3 = orientation(p2, q2, p1);
double o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
{
return true;
}
// Special Cases
// p1, q1 and p2 are collinear and
// p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1))
{
return true;
}
// p1, q1 and p2 are collinear and
// q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1))
{
return true;
}
// p2, q2 and p1 are collinear and
// p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2))
{
return true;
}
// p2, q2 and q1 are collinear and
// q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2))
{
return true;
}
// Doesn't fall in any of the above cases
return false;
}
//如果点p在,则返回true
//在n个顶点的多边形[]内
public static bool isInside(Point[] polygon, int n, Point p)
{
// There must be at least 3 vertices in polygon[]
if (n < 3)
{
return false;
}
// Create a point for line segment from p to infinite
Point extreme = new Point(INF, p.y);
// Count intersections of the above line
// with sides of polygon
int count = 0, i = 0;
do
{
int next = (i + 1) % n;
// Check if the line segment from 'p' to
// 'extreme' intersects with the line
// segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect(polygon[i],
polygon[next], p, extreme))
{
// If the point 'p' is collinear with line
// segment 'i-next', then check if it lies
// on segment. If it lies, return true, otherwise false
if (orientation(polygon[i], p, polygon[next]) == 0)
{
return onSegment(polygon[i], p,
polygon[next]);
}
count++;
}
i = next;
} while (i != 0);
// Return true if count is odd, false otherwise
return (count % 2 == 1); // Same as (count%2 == 1)
}
// Driver Code
public static void Main(String[] args)
{
Point[] polygon1 = {new Point(0, 0),
new Point(10, 0),
new Point(10, 10),
new Point(0, 10)};
int n = polygon1.Length;
Point p = new Point(20, 20);
if (isInside(polygon1, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
p = new Point(5, 5);
if (isInside(polygon1, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
Point[] polygon2 = {new Point(0, 0),
new Point(5, 5),
new Point(5, 0)};
p = new Point(3, 3);
n = polygon2.Length;
if (isInside(polygon2, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
p = new Point(5, 1);
if (isInside(polygon2, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
p = new Point(8, 1);
if (isInside(polygon2, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
Point[] polygon3 = {new Point(0, 0),
new Point(10, 0),
new Point(10, 10),
new Point(0, 10)};
p = new Point(-1, 10);
n = polygon3.Length;
if (isInside(polygon3, n, p))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
}
// This code is contributed by 29AjayKumar
【CAD二次开发】如何判断一个点是否在多段线内
最新推荐文章于 2024-01-31 14:26:42 发布