如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域
Posted Dontla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域相关的知识,希望对你有一定的参考价值。
文章目录
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;
百分比坐标测试也没有问题
代码原理
主要是射线法
以上是关于如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域的主要内容,如果未能解决你的问题,请参考以下文章