C++ 矩形相交面积
下面是两个矩形。给定矩形顶点的坐标-(x1,y1)…(x8,y8),如何计算重叠区域的面积(下图中的白色)?C++ 矩形相交面积,c++,math,computational-geometry,C++,Math,Computational Geometry,下面是两个矩形。给定矩形顶点的坐标-(x1,y1)…(x8,y8),如何计算重叠区域的面积(下图中的白色)? 注意: 点的坐标可以是任意的 矩形可以重叠,也可以不重叠 假设矩形不重叠或在点或线处重叠时面积为0 如果一个矩形在另一个矩形内,则计算较小矩形的面积 您可以通过求解图形所有对边的交点方程来计算交点: /frac{x-a}{b-a}=/frac{x-c}{d-c} 以这种方式获得的点可以位于平行线的两侧,尽管它们不能位于平行线的两侧。您必须检查通过求解方程获得的交点是否位于图形的侧面。如果
注意:
您可以通过求解图形所有对边的交点方程来计算交点: /frac{x-a}{b-a}=/frac{x-c}{d-c} 以这种方式获得的点可以位于平行线的两侧,尽管它们不能位于平行线的两侧。您必须检查通过求解方程获得的交点是否位于图形的侧面。如果他们这样做了,您可以计算延伸到两个地物内部的地物边的长度,并通过取其倍数来计算交点的平方
我想我的方法听起来有点太复杂了,但这是我想到的第一个想法。既然你说矩形可能没有对齐,可能的答案可能是零、点、线段或3-8边的多边形 执行此
2d boolean
操作的常用方法是选择边的逆时针顺序,然后计算临界点(交点或角点)之间的边段。在每个交叉点,您可以在第一个矩形的边段和第二个矩形的边段之间切换,或者反之亦然。始终拾取上一段左侧的段
有很多细节,但基本算法是找到所有交点,并用适当的数据结构对它们的边缘进行排序。选择一个交点(如果有),然后选择一条远离该交点的线段。找到所选起始段左侧另一个矩形的段。在图中,我们选择交叉点a上的绿色线段(箭头指示的方向)作为参考线段。右边另一个矩形的线段是从a到b的线段。将其用作下一个参考线段,并选择其左侧的绿色线段。这是从b到c的部分。以相同的方式查找段cd。下一段是从d到角点,因此角点也位于交点的顶点列表中。从玉米中我们回到了a
要每次选择左侧,请使用相交边方向向量坐标的确定值。如果有向边的有序对的行列式是正的,那么你就走对了
现在已经有了相交多边形的顶点,可以使用来获取面积
我要留给你们的一些细节是:
- 如果一个角点与另一个三角形的边或顶点重合怎么办
- 如果没有交叉口怎么办?(一个矩形在另一个矩形内,或者它们是不相交的——您可以使用多边形中的点检查来解决这个问题。请参阅
- 如果交点是一个点或一段,该怎么办
当然,当重复次数较多时,结果会更精确。顺便说一句,这种方法称为蒙特卡罗方法。用三角形而不是矩形来思考这个问题可能会有所帮助。在空间中找到给定三个点的三角形面积相对简单 通过将矩形面积减去三角形面积之和,可以找到相交区域,如下图所示 从本质上讲,它变成了一个新的概念 有一个很好的介绍,其中有一些关于数据结构和算法的指针 编辑: 有一些可以重复使用
如果你知道你要开始的两个三角形的面积,你可以找到矩形并集的总面积,那么交点就是两个矩形的总面积-并集面积。如果你碰巧使用了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;
}