参考网上资料,这里采用2种方法判断一个点,是否在四边形内。
方法一:向量积计算法。可以适用于任何形状的四边形,或者多边形;
方法二:面积计算法。只适用于凸四边形,或者凸多边形;
代码如下,分别用2种方法进行判断,看分析结果是否一致。
目前生成随机凸四边形较慢,有需要的话,可以用多个线程生成随机凸四边形,一个或两个线程进行分析。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <float.h>
#include <math.h>
#include <time.h>
/*****************************************************************************
*
* Macro definition
*
*****************************************************************************/
#define equal_zero(x) (fabs(x) < DBL_MIN)
#define two_equal(x1, x2) (fabs((x1) - (x2)) < DBL_MIN)
#define two_not_equal(x1, x2) (fabs((x1) - (x2)) > DBL_MIN)
#define same_sign_2(x1,x2) (((x1) > 0.0 && (x2) > 0.0) || ((x1) < 0.0 && (x2) < 0.0))
#define same_sign_3(x1,x2,x3) (((x1) > 0.0 && (x2) > 0.0 && (x3) > 0.0) || ((x1) < 0.0 && (x2) < 0.0 && (x3) < 0.0))
#define same_sign_4(x1,x2,x3,x4) (((x1) > 0.0 && (x2) > 0.0 && (x3) > 0.0 && (x4) > 0.0) || ((x1) < 0.0 && (x2) < 0.0 && (x3) < 0.0 && (x4) < 0.0))
/*****************************************************************************
*
* Structure/Class definition
*
*****************************************************************************/
//
typedef struct Point {
double x;
double y;
} Point;
/*****************************************************************************
*
* Data definition
*
*****************************************************************************/
/*****************************************************************************
*
* Function Entity
*
*****************************************************************************/
//
// 方法一、向量积判断
//
//
// B C
// ----------------------
// | |
// | .P(px, py) |
// | |
// ----------------------
// A D
//
// 四边形4个点按上图A、B、C、D顺时针填入(也可以逆时针)。务必按顺时针(或者逆时针)输入,不可乱序!!!
// 如果点在顺时针A、B、C、D围城的四边形内,且按函数计算出的4个向量积都大于0,则点在四边形内
// 如果计算出的4个向量积,有1个为0,则说明点在四边形边框上,或延长线上!!!
// 如果计算出的4个向量积,正负不一致,则说明点在四边形外
//
//
// 计算点是否在线段上
//
static int ChkPointOnLine(Point &chk_point, Point &p_start, Point &p_end) {
//
if (p_start.x < chk_point.x && p_end.x < chk_point.x) {
return 0;
}
//
if (p_start.x > chk_point.x && p_end.x > chk_point.x) {
return 0;
}
//
if (p_start.y < chk_point.y && p_end.y < chk_point.y) {
return 0;
}
//
if (p_start.y > chk_point.y && p_end.y > chk_point.y) {
return 0;
}
return 1;
}
//
static int ChkPointInZone_ByCrossProduct(Point &point, Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
double a;
double b;
double c;
double d;
a = (point_b.x - point_a.x) * (point.y - point_a.y) - (point_b.y - point_a.y) * (point.x - point_a.x);
b = (point_c.x - point_b.x) * (point.y - point_b.y) - (point_c.y - point_b.y) * (point.x - point_b.x);
c = (point_d.x - point_c.x) * (point.y - point_c.y) - (point_d.y - point_c.y) * (point.x - point_c.x);
d = (point_a.x - point_d.x) * (point.y - point_d.y) - (point_a.y - point_d.y) * (point.x - point_d.x);
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
//printf("ChkPointInZone - point in quadrangle\n\r");
return 1;
}
if (a == 0) {
//printf("ChkPointInZone - point on line segment ab\n\r");
return ChkPointOnLine(point, point_a, point_b);
}
if (b == 0) {
//printf("ChkPointInZone - point on line segment bc\n\r");
return ChkPointOnLine(point, point_b, point_c);
}
if (c == 0) {
//printf("ChkPointInZone - point on line segment cd\n\r");
return ChkPointOnLine(point, point_c, point_d);
}
if (d == 0) {
//printf("ChkPointInZone - point on line segment da\n\r");
return ChkPointOnLine(point, point_d, point_a);
}
//printf("ChkPointInZone - point out of quadrangle\n\r");
return 0;
}
//
// 方法二、点与四边形构成的三角形面积和,等于四边形面积
//
//
// B C
// ----------------------
// | |
// | .P(px, py) |
// | |
// ----------------------
// A D
//
//
double CalcTriangleArea(Point &point_1, Point &point_2, Point &point_3) {
// S = (x1y2 + x2y3 + x3y1 - x1y3 - x2y1 - x3y2) / 2;
return (fabs(point_1.x * point_2.y + point_2.x * point_3.y + point_3.x * point_1.y - \
point_1.x * point_3.y - point_2.x * point_1.y - point_3.x * point_2.y) / 2.0);
}
//
static int ChkPointInZone_ByArea(Point &point, Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
double polygon_area;
double chk_point_area;
double tmp;
polygon_area = 0.0;
chk_point_area = 0.0;
//
tmp = CalcTriangleArea(point_a, point_b, point_c);
polygon_area += tmp;
tmp = CalcTriangleArea(point_a, point_c, point_d);
polygon_area += tmp;
//
tmp = CalcTriangleArea(point, point_a, point_b);
chk_point_area += tmp;
//printf("chk_point_area - pab = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_b, point_c);
chk_point_area += tmp;
//printf("chk_point_area - pbc = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_c, point_d);
chk_point_area += tmp;
//printf("chk_point_area - pcd = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_d, point_a);
chk_point_area += tmp;
//printf("chk_point_area - pda = %f\r\n", tmp);
//printf("polygon_area = %f\r\n", polygon_area);
//printf("chk_point_area = %f\r\n", chk_point_area);
//
if(two_equal(polygon_area, chk_point_area)) {
return 1;
}
return 0;
}
//
// 以下是生成随机四边形、随机凸四边形
//
//
#define P_MAX (30)
#define P_MIN (5)
void GenerateOnePoint(Point &point) {
//srand((unsigned int)time(NULL));
point.x = rand() % (P_MAX - P_MIN + 1) + P_MIN;
point.y = rand() % (P_MAX - P_MIN + 1) + P_MIN;
}
//
void GenerateQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
GenerateOnePoint(point_a);
do {
GenerateOnePoint(point_b);
} while(two_equal(point_b.x, point_a.x) && two_equal(point_b.y, point_a.y));
do {
GenerateOnePoint(point_c);
} while((two_equal(point_c.x, point_a.x) && two_equal(point_c.y, point_a.y)) ||
(two_equal(point_c.x, point_b.x) && two_equal(point_c.y, point_b.y)));
do {
GenerateOnePoint(point_d);
} while((two_equal(point_d.x, point_a.x) && two_equal(point_d.y, point_a.y)) ||
(two_equal(point_d.x, point_b.x) && two_equal(point_d.y, point_b.y)) ||
(two_equal(point_d.x, point_c.x) && two_equal(point_d.y, point_c.y)));
}
// ConvexQuadrangle,凸四边形
// ConcaveQuadrangle,凹四边形
// 判断凸四边形的方法:
// 1. 面积计算。凸四边形任意顶点,与对角点划分出2个三角形面积和,等于四边形面积。凹四边形,任意顶点,与对角点划分出2个三角形面积和,不一致;
// 2. 向量积。凸四边形,四边依次算向量积,方向一致;凹四边形,四边依次算向量积,会有方向不一致;
int JudgeConvexQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d){
double a;
double b;
double c;
double d;
a = (point_d.x - point_a.x) * (point_b.y - point_a.y) - (point_d.y - point_a.y) * (point_b.x - point_a.x);
b = (point_a.x - point_b.x) * (point_c.y - point_b.y) - (point_a.y - point_b.y) * (point_c.x - point_b.x);
c = (point_b.x - point_c.x) * (point_d.y - point_c.y) - (point_b.y - point_c.y) * (point_d.x - point_c.x);
d = (point_c.x - point_d.x) * (point_a.y - point_d.y) - (point_c.y - point_d.y) * (point_a.x - point_d.x);
//printf("JudgeConvexQuadrangle - %f, %f, %f, %f\r\n", a, b, c, d);
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
//printf("JudgeConvexQuadrangle - Convex Quadrangle\n\r");
return 1;
}
return 0;
}
//
void GenerateConvexQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
do {
GenerateQuadrangle(point_a, point_b, point_c, point_d);
} while(!JudgeConvexQuadrangle(point_a, point_b, point_c, point_d));
}
int main(int argc, char **argv) {
int i;
int j;
Point p_test;
Point p_a;
Point p_b;
Point p_c;
Point p_d;
int rtn_cross_product;
int rtn_area;
Point Quadrangle[3][4] = {
{{1.0, 1.0}, {1.0, 2.0}, {4.0, 2.0}, {4.0, 1.0}}, // 矩形
{{1.0, 2.0}, {2.0, 4.0}, {5.0, 3.0}, {3.0, 1.0}}, // 凸四边形
{{1.0, 1.0}, {3.0, 6.0}, {7.0, 0.5}, {4.0, 3.0}} // 凹四边形
};
srand((unsigned int)time(NULL));
/*
// 用给定的四边形进行测试
for (i = 0; i < 0x7fffffff; ++ i) {
p_test.x = rand() % 9;
p_test.y = rand() % 9;
for (j = 0; j < 2; ++ j) {
rtn_cross_product = ChkPointInZone_ByCrossProduct(p_test,
Quadrangle[j][0], Quadrangle[j][1], Quadrangle[j][2], Quadrangle[j][3]);
rtn_area = ChkPointInZone_ByArea(p_test,
Quadrangle[j][0], Quadrangle[j][1], Quadrangle[j][2], Quadrangle[j][3]);
if (rtn_area != rtn_cross_product) {
printf("Quadrangle index = %d, test(x,y) = (%f, %f), product rtn = %d, area rtn = %d\r\n", j, p_test.x, p_test.y, rtn_cross_product, rtn_area);
}
//printf("rtn_cross_product = %d, rtn_area = %d\r\n", rtn_cross_product, rtn_area);
}
}
printf("given polygon test over\r\n");
*/
// 随机生成凸四边形进行测试
for (i = 0; i < 100; ++ i) {
p_test.x = rand() % 40;
p_test.y = rand() % 40;
GenerateConvexQuadrangle(p_a, p_b, p_c, p_d);
rtn_cross_product = ChkPointInZone_ByCrossProduct(p_test, p_a, p_b, p_c, p_d);
rtn_area = ChkPointInZone_ByArea(p_test, p_a, p_b, p_c, p_d);
if (rtn_area != rtn_cross_product) {
printf("test(x,y) = (%f, %f), quadrangle = (%f, %f), (%f, %f), (%f, %f), (%f, %f), product rtn = %d, area rtn = %d\r\n",
p_test.x, p_test.y, p_a.x, p_a.y, p_b.x, p_b.y, p_c.x, p_c.y, p_d.x, p_d.y, rtn_cross_product, rtn_area);
}
//printf("rtn_cross_product = %d, rtn_area = %d\r\n", rtn_cross_product, rtn_area);
}
printf("rand polygon test over\r\n");
}
多线程测试版本,线程数量根据自己电脑CPU核数进行调整,默认10。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <float.h>
#include <math.h>
#include <time.h>
/*****************************************************************************
*
* Macro definition
*
*****************************************************************************/
#define equal_zero(x) (fabs(x) < DBL_MIN)
#define two_equal(x1, x2) (fabs((x1) - (x2)) < DBL_MIN)
#define two_not_equal(x1, x2) (fabs((x1) - (x2)) > DBL_MIN)
#define same_sign_2(x1,x2) (((x1) > 0.0 && (x2) > 0.0) || ((x1) < 0.0 && (x2) < 0.0))
#define same_sign_3(x1,x2,x3) (((x1) > 0.0 && (x2) > 0.0 && (x3) > 0.0) || ((x1) < 0.0 && (x2) < 0.0 && (x3) < 0.0))
#define same_sign_4(x1,x2,x3,x4) (((x1) > 0.0 && (x2) > 0.0 && (x3) > 0.0 && (x4) > 0.0) || ((x1) < 0.0 && (x2) < 0.0 && (x3) < 0.0 && (x4) < 0.0))
/*****************************************************************************
*
* Structure/Class definition
*
*****************************************************************************/
//
typedef struct Point {
double x;
double y;
} Point;
/*****************************************************************************
*
* Data definition
*
*****************************************************************************/
/*****************************************************************************
*
* Function Entity
*
*****************************************************************************/
//
// 方法一、向量积判断
//
//
// B C
// ----------------------
// | |
// | .P(px, py) |
// | |
// ----------------------
// A D
//
// 四边形4个点按上图A、B、C、D顺时针填入(也可以逆时针)。务必按顺时针(或者逆时针)输入,不可乱序!!!
// 如果点在顺时针A、B、C、D围城的四边形内,且按函数计算出的4个向量积都大于0,则点在四边形内
// 如果计算出的4个向量积,有1个为0,则说明点在四边形边框上,或延长线上!!!
// 如果计算出的4个向量积,正负不一致,则说明点在四边形外
//
//
// 计算点是否在线段上
//
static int ChkPointOnLine(Point &chk_point, Point &p_start, Point &p_end) {
//
if (p_start.x < chk_point.x && p_end.x < chk_point.x) {
return 0;
}
//
if (p_start.x > chk_point.x && p_end.x > chk_point.x) {
return 0;
}
//
if (p_start.y < chk_point.y && p_end.y < chk_point.y) {
return 0;
}
//
if (p_start.y > chk_point.y && p_end.y > chk_point.y) {
return 0;
}
return 1;
}
//
static int ChkPointInZone_ByCrossProduct(Point &point, Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
double a;
double b;
double c;
double d;
a = (point_b.x - point_a.x) * (point.y - point_a.y) - (point_b.y - point_a.y) * (point.x - point_a.x);
b = (point_c.x - point_b.x) * (point.y - point_b.y) - (point_c.y - point_b.y) * (point.x - point_b.x);
c = (point_d.x - point_c.x) * (point.y - point_c.y) - (point_d.y - point_c.y) * (point.x - point_c.x);
d = (point_a.x - point_d.x) * (point.y - point_d.y) - (point_a.y - point_d.y) * (point.x - point_d.x);
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
//printf("ChkPointInZone - point in quadrangle\n\r");
return 1;
}
if (a == 0) {
//printf("ChkPointInZone - point on line segment ab\n\r");
return ChkPointOnLine(point, point_a, point_b);
}
if (b == 0) {
//printf("ChkPointInZone - point on line segment bc\n\r");
return ChkPointOnLine(point, point_b, point_c);
}
if (c == 0) {
//printf("ChkPointInZone - point on line segment cd\n\r");
return ChkPointOnLine(point, point_c, point_d);
}
if (d == 0) {
//printf("ChkPointInZone - point on line segment da\n\r");
return ChkPointOnLine(point, point_d, point_a);
}
//printf("ChkPointInZone - point out of quadrangle\n\r");
return 0;
}
//
// 方法二、点与四边形构成的三角形面积和,等于四边形面积
//
//
// B C
// ----------------------
// | |
// | .P(px, py) |
// | |
// ----------------------
// A D
//
//
double CalcTriangleArea(Point &point_1, Point &point_2, Point &point_3) {
// S = (x1y2 + x2y3 + x3y1 - x1y3 - x2y1 - x3y2) / 2;
return (fabs(point_1.x * point_2.y + point_2.x * point_3.y + point_3.x * point_1.y - \
point_1.x * point_3.y - point_2.x * point_1.y - point_3.x * point_2.y) / 2.0);
}
//
static int ChkPointInZone_ByArea(Point &point, Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
double polygon_area;
double chk_point_area;
double tmp;
polygon_area = 0.0;
chk_point_area = 0.0;
//
tmp = CalcTriangleArea(point_a, point_b, point_c);
polygon_area += tmp;
tmp = CalcTriangleArea(point_a, point_c, point_d);
polygon_area += tmp;
//
tmp = CalcTriangleArea(point, point_a, point_b);
chk_point_area += tmp;
//printf("chk_point_area - pab = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_b, point_c);
chk_point_area += tmp;
//printf("chk_point_area - pbc = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_c, point_d);
chk_point_area += tmp;
//printf("chk_point_area - pcd = %f\r\n", tmp);
tmp = CalcTriangleArea(point, point_d, point_a);
chk_point_area += tmp;
//printf("chk_point_area - pda = %f\r\n", tmp);
//printf("polygon_area = %f\r\n", polygon_area);
//printf("chk_point_area = %f\r\n", chk_point_area);
//
if(two_equal(polygon_area, chk_point_area)) {
return 1;
}
return 0;
}
//
// 以下是生成随机四边形、随机凸四边形
//
//
#define P_MAX (30)
#define P_MIN (5)
void GenerateOnePoint(Point &point) {
//srand((unsigned int)time(NULL));
point.x = rand() % (P_MAX - P_MIN + 1) + P_MIN;
point.y = rand() % (P_MAX - P_MIN + 1) + P_MIN;
}
//
void GenerateQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
GenerateOnePoint(point_a);
do {
GenerateOnePoint(point_b);
} while(two_equal(point_b.x, point_a.x) && two_equal(point_b.y, point_a.y));
do {
GenerateOnePoint(point_c);
} while((two_equal(point_c.x, point_a.x) && two_equal(point_c.y, point_a.y)) ||
(two_equal(point_c.x, point_b.x) && two_equal(point_c.y, point_b.y)));
do {
GenerateOnePoint(point_d);
} while((two_equal(point_d.x, point_a.x) && two_equal(point_d.y, point_a.y)) ||
(two_equal(point_d.x, point_b.x) && two_equal(point_d.y, point_b.y)) ||
(two_equal(point_d.x, point_c.x) && two_equal(point_d.y, point_c.y)));
}
// ConvexQuadrangle,凸四边形
// ConcaveQuadrangle,凹四边形
// 判断凸四边形的方法:
// 1. 面积计算。凸四边形任意顶点,与对角点划分出2个三角形面积和,等于四边形面积。凹四边形,任意顶点,与对角点划分出2个三角形面积和,不一致;
// 2. 向量积。凸四边形,四边依次算向量积,方向一致;凹四边形,四边依次算向量积,会有方向不一致;
int JudgeConvexQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d){
double a;
double b;
double c;
double d;
a = (point_d.x - point_a.x) * (point_b.y - point_a.y) - (point_d.y - point_a.y) * (point_b.x - point_a.x);
b = (point_a.x - point_b.x) * (point_c.y - point_b.y) - (point_a.y - point_b.y) * (point_c.x - point_b.x);
c = (point_b.x - point_c.x) * (point_d.y - point_c.y) - (point_b.y - point_c.y) * (point_d.x - point_c.x);
d = (point_c.x - point_d.x) * (point_a.y - point_d.y) - (point_c.y - point_d.y) * (point_a.x - point_d.x);
//printf("JudgeConvexQuadrangle - %f, %f, %f, %f\r\n", a, b, c, d);
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
//printf("JudgeConvexQuadrangle - Convex Quadrangle\n\r");
return 1;
}
return 0;
}
//
void GenerateConvexQuadrangle(Point &point_a, Point &point_b, Point &point_c, Point &point_d) {
do {
GenerateQuadrangle(point_a, point_b, point_c, point_d);
} while(!JudgeConvexQuadrangle(point_a, point_b, point_c, point_d));
}
#include <pthread.h>
#include <list>
//
typedef struct ConvexQuadrangle {
Point a;
Point b;
Point c;
Point d;
} ConvexQuadrangle;
//
static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t data_lock = PTHREAD_MUTEX_INITIALIZER;
static std::list<ConvexQuadrangle> quadrangle_list;
//
static int StartThread(void *(*thread_entry)(void *), void *thread_para) {
int rtn;
pthread_attr_t thread_attr;
pthread_t thread_ID;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
rtn = pthread_create(&thread_ID, &thread_attr, thread_entry, thread_para);
return rtn;
}
//
void *ThreadGenerateConvexQuadrangle(void *para) {
ConvexQuadrangle convex_quadrangle;
while (1) {
//
GenerateConvexQuadrangle(convex_quadrangle.a, convex_quadrangle.b, convex_quadrangle.c, convex_quadrangle.d);
//
pthread_mutex_lock(&data_lock);
//
if (quadrangle_list.size() > 1000) {
pthread_mutex_unlock(&data_lock);
usleep(100000);
continue;
}
quadrangle_list.push_back(convex_quadrangle);
pthread_cond_signal(&data_ready);
pthread_mutex_unlock(&data_lock);
}
return NULL;
}
//
int main(int argc, char **argv) {
int i;
Point p_test;
ConvexQuadrangle convex_quadrangle;
int rtn_cross_product;
int rtn_area;
//
srand((unsigned int)time(NULL));
//
for (i = 0; i < 10; ++ i) {
StartThread(ThreadGenerateConvexQuadrangle, NULL);
}
// 随机生成凸四边形进行测试
for (i = 0; i < 10; ++ i) {
pthread_mutex_lock(&data_lock);
while (0 == quadrangle_list.size()) {
pthread_cond_wait(&data_ready, &data_lock);
}
//
convex_quadrangle = quadrangle_list.front();
quadrangle_list.pop_front();
pthread_mutex_unlock(&data_lock);
printf("convex_quadrangle - (%f, %f), (%f, %f), (%f, %f), (%f, %f)\n\r",
convex_quadrangle.a.x, convex_quadrangle.a.y,
convex_quadrangle.b.x, convex_quadrangle.b.y,
convex_quadrangle.c.x, convex_quadrangle.c.y,
convex_quadrangle.d.x, convex_quadrangle.d.y);
//
p_test.x = rand() % 40;
p_test.y = rand() % 40;
//
rtn_cross_product = ChkPointInZone_ByCrossProduct(p_test, convex_quadrangle.a, convex_quadrangle.b, convex_quadrangle.c, convex_quadrangle.d);
rtn_area = ChkPointInZone_ByArea(p_test, convex_quadrangle.a, convex_quadrangle.b, convex_quadrangle.c, convex_quadrangle.d);
//
if (rtn_area != rtn_cross_product) {
printf("test(x,y) = (%f, %f), quadrangle = (%f, %f), (%f, %f), (%f, %f), (%f, %f), product rtn = %d, area rtn = %d\r\n",
p_test.x, p_test.y,
convex_quadrangle.a.x, convex_quadrangle.a.y,
convex_quadrangle.b.x, convex_quadrangle.b.y,
convex_quadrangle.c.x, convex_quadrangle.c.y,
convex_quadrangle.d.x, convex_quadrangle.d.y, rtn_cross_product, rtn_area);
}
//printf("rtn_cross_product = %d, rtn_area = %d\r\n", rtn_cross_product, rtn_area);
}
printf("rand polygon test over\r\n");
}
ChatGPT生成的代码,支持凸多边形、凹多边形:
#include <stdio.h>
// 定义二维坐标结构体
typedef struct {
double x;
double y;
} Point;
// 判断点是否在多边形内
int is_point_in_polygon(Point point, Point polygon[], int n) {
int i, j;
int is_inside = 0;
for (i = 0, j = n-1; i < n; j = i++) {
// 判断点是否在多边形的边界上
if ((polygon[i].y == point.y && polygon[i].x == point.x) ||
(polygon[j].y == point.y && polygon[j].x == point.x)) {
return 1;
}
// 判断点是否在多边形的边上
if ((polygon[i].y == point.y && polygon[j].y == point.y &&
((polygon[i].x <= point.x && point.x <= polygon[j].x) ||
(polygon[j].x <= point.x && point.x <= polygon[i].x))) ||
(polygon[i].x == point.x && polygon[j].x == point.x &&
((polygon[i].y <= point.y && point.y <= polygon[j].y) ||
(polygon[j].y <= point.y && point.y <= polygon[i].y)))) {
return 1;
}
// 判断点是否在多边形内部
if (((polygon[i].y > point.y) != (polygon[j].y > point.y)) &&
(point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
is_inside = !is_inside;
}
}
return is_inside;
}
int main() {
Point point = { 1.0, 1.0 }; // 待判断的点
Point polygon[] = { { 0.0, 0.0 }, { 2.0, 0.0 }, { 2.0, 2.0 }, { 0.0, 2.0 } }; // 多边形的顶点
int n = sizeof(polygon) / sizeof(Point); // 多边形的顶点数
// 判断点是否在多边形内
if (is_point_in_polygon(point, polygon, n)) {
printf("点 (%.1f, %.1f) 在多边形内\n", point.x, point.y);
} else {
printf("点 (%.1f, %.1f) 不在多边形内\n", point.x, point.y);
}
return 0;
}