#include <stdio.h>
#include <stdbool.h>
#include <math.h>
typedef struct {
double x, y;
} Pointxy;
// 计算向量叉积 (p2-p1) × (p3-p1)
static double crossProduct(Pointxy p1, Pointxy p2, Pointxy p3) {
return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
}
// 判断点是否在线段上(考虑浮点数精度)
static bool isPointOnSegment(Pointxy p1, Pointxy p2, Pointxy p) {
// 计算叉积,如果为0则点在线段所在直线上
double cross = crossProduct(p1, p2, p);
if (fabs(cross) > 1e-10) {
return false;
}
// 检查点是否在两个端点之间
double min_x = fmin(p1.x, p2.x);
double max_x = fmax(p1.x, p2.x);
double min_y = fmin(p1.y, p2.y);
double max_y = fmax(p1.y, p2.y);
return (p.x >= min_x - 1e-10 && p.x <= max_x + 1e-10 &&
p.y >= min_y - 1e-10 && p.y <= max_y + 1e-10);
}
// 判断点是否在凸四边形内部
static bool isPointInConvexQuad(Pointxy quad[4], Pointxy p) {
// // 检查点是否在四边形的边界上
// for (int i = 0; i < 4; i++) {
// if (isPointOnSegment(quad[i], quad[(i + 1) % 4], p)) {
// return true;
// }
// }
// 检查点是否在所有边的同一侧(对于凸四边形)
double d1 = crossProduct(quad[0], quad[1], p);
double d2 = crossProduct(quad[1], quad[2], p);
double d3 = crossProduct(quad[2], quad[3], p);
double d4 = crossProduct(quad[3], quad[0], p);
// // 对于凸四边形,所有叉积应该同号(都在内部或都在外部)
// // 我们检查是否都在内部(>0)或都在外部(<0)
bool has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0) || (d4 < 0);
bool has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0) || (d4 > 0);
return !(has_neg && has_pos);
}
// 判断矩形是否在凸四边形内部
static bool isBoxInConvexQuad(Pointxy quad[4], Pointxy boxMin, Pointxy boxMax) {
// 矩形的四个顶点
Pointxy vertices[4] = {
{boxMin.x, boxMin.y},
{boxMin.x, boxMax.y},
{boxMax.x, boxMin.y},
{boxMax.x, boxMax.y}
};
//任何一个在里面,就满足
for (int i = 0; i < 4; i++) {
if (isPointInConvexQuad(quad, vertices[i])) {
return true;
}
}
return false;
// // 检查矩形的每个顶点是否都在四边形内部
// for (int i = 0; i < 4; i++) {
// if (!isPointInConvexQuad(quad, vertices[i])) {
// return false;
// }
// }
// return true;
}
// 定义一个凸四边形(按顺时针或逆时针顺序)
Pointxy quad[4] = {
{10, 10},
{20, 10},
{25, 20},
{ 5, 20}
};
void test_point(Pointxy testPoint){
// Pointxy testPoint = {5, 2};
printf("点 x:%lf,y:%lf ",testPoint.x,testPoint.y);
if (isPointInConvexQuad(quad, testPoint)) {
printf("点在四边形内部\n");
} else {
printf("点不在四边形内部\n");
}
}
void test_box(Pointxy boxMin,Pointxy boxMax){
// Pointxy boxMin = {1, 1};
// Pointxy boxMax = {5, 5};
printf("box x:%lf,y:%lf w:%lf,h:%lf ",boxMin.x,boxMin.y,boxMax.x-boxMin.x,boxMax.y-boxMin.y);
if (isBoxInConvexQuad(quad, boxMin, boxMax)) {
printf("矩形在四边形内部\n");
} else {
printf("矩形不在四边形内部\n");
}
}
// 编译运行 g++ 00_test_box.cpp -o 00_test_box && ./00_test_box
int main() {
// 测试点
printf("\n\ntest 点 外面\n");
//外面
test_point({0,0});
test_point({15,5});
test_point({5,15});
test_point({15,25});
test_point({25,15});
//里面
printf("\n\ntest 点 里面\n");
test_point({15,15});
test_point({11,11});
test_point({10,10});
// 测试矩形
printf("\n\ntest 矩形\n");
test_box({1,1},{5,5});//外
test_box({1,1},{15,15});//里
return 0;
}