如何判断一个点在多边形内
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何判断一个点在多边形内相关的知识,希望对你有一定的参考价值。
参考技术A 对于凸多边形而言(以三角形ABC为例),假设存在一个点D,若这个点在三角形的内部,则以该点为起点,和原多边形的任意两个连续的且尊照多边形组成方向的点(如DAB、DBC、DCA)组成的三角形讲都是一个方向,如DAB和DBC都是顺时针方向。若这个点在三角形的外部,则会出现DAB、DBC、DCA三个三角形方向不一致的情形,即其中有一个不同于另外两个(如一个顺,两个逆)。到这里我们就知道了如何判断一个点在一个三角形内部的算法,总结一下就是通过判断该点同三角形连续两点组成三角形的顺逆性(归于面积的正负)来得到结果的。
实际上,对于其他的凸多边性也可以用一样的方法,只是这个时候判断的三角形的数目增加了,不管怎么样,只要点在多边形内部他们的顺逆都是一样的。对于凹多边形而言,情况就要相对复杂一些了。此时,判断一个点是否在其内部的计算量会增加比较多。具体算法如下:此时三角形一个个的判断可能会失效,我们应当两个同时判断。即判断该点是否同时在多边形的连续两个三角形之中,相当于是求两个三角形的交集,直到完成多边形封闭。
如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域
文章目录
VS测试代码:test.c(测试传入坐标顺时针、逆时针,发现没啥区别!)
#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
typedef struct
double x, y;
Point;
int InsidePolygon(Point* polygon, int N, Point p)
int counter = 0;
int i;
double xinters;
Point p1, p2;
p1 = polygon[0];
for (i = 1; i <= N; i++)
p2 = polygon[i % N];
if (p.y > MIN(p1.y, p2.y))
//低
if (p.y <= MAX(p1.y, p2.y))
//高
if (p.x <= MAX(p1.x, p2.x))
//右
if (p1.y != p2.y)
//简单忽略平行X轴这种情况
xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//交叉点坐标 参考./media/point-and-polygon/xinters.jpg
if (p1.x == p2.x || p.x <= xinters)
counter++;
p1 = p2;
if (counter % 2 == 0)
return 0;
else
return 1;
int main()
Point points[4] = 0, 1, 3, 0, 3, 4, 0, 3 ; //逆时针闭合图形
Point points[4] = 0, 1, 0, 3, 3, 4, 3, 0 ; //顺时针闭合图形 //测试发现,顺时针和逆时针的结果是相同的
//Point p0 = 0, 0 ; //0 //外
//Point p0 = 0, 1 ; //1 //边界
//Point p0 = 1, 0 ; //0 //外
//Point p0 = 2, 1 ; //1 //内
//Point p0 = 2, 2 ; //1 //内
//Point p0 = 2, 3 ; //1 //内
//Point p0 = 2, 4 ; //0 //外
//Point p0 = 4, 0 ; //0 //外
//Point p0 = -2, -2 ; //0 //外
//Point p0 = -2, 2 ; //0 外
//Point p0 = 2, -2 ; //0 //外
Point p0 = 1, 1 ; //1 //内
printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试
return 0;
测试从外部横向穿越多边形顶点、从内部穿越多边形顶点、穿越水平边的情况
#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
typedef struct
double x, y;
Point;
int InsidePolygon(Point* polygon, int N, Point p)
int counter = 0;
int i;
double xinters;
Point p1, p2;
p1 = polygon[0];
for (i = 1; i <= N; i++)
p2 = polygon[i % N];
if (p.y > MIN(p1.y, p2.y))
//低
if (p.y <= MAX(p1.y, p2.y))
//高
if (p.x <= MAX(p1.x, p2.x))
//右
if (p1.y != p2.y)
//简单忽略平行X轴这种情况
xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//交叉点坐标 参考./media/point-and-polygon/xinters.jpg
if (p1.x == p2.x || p.x <= xinters)
counter++;
p1 = p2;
if (counter % 2 == 0)
return 0;
else
return 1;
int main()
Point points[6] = 0, 1, 1, 2, 0, 3, 3, 3, 5, 4, 3, 0 ;
//0外1内
//Point p0 = 0, 0 ; //从外部横向穿越顶点 //0
//Point p0 = 0, 2 ; //从内部横向穿越顶点 //0
//Point p0 = 2, 2 ; //从内部横向穿越顶点 //1
//Point p0 = -1, 3 ; //横向跨越水平线(在多边形外) //0
Point p0 = 4, 3 ; //横向跨越水平线(在多边形内) //1
printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试
return 0;
测试发现没啥问题,基本正确
VS测试代码:test.c(测试百分比坐标模式)
#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
typedef struct
double x, y;
Point;
int InsidePolygon(Point* polygon, int N, Point p)
int counter = 0;
int i;
double xinters;
Point p1, p2;
p1 = polygon[0];
for (i = 1; i <= N; i++)
p2 = polygon[i % N];
if (p.y > MIN(p1.y, p2.y))
//低
if (p.y <= MAX(p1.y, p2.y))
//高
if (p.x <= MAX(p1.x, p2.x))
//右
if (p1.y != p2.y)
//简单忽略平行X轴这种情况
xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//交叉点坐标 参考./media/point-and-polygon/xinters.jpg
if (p1.x == p2.x || p.x <= xinters)
counter++;
p1 = p2;
if (counter % 2 == 0)
return 0;
else
return 1;
int main()
//Point points[4] = 0, 1, 0, 3, 3, 4, 3, 0;
Point points[4] = 0, 0.25, 0, 0.75, 1, 1, 1, 0 ; //假设总区域是(0, 0)-> (3, 4)
//0外1内
//Point p0 = 0, 0 ;
//Point p0 = 0, 0 ; //0
//Point p0 = 1, 0 ;
//Point p0 = 0.33, 0 ; //0
//Point p0 = 2, 0 ;
//Point p0 = 0.66, 0 ; //0
//Point p0 = 1, 1 ;
//Point p0 = 0.33, 0.25 ; //1
//Point p0 = 1, 2 ;
//Point p0 = 0.33, 0.5 ; //1
//
//Point p0 = 2, 2 ;
//Point p0 = 0.66, 0.5 ; //1
//Point p0 = 1, 3 ;
//Point p0 = 0.33, 0.75 ; //1
//Point p0 = 2, 3 ;
//Point p0 = 0.66, 0.75 ; //1
//Point p0 = 1, 4 ;
//Point p0 = 0.33, 1 ; //0
//Point p0 = 2, 4 ;
//Point p0 = 0.33, 1 ; //0
//
//Point p0 = 3, 5 ;
//Point p0 = 1, 1.25 ; //0
//Point p0 = 4, 0;
Point p0 = 1.33, 0; //0
printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试
return 0;
百分比坐标测试也没有问题
代码原理
主要是射线法
以上是关于如何判断一个点在多边形内的主要内容,如果未能解决你的问题,请参考以下文章
如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域