c语言判断某个点是否在凸四边形内部,边界范围用


#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;
}
posted @ 2025-12-03 15:33  小城熊儿  阅读(0)  评论(0)    收藏  举报