判断点是否在四边形内

参考网上资料,这里采用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;
}

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是判断坐标是否四边形内的 Python 代码: ```python def is_inside_quad(x, y, quad): """ 判断坐标是否四边形内 参数: x: 待判断的横坐标 y: 待判断的纵坐标 quad: 四边形的四个顶坐标,格式为 [(x1,y1), (x2,y2), (x3,y3), (x4,y4)] 返回值: 如果四边形内,返回 True,否则返回 False """ # 计算四边形边向量及法向量 vectors = [] norms = [] for i in range(len(quad)): j = (i + 1) % len(quad) vector = (quad[j][0] - quad[i][0], quad[j][1] - quad[i][1]) vectors.append(vector) norms.append((vector[1], -vector[0])) # 判断是否四边形内 for i in range(len(norms)): vector = (x - quad[i][0], y - quad[i][1]) if vectors[i][0] * vector[1] - vectors[i][1] * vector[0] < 0: return False if norms[i][0] * vector[1] - norms[i][1] * vector[0] < 0: return False return True ``` 使用示例: ```python # 定义四边形的四个顶坐标 quad = [(1, 1), (5, 2), (6, 6), (2, 5)] # 判断 (3, 3) 是否四边形内 print(is_inside_quad(3, 3, quad)) # 输出 True # 判断 (4, 4) 是否四边形内 print(is_inside_quad(4, 4, quad)) # 输出 True # 判断 (6, 3) 是否四边形内 print(is_inside_quad(6, 3, quad)) # 输出 False # 判断 (0, 0) 是否四边形内 print(is_inside_quad(0, 0, quad)) # 输出 False ``` 注意:这只是一个简单的实现,如果四边形是凸多边形或带孔多边形,可能需要使用更复杂的算法判断是否在多边形内。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值