当前位置:   article > 正文

IOU的C语言快速实现

IOU的C语言快速实现

typedef enum {
    REF_FRONTLEFT = 0,
    REF_FRONTRIGHT,
    REF_REARRIGHT,
    REF_REARLEFT,
    REF_FRONTCENTER,
    REF_RIGHTCENTER,
    REF_REARCENTER,
    REF_LEFTCENTER,
    REF_CENTER,

    REF_POINT_CNT
}EReferencePoint;

typedef struct {
    float x;       
    float y;   
} Point2F;

typedef struct {
    EReferencePoint en_ref_point;
    Point2F xy_point;
}RefPoint_st;

typedef struct {
    u_char_t size;
    Point2F  point_coordinate[10];
}Overlap_Points;

/*!
此部分函数主要是计算矩形相交的面积   备注:将4个点按照时钟序排列(必须是顺时针或者逆时针排序好的)
box1_refpoint  : box1的参考点结构体包含为哪个参考点和其坐标(必须是按照时钟序排列)
\box2_refpoint  : box1的参考点结构体包含为哪个参考点和其坐标(必须是按照时钟序排列)
 box1_points    : box1的四个顶点的坐标(必须是按照时钟序排列)
box2_points    : box2的四个顶点的坐标(必须是按照时钟序排列)
overlap_points : 两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合S和个数的结构体
\return   overlap_area   : 相交的面积
*/
float calcuate_boxes_overlap(RefPoint_st *box1_refpoint, RefPoint_st *box2_refpoint,float *box1_points, float *box2_points, Overlap_Points *overlap_points)
{
    if (box1_refpoint == NULL || box2_refpoint == NULL || box1_points == NULL || box2_points == NULL || overlap_points == NULL)
    {
        return 0.0f;
    }
    float overlap_area = 0.0f;
    whether_rectangles_intersect(box1_refpoint, box2_refpoint, box1_points, box2_points, overlap_points);
    sort_vertex_in_convex_polygon(overlap_points);
    overlap_area = cal_overlap_area(overlap_points);
    return overlap_area;
}

/*!
计算出两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合Soverlap_points : 两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合S和个数的结构体
*/
void whether_rectangles_intersect(RefPoint_st* box1_refpoint, RefPoint_st* box2_refpoint, float* box1_points, float* box2_points, Overlap_Points* overlap_points)
{   
    if (box1_refpoint == NULL || box2_refpoint == NULL || box1_points == NULL || box2_points == NULL || overlap_points == NULL)
    {
        return;
    }
    bool whether_point_in_box = false;
    for (int i = 0; i < 4; i++)
    {
        whether_point_in_box = false;
        whether_point_in_box = point_in_box(box1_refpoint[i].xy_point, box2_points);
        if (whether_point_in_box)
        {
            overlap_points->point_coordinate[overlap_points->size] = box1_refpoint[i].xy_point;
            overlap_points->size++;
        }
    }
    for (int i = 0; i < 4; i++)
    {
        whether_point_in_box = false;
        whether_point_in_box = point_in_box(box2_refpoint[i].xy_point, box1_points);
        if (whether_point_in_box)
        {
            overlap_points->point_coordinate[overlap_points->size] = box2_refpoint[i].xy_point;
            overlap_points->size++;
        }
    }
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            line_segment_intersection(box1_points, box2_points, i, j, overlap_points);
        }
    }
}
 

/*!
对两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合S进行时钟序排序overlap_points : 两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合S和个数的结构体
*/

void sort_vertex_in_convex_polygon(Overlap_Points* overlap_points) 
{
    if (overlap_points == NULL || overlap_points->size > 9)
    {
        return;
    }
    Point2F polygon_center = { 0 };
    if (overlap_points->size > 0)
    {
        for (u_char_t i = 0; i < overlap_points->size; i++)
        {
            polygon_center.x += overlap_points->point_coordinate[i].x;
            polygon_center.y += overlap_points->point_coordinate[i].y;
        }
        polygon_center.x = polygon_center.x/overlap_points->size;
        polygon_center.y = polygon_center.y/overlap_points->size;
        //选择排序
        for (u_char_t i = 0; i < overlap_points->size; i++)
        {
            for (u_char_t j = i + 1; j < overlap_points->size; j++)
            {
                Point2F tmp = { 0 };
                float vx_i = overlap_points->point_coordinate[i].x - polygon_center.x;
                float vy_i = overlap_points->point_coordinate[i].y - polygon_center.y;
                float d_i = sqrtf(vx_i * vx_i + vy_i * vy_i);
                //单位向量
                vx_i = vx_i / d_i;
                vy_i = vy_i / d_i;
                if (vy_i < 0)
                {
                    vx_i = -2 - vx_i;
                }
                float vx_j = overlap_points->point_coordinate[j].x - polygon_center.x;
                float vy_j = overlap_points->point_coordinate[j].y - polygon_center.y;
                float d_j = sqrtf(vx_j * vx_j + vy_j * vy_j);
                vx_j = vx_j / d_j;
                vy_j = vy_j / d_j;
                if (vy_j < 0)
                {
                    vx_j = -2 - vx_j;
                }
                if (vx_i > vx_j)
                {
                    tmp = overlap_points->point_coordinate[i];
                    overlap_points->point_coordinate[i] = overlap_points->point_coordinate[j];
                    overlap_points->point_coordinate[j] = tmp;
                }
            }
        }
    }
}
 

/*!
根据向量的叉积求解面积即可(如找到一个点p,将每一条边都和这个点相连的三角形通过叉积求面积进行加和)
box1_refpoint  : box1的参考点结构体包含为哪个参考点和其坐标(必须是按照时钟序排列)
box2_refpoint  : box1的参考点结构体包含为哪个参考点和其坐标(必须是按照时钟序排列)
box1_points    : box1的四个顶点的坐标(必须是按照时钟序排列)
box2_points    : box2的四个顶点的坐标(必须是按照时钟序排列)
overlap_points : 两个矩形相交的点以及某个矩形的顶点落在另一个矩形内的点集合S和个数的结构体
return    overlap_area   : 相交的面积
*/

float cal_overlap_area(Overlap_Points* overlap_points)
{
    if (overlap_points == NULL || overlap_points->size > 9)
    {
        return 0.0f;
    }
    float area_val = 0.0f;
    if (overlap_points->size > 2)
    {
        Point2F point_a = overlap_points->point_coordinate[0];
        for (u_char_t i = 0; i < (overlap_points->size - 2); i++)
        {
            Point2F point_b = overlap_points->point_coordinate[i + 1];
            Point2F point_c = overlap_points->point_coordinate[i + 2];
            //S= (1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2)
            area_val += fabsf(((point_a.x - point_c.x) * (point_b.y - point_c.y) - (point_a.y - point_c.y) *
                (point_b.x - point_c.x)) / 2.0f);
        }
    }
    return area_val;
}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/613042
推荐阅读
相关标签
  

闽ICP备14008679号