给定一个多边形和一个点“p”,找出“p”是否位于多边形内部。位于边界上的点也被视为内部点。
例子:
实施步骤:
1.在每个点的右边画一条水平线,并将其延伸到无穷远
2.计算该线与多边形边相交的次数。
3.如果相交数为奇数或点位于多边形的边上,则点位于多边形内部。若没有一个条件是true的,那个么这个点就在外面。
如何处理上图中的点“g”?
注意,如果点位于直线上或与给定多边形的一个顶点相同,则应返回true。为了处理这个问题,在检查从“p”到极值的射线是否相交后,我们检查“p”是否与多边形当前边的顶点共线。如果它是共线的,那么我们检查点“p”是否位于多边形的当前边,如果是,返回true,否则返回false。
实现代码
#include <bits/stdc++.h>
using namespace std;
struct Point {
int x, y;
};
struct line {
Point p1, p2;
};
bool onLine(line l1, Point p)
{
// Check whether p is on the line or not
if (p.x <= max(l1.p1.x, l1.p2.x)
&& p.x >= min(l1.p1.x, l1.p2.x)
&& (p.y <= max(l1.p1.y, l1.p2.y)
&& p.y >= min(l1.p1.y, l1.p2.y)))
return true;
return false;
}
int direction(Point a, Point b, Point c)
{
int val = (b.y - a.y) * (c.x - b.x)
- (b.x - a.x) * (c.y - b.y);
if (val == 0)
// Collinear
return 0;
else if (val < 0)
// Anti-clockwise direction
return 2;
// Clockwise direction
return 1;
}
bool isIntersect(line l1, line l2)
{
// Four direction for two lines and points of other line
int dir1 = direction(l1.p1, l1.p2, l2.p1);
int dir2 = direction(l1.p1, l1.p2, l2.p2);
int dir3 = direction(l2.p1, l2.p2, l1.p1);
int dir4 = direction(l2.p1, l2.p2, l1.p2);
// When intersecting
if (dir1 != dir2 && dir3 != dir4)
return true;
// When p2 of line2 are on the line1
if (dir1 == 0 && onLine(l1, l2.p1))
return true;
// When p1 of line2 are on the line1
if (dir2 == 0 && onLine(l1, l2.p2))
return true;
// When p2 of line1 are on the line2
if (dir3 == 0 && onLine(l2, l1.p1))
return true;
// When p1 of line1 are on the line2
if (dir4 == 0 && onLine(l2, l1.p2))
return true;
return false;
}
bool checkInside(Point poly[], int n, Point p)
{
// When polygon has less than 3 edge, it is not polygon
if (n < 3)
return false;
// Create a point at infinity, y is same as point p
line exline = { p, { 9999, p.y } };
int count = 0;
int i = 0;
do {
// Forming a line from two consecutive points of
// poly
line side = { poly[i], poly[(i + 1) % n] };
if (isIntersect(side, exline)) {
// If side is intersects exline
if (direction(side.p1, p, side.p2) == 0)
return onLine(side, p);
count++;
}
i = (i + 1) % n;
} while (i != 0);
// When count is odd
return count & 1;
}
// Driver code
int main()
{
Point polygon[]
= { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } };
Point p = { 5, 3 };
int n = 4;
// Function call
if (checkInside(polygon, n, p))
cout << "Point is inside.";
else
cout << "Point is outside.";
return 0;
}
输出
Point is inside.
时间复杂度:O(n),其中n是给定多边形中的顶点数。
辅助空间:O(1),因为没有占用额外的空间。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论.
本文内容来源于How to check if a given point lies inside or outside a polygon? - GeeksforGeeks