吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 546|回复: 6
收起左侧

[求助] IOU求重叠面积函数,部分代码不太理解 求助

[复制链接]
benson0308 发表于 2023-12-7 13:49
本帖最后由 benson0308 于 2023-12-7 13:54 编辑

源代码:

%%%%%%%%%%%%%%%%%%%%%
%{

        *函 数 名:is_overlap

        *功能描述: 判断两个库位是否匹配,即是否为同一库位

        *输入参数:  Slot1       - 全局坐标系下的库位1

        *          Slot2        - 全局坐标系下的库位1

        *          threshold    - 判断是否重叠的阈值,0-1,值越大代表重叠度越高,1代表完全重叠

        *输出参数: ret
               0 - Slot1和Slot2不匹配
               1 - Slot1和Slot2匹配
%}
function ret=is_overlap(Slot1, Slot2, threshold)
point.x=single(0);
point.y=single(0);
pt_Slot1=repmat(point,4,1);
pt_Slot2=repmat(point,4,1);

Slot1.p0_x = (round(Slot1.p0_x*10000))./10000;
Slot1.p0_y = (round(Slot1.p0_y*10000))./10000;
Slot1.p1_x = (round(Slot1.p1_x*10000))./10000;
Slot1.p1_y = (round(Slot1.p1_y*10000))./10000;
Slot1.p2_x = (round(Slot1.p2_x*10000))./10000;
Slot1.p2_y = (round(Slot1.p2_y*10000))./10000;
Slot1.p3_x = (round(Slot1.p3_x*10000))./10000;
Slot1.p3_y = (round(Slot1.p3_y*10000))./10000;

pt_Slot1(1).x=Slot1.p0_x;pt_Slot1(1).y=Slot1.p0_y;
pt_Slot1(2).x=Slot1.p1_x;pt_Slot1(2).y=Slot1.p1_y;
pt_Slot1(3).x=Slot1.p2_x;pt_Slot1(3).y=Slot1.p2_y;
pt_Slot1(4).x=Slot1.p3_x;pt_Slot1(4).y=Slot1.p3_y;
pt_Slot1_PN = length(pt_Slot1);

Slot2.p0_x = (round(Slot2.p0_x*10000))./10000;
Slot2.p0_y = (round(Slot2.p0_y*10000))./10000;
Slot2.p1_x = (round(Slot2.p1_x*10000))./10000;
Slot2.p1_y = (round(Slot2.p1_y*10000))./10000;
Slot2.p2_x = (round(Slot2.p2_x*10000))./10000;
Slot2.p2_y = (round(Slot2.p2_y*10000))./10000;
Slot2.p3_x = (round(Slot2.p3_x*10000))./10000;
Slot2.p3_y = (round(Slot2.p3_y*10000))./10000;


pt_Slot2(1).x=Slot2.p0_x;pt_Slot2(1).y=Slot2.p0_y;
pt_Slot2(2).x=Slot2.p1_x;pt_Slot2(2).y=Slot2.p1_y;
pt_Slot2(3).x=Slot2.p2_x;pt_Slot2(3).y=Slot2.p2_y;
pt_Slot2(4).x=Slot2.p3_x;pt_Slot2(4).y=Slot2.p3_y;
pt_Slot2_PN = length(pt_Slot2);

p0_sqrt = sqrt((Slot1.p0_x - Slot2.p0_x)^2 + (Slot1.p0_y - Slot2.p0_y)^2);
p1_sqrt = sqrt((Slot1.p1_x - Slot2.p1_x)^2 + (Slot1.p1_y - Slot2.p1_y)^2);
p2_sqrt = sqrt((Slot1.p2_x - Slot2.p2_x)^2 + (Slot1.p2_y - Slot2.p2_y)^2);
p3_sqrt = sqrt((Slot1.p3_x - Slot2.p3_x)^2 + (Slot1.p3_y - Slot2.p3_y)^2);

if ((p0_sqrt < 0.3) && (p1_sqrt < 0.3) && (p2_sqrt < 0.3) && (p3_sqrt < 0.3))
    ret = 1;
    return;
else
   
end

%排序
pc1=pointsOrdered(pt_Slot1, pt_Slot1_PN);
pc2=pointsOrdered(pt_Slot2, pt_Slot2_PN);

inter=intersectPolygonSHPC(pc1,pc2);
pc_inter=pointsOrdered2(inter);

if pc_inter.size<=0 || pc1.size<=0
    proportion = single(0);
else
    proportion = computeArea(pc_inter)/computeArea(pc1);
end
% proportion = polyarea([pc_inter.x],[pc_inter.y])/polyarea([pc1.point.x],[pc1.point.y]);

if proportion>threshold
    ret=1;
else
    ret=0;
end
% plot([pc1.point.x pc1.point(1).x],[pc1.point.y pc1.point(1).y],'b',[pc2.point.x pc2.point(1).x],[pc2.point.y pc2.point(1).y],'g',[pc_inter.point.x pc_inter.point(1).x],[pc_inter.point.y pc_inter.point(1).y],'r')
end
function res=intersectPolygonSHPC(Slot1,Slot2)
    n=Slot1.size;
    point.x=single(0);
    point.y=single(0);
    res.point=repmat(point,16,1);
%     res.size = uint8(0);
    res.size = 0;
    p1=res;
    dir = left_of(Slot2.point(1), Slot2.point(2), Slot2.point(3));
    Slot1_temp=res;
    Slot2_temp=res;
    for k=1:Slot1.size
        Slot1_temp.point(k).x=Slot1.point(k).x;
        Slot1_temp.point(k).y=Slot1.point(k).y;
        Slot1_temp.size=Slot1.size;
    end
    for k=1:Slot2.size
        Slot2_temp.point(k).x=Slot2.point(k).x;
        Slot2_temp.point(k).y=Slot2.point(k).y;
        Slot2_temp.size=Slot2.size;
    end
    p2=poly_edge_clip(Slot1_temp,Slot2_temp.point(n), Slot2_temp.point(1), dir);
   
    for i =1:n-1
        tmp = p2;
        p2 = p1;
        p1 = tmp;
        p2=poly_edge_clip(p1, Slot2_temp.point(i), Slot2_temp.point(i+1), dir);
    end

    index=0;
    for i =1:p2.size
        index=index+1;
        res.point(index)=p2.point(i);
        res.size = res.size + 1;
    end
end

function res=poly_edge_clip(sub,x0,x1,left)
    n=sub.size;
    point.x=single(0);
    point.y=single(0);
    res.point=repmat(point,16,1);
    res.size = 0;
    if n==0
        return;
    end
    v0=sub.point(n);
    side0 = left_of(x0, x1, v0);
    if side0 ~=-left
        res.size=res.size+1;
        res.point(res.size).x=v0.x;
        res.point(res.size).y=v0.y;
    end
   
    for i=1:n
        v1 = sub.point(i);
        side1 = left_of(x0, x1, v1);
        if ((side0 + side1 == 0 )&& side0)
            %       /* last point and current straddle the edge */
            [ret,temp]=line_sect(x0, x1, v0, v1);
            if (ret)
                res.size=res.size+1;
                res.point(res.size)=temp;
            end
        end
        if (i == n)
            break;
        end
        
        if (side1 ~= -left)
            res.size=res.size+1;
            res.point(res.size).x=v1.x;
            res.point(res.size).y=v1.y;
        end
        v0 = v1;
        side0 = side1;
    end
end


function [ret,temp]=line_sect(x0,x1,y0,y1)
    ret = 1;
    temp.x = single(0);
    temp.y = single(0);

    dx=vsub(x1, x0);
    dy=vsub(y1, y0);
    d=vsub(x0, y0);
    dyx = cross(dy, dx);
    if (~dyx)
        ret= 0;
        return;
    end
    dyx = cross(d, dx) / dyx;
    if (dyx <= 0 || dyx >= 1)
        ret= 0;
        return;
    end
    temp.x = (y0.x + dyx * dy.x);
    temp.y = (y0.y + dyx * dy.y);
    ret= 1;
end

function ret=left_of(a,b,c)

    ret = 0;

    tmp1=vsub(b, a);%向量a->b
    tmp2=vsub(c, b);
    x = cross(tmp1, tmp2);%叉积
    if x < 0
        ret=-1;
    elseif x == 0
        ret=0;
    else
        ret=1;
    end
end

function res=vsub(a,b)
    point.x=single(0);
    point.y=single(0);
    res=point;
    res.x = a.x - b.x;
    res.y = a.y - b.y;
end

function ret=cross(a,b)
    ret= a.x * b.y - a.y * b.x;
end

function pc=pointsOrdered(pt, pt_num)

%     n=pt_num;
    if( pt_num <= 0)
        return;
    end

    center.x = mean([pt(1).x pt(2).x pt(3).x pt(4).x]);
    center.y = mean([pt(1).y pt(2).y pt(3).y pt(4).y]);

    temp.x=single(0);
    temp.y=single(0);
    temp.angle=single(0);
    pc.point=repmat(temp,16,1);
    pc.size = pt_num;
    for i = 1:pt_num
        pc.point(i).x = pt(i).x;
        pc.point(i).y = pt(i).y;
        pc.point(i).angle = atan2((pt(i).y - center.y), (pt(i).x - center.x));
    end
    pc.point=qsort(pc.point, pt_num, 1);%按角度升序排列,直角坐标系X轴为0度   从-pi到pi排列
    for i = 1:pt_num
        pt(i).x = pc.point(i).x;
        pt(i).y = pc.point(i).y;
    end
end

function pc=pointsOrdered2(pt)
    n=pt.size;
    temp.x=single(0);
    temp.y=single(0);
    temp.angle=single(0);
    pc.point=repmat(temp,16,1);
    pc.size = n;
    if( n <= 0)
        return;
    end
    center.x = single(0);
    center.y = single(0);
    for ii = 1:n
        center.x = center.x + pt.point(ii).x;
        center.y = center.y + pt.point(ii).y;
    end
    center.x = center.x/single(n);
    center.y = center.y/single(n);

    for i = 1:n
        pc.point(i).x = pt.point(i).x;
        pc.point(i).y = pt.point(i).y;
        pc.point(i).angle = atan2((pt.point(i).y - center.y), (pt.point(i).x - center.x));
    end
    pc.point=qsort(pc.point, n, 1);
    for i = 1:n
        pt.point(i).x = pc.point(i).x;
        pt.point(i).y = pc.point(i).y;
    end
end
%comp_point_with_angle=1 升序,-1 降序
function ret=qsort(pc,n,comp_point_with_angle)
    if comp_point_with_angle==1
        for i=1:n
            for j=i:n
                if pc(i).angle>pc(j).angle
                    temp=pc(i);
                    pc(i)=pc(j);
                    pc(j)=temp;
                end
               
            end
        end
    else
        for i=1:n
            for j=i+n
                if pc(i).angle<pc(j).angle
                    temp=pc(i);
                    pc(i)=pc(j);
                    pc(j)=temp;
                end
               
            end
        end
    end
    ret=pc;
end

function area0=computeArea(pt)
    area0 = single(0);
    n=pt.size;
    if n <= 0
        return;
    end

    for i=1:n-1
        area0 = area0+pt.point(i).x * pt.point(i+1).y;
        area0 = area0-pt.point(i).y * pt.point(i+1).x;
    end
    area0 = area0+pt.point(n).x * pt.point(1).y;
    area0 = area0-pt.point(n).y * pt.point(1).x;

    area0 = 0.5*abs(area0);

end
%%%%%%%%%%%%%%%%%%%%%

其中line_sect模块什么作用,(dyx <= 0 || dyx > 1)作何筛选?

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Mtnuli + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

qfxldhw 发表于 2023-12-7 15:32
代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判断这两条线段是否相交,并计算它们的交点坐标。

在给定的函数中,line_sect 接收四个点作为输入,分别代表两条线段的起点和终点。它首先计算两条线段的斜率,然后判断两条线段是否相交。

代码中的 (dyx <= 0 || dyx >= 1) 是用来排除交点位置不在两条线段的端点之间的情况。dyx 是通过计算交点在两条线段上的比例,判断其位置是否在两条线段的范围内。如果交点的比例小于等于 0 或者大于等于 1,意味着交点在延长线上而不在两条线段之间,因此不是线段的交点。

这个判断条件的作用是排除一些特殊情况,避免将不在线段上的点作为交点进行处理,确保得到的交点是有效的且位于两条线段之间的。
Mtnuli 发表于 2023-12-7 15:55
ciker_li 发表于 2023-12-7 19:11
 楼主| benson0308 发表于 2023-12-8 09:11
ciker_li 发表于 2023-12-7 19:11
这是啥语言写的?

matlab  .m
 楼主| benson0308 发表于 2023-12-8 09:14
本帖最后由 benson0308 于 2023-12-8 09:17 编辑
qfxldhw 发表于 2023-12-7 15:32
代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判 ...

感谢楼主,我也找到一部分参考。

https://www.cnblogs.com/zhb2000/p/vector-cross-product-solve-intersection.html#:~:text=%E5%A6%82%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%8C%E6%9C%89%E4%B8%A4%E6%9D%A1%E7%9B%B4%E7%BA%BF%E4%BA%A4%E4%BA%8E%E7%82%B9%20I%20%E3%80%82%20%E6%88%91%E4%BB%AC%E7%94%A8%E7%82%B9%20p%201%20%E5%92%8C%E5%90%91%E9%87%8F%20v
 楼主| benson0308 发表于 2023-12-8 09:15
qfxldhw 发表于 2023-12-7 15:32
代码中的 line_sect 函数是用来计算两条直线的交点的。它的作用是通过输入的两条线段(由四个点表示),判 ...

感谢楼主,我最近也在补相关知识。
代码是先用给矩形角点排序,然后利用叉乘判断矩形角点是否在另一矩形任一条线的同侧,如果异侧使用 line_sect函数求两线段交点。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表