C++ 矩形相交面积

C++ 矩形相交面积,c++,math,computational-geometry,C++,Math,Computational Geometry,下面是两个矩形。给定矩形顶点的坐标-(x1,y1)…(x8,y8),如何计算重叠区域的面积(下图中的白色)? 注意: 点的坐标可以是任意的 矩形可以重叠,也可以不重叠 假设矩形不重叠或在点或线处重叠时面积为0 如果一个矩形在另一个矩形内,则计算较小矩形的面积 您可以通过求解图形所有对边的交点方程来计算交点: /frac{x-a}{b-a}=/frac{x-c}{d-c} 以这种方式获得的点可以位于平行线的两侧,尽管它们不能位于平行线的两侧。您必须检查通过求解方程获得的交点是否位于图形的侧面。如果

下面是两个矩形。给定矩形顶点的坐标-(x1,y1)…(x8,y8),如何计算重叠区域的面积(下图中的白色)?

注意:

  • 点的坐标可以是任意的
  • 矩形可以重叠,也可以不重叠
  • 假设矩形不重叠或在点或线处重叠时面积为0
  • 如果一个矩形在另一个矩形内,则计算较小矩形的面积

  • 您可以通过求解图形所有对边的交点方程来计算交点: /frac{x-a}{b-a}=/frac{x-c}{d-c}

    以这种方式获得的点可以位于平行线的两侧,尽管它们不能位于平行线的两侧。您必须检查通过求解方程获得的交点是否位于图形的侧面。如果他们这样做了,您可以计算延伸到两个地物内部的地物边的长度,并通过取其倍数来计算交点的平方


    我想我的方法听起来有点太复杂了,但这是我想到的第一个想法。

    既然你说矩形可能没有对齐,可能的答案可能是零、点、线段或3-8边的多边形

    执行此
    2d boolean
    操作的常用方法是选择边的逆时针顺序,然后计算临界点(交点或角点)之间的边段。在每个交叉点,您可以在第一个矩形的边段和第二个矩形的边段之间切换,或者反之亦然。始终拾取上一段左侧的段

    有很多细节,但基本算法是找到所有交点,并用适当的数据结构对它们的边缘进行排序。选择一个交点(如果有),然后选择一条远离该交点的线段。找到所选起始段左侧另一个矩形的段。在图中,我们选择交叉点a上的绿色线段(箭头指示的方向)作为参考线段。右边另一个矩形的线段是从a到b的线段。将其用作下一个参考线段,并选择其左侧的绿色线段。这是从b到c的部分。以相同的方式查找段cd。下一段是从d到角点,因此角点也位于交点的顶点列表中。从玉米中我们回到了a

    要每次选择左侧,请使用相交边方向向量坐标的确定值。如果有向边的有序对的行列式是正的,那么你就走对了

    现在已经有了相交多边形的顶点,可以使用来获取面积

    我要留给你们的一些细节是:

    • 如果一个角点与另一个三角形的边或顶点重合怎么办

    • 如果没有交叉口怎么办?(一个矩形在另一个矩形内,或者它们是不相交的——您可以使用多边形中的点检查来解决这个问题。请参阅

    • 如果交点是一个点或一段,该怎么办


    您可能会发现另一种方式很有趣,但在这种情况下可能不适用,那就是:

  • 确定最小矩形(其边平行于 包含两个给定矩形的坐标轴),让 把那个新的称为边界框
  • 选择边界框中的随机点,并检查它是否在两个矩形中
  • 重复第2步(取决于结果的精度),并有两个计数器,一到两个 跟踪两个矩形内的点数,以及 另一个是步骤2的重复次数
  • 最终的解决方案是将边界框的面积乘以两个矩形内的点数,然后除以数值 重复第2步,或以公式形式:

    相交面积=边界框面积*两个内点的数量/ 重复次数


  • 当然,当重复次数较多时,结果会更精确。顺便说一句,这种方法称为蒙特卡罗方法。

    用三角形而不是矩形来思考这个问题可能会有所帮助。在空间中找到给定三个点的三角形面积相对简单

    通过将矩形面积减去三角形面积之和,可以找到相交区域,如下图所示

    从本质上讲,它变成了一个新的概念

    有一个很好的介绍,其中有一些关于数据结构和算法的指针

    编辑:

    有一些可以重复使用


    如果你知道你要开始的两个三角形的面积,你可以找到矩形并集的总面积,那么交点就是两个矩形的总面积-并集面积。

    如果你碰巧使用了Qt,那么交点可以计算为
    QPolygonF
    交点。 大致如此:

    QPolygonF p1,p2, intersected;
    p1 << QPointF(r1x1,r1y1) << ... << QPointF(r1x4, r1y4);
    p2 << QPointF(r2x1,r2y2) << ... << QPointF(r2x4, r2y4);
    intersected = p1.intersected(p2);
    
    float area = polyArea(intersected); // see code block below
    
    QPolygonF p1,p2,相交;
    
    p1可能需要使用opencv。使用fillPoly()函数生成一个矩形。确保填充矩形为白色(255、255、255)。然后使用copyTo()函数,您将获得重叠区域。然后检查每个像素的值,如果是白色,则为+1。

    更具体地说,您是指轴对齐的矩形,对吗?平行线是三维多边形,可以有非直角交点。您的图像似乎显示一对对齐的矩形。深黄色:是帕克:对不起,我的输入错误,我是说矩形。重叠区域的面积:是的,这就是我想要的
    inline float polyArea(const QPolygonF& p)
    {
        //https://en.wikipedia.org/wiki/Polygon#Area_and_centroid
        const int n = p.size();
        float area = 0.0;
        for (int i=0; i<n; i++)
        {
            area += p[i].x()*p[(i+1)%n].y() - p[(i+1)%n].x()*p[i].y();
        }
        if (area < 0)
            return -0.5*area;
        else
            return 0.5*area;
    }