如何计算三角形(指定为三(X,Y)对)和圆(X,Y,R)之间的交叉区域?我做了一些搜索无济于事。这是为了工作,而不是学校。 :)
在C#中看起来像这样:
struct { PointF vert[3]; } Triangle;
struct { PointF center; float radius; } Circle;
// returns the area of intersection, e.g.:
// if the circle contains the triangle, return area of triangle
// if the triangle contains the circle, return area of circle
// if partial intersection, figure that out
// if no intersection, return 0
double AreaOfIntersection(Triangle t, Circle c)
{
...
}
答案 0 :(得分:32)
答案 1 :(得分:27)
如果你想要一个精确的解决方案(或至少与使用浮点运算一样精确),那么这将涉及大量的工作,因为有很多情况需要考虑。
我计算了九种不同的情况(在下图中按圆圈内三角形的顶点数量分类,以及圆圈中相交或包含的三角形边缘数量):
(然而,众所周知,这种几何情况的枚举是棘手的,如果我错过了一两个,它就不会让我感到惊讶!)
所以方法是:
确定三角形的每个顶点是否在圆圈内。我假设你知道怎么做。
确定三角形的每个边缘是否与圆相交。 (我写了一个方法here,或者看到任何计算几何图书。)你需要计算在步骤4中使用的一个或多个交点(如果有的话)。
确定您拥有的九个案例中的哪一个。
计算交叉口的面积。案例1,2和9很容易。在剩余的六个案例中,我绘制了虚线,以显示如何根据三角形的原始顶点以及在步骤2中计算的交叉点将交叉区域划分为三角形和circular segments。 / p>
这个算法会非常精巧并且容易出错,只会影响其中一个案例,因此请确保您的测试用例涵盖了所有9个案例(我建议也可以排列测试三角形的顶点)。特别注意三角形的一个顶点位于圆的边缘的情况。
如果你不需要精确的解决方案,那么光栅化数字并计算交叉点中的像素(正如其他几位受访者所建议的那样)似乎是一种更容易的代码处理方法,相应地也不容易出错。
答案 2 :(得分:2)
我差不多一年半了,但我想也许人们会对我写的code here感兴趣,我认为这样做是正确的。查看靠近底部的功能IntersectionArea。一般的方法是挑选由圆圈限定的凸多边形,然后处理小圆形帽。
答案 3 :(得分:1)
假设你说的是整数像素,而不是真实的,那么天真的实现就是遍历三角形的每个像素,并检查圆心的距离与半径之间的距离。
这不是一个可爱的公式,或者特别快,但它确实完成了工作。
答案 4 :(得分:1)
注意:这不是一个小问题,我希望它不是作业; - )
答案 5 :(得分:1)
如果您拥有GPU,可以使用this技术获取交叉点的像素数。
答案 6 :(得分:1)
我认为你不应该将圆形近似为一组三角形,而不是用多边形逼近它的形状。 天真算法看起来像:
您可以通过将第2步和第3步组合成单一功能来优化此算法。
阅读此链接:
Area of convex polygon
Intersection of convex polygons
答案 7 :(得分:1)
由于你的形状是凸的,你可以使用蒙特卡罗面积估计。
在圆圈和三角形周围画一个方框。
在框中选择随机点,并计算圆圈中落下的数量,以及圆圈和三角形中落入的数量。
交点面积circle圆的面积*#以圆圈表示,三角形/圆圈中的#点
当估计区域在一定数量的回合中没有变化超过一定量时停止选择点,或者仅根据框的区域选择固定数量的点。除非你的一个形状面积很小,否则面积估计应该快速收敛。
注意:以下是确定点是否在三角形中的方式:Barycentric coordinates
答案 8 :(得分:0)
您需要多少精确度?如果您可以使用更简单的形状来近似圆形,则可以简化问题。例如,将圆形建模为一组在中心相交的非常窄的三角形并不困难。
答案 9 :(得分:0)
如果只有一个三角形的线段与圆相交,那么纯数学解决方案就不会太难。一旦知道两个交点何时出现,就可以使用距离公式来找到弦长。
ϑ = 2 sin⁻¹(0.5 c / r)
A = 0.5 r² (ϑ - sin(ϑ))
其中c是弦长,r是半径,θ是通过中心的角度,A是面积。请注意,如果切掉一半以上的圆圈,此解决方案就会中断。
如果你只需要一个近似值,这可能是不值得的,因为它对实际的交叉点看起来有几个假设。
答案 10 :(得分:0)
我的第一直觉是变换所有东西,使圆圈以原点为中心,将三角形转换为极坐标,并求解三角形与圆的交点(或包围)。我实际上并没有在纸上完成它,但这只是一种预感。