圆与矩形的交面积
我正在寻找一种快速方法来确定矩形和圆形之间的相交面积(我需要进行数百万次这样的计算)。
一个特定的属性是,在所有情况下,圆形和矩形始终有 2 个交点。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我正在寻找一种快速方法来确定矩形和圆形之间的相交面积(我需要进行数百万次这样的计算)。
一个特定的属性是,在所有情况下,圆形和矩形始终有 2 个交点。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
给定 2 个交点:
0 个顶点 在圆内:圆形的面积线段
1个顶点在圆内:圆线段和三角形的面积之和。
2 个顶点在圆内:两个三角形和一个圆弧段的面积之和
3 个顶点在圆内:矩形面积减去一个圆的面积三角形加上圆弧段的面积
要计算这些面积:
您需要使用的大多数点都可以通过查找 直线和圆的交点
您需要计算的面积可以通过 计算圆弧段的面积 和 计算三角形的面积。
可以通过计算顶点到圆心的距离是否小于半径来判断顶点是否在圆内。
可以通过计算顶点到圆心的距离是否小于半径来判断
Given 2 points of intersection:
0 vertices is inside the circle: The area of a circular segment
1 vertex is inside the circle: The sum of the areas of a circular segment and a triangle.
2 vertices are inside the circle: The sum of the area of two triangles and a circular segment
3 vertices are inside the circle: The area of the rectangle minus the area of a triangle plus the area of a circular segment
To calculate these areas:
Most of the points you'll need to use can be found by finding the intersection of a line and a circle
The areas you need to compute can be found by computing the area of a circular segment and computing the area of a triangle.
You can determine if a vertex is inside the circle by calculating if its distance from the center is less than the radius.
我意识到这个问题不久前就得到了回答,但我正在解决同样的问题,但我找不到可以使用的开箱即用的可行解决方案。 请注意,我的框是轴对齐,OP并未完全指定这一点。 下面的解决方案是完全通用的,并且适用于任意数量的交叉点(不仅仅是两个)。 请注意,如果您的框不是轴对齐的(但仍然是直角框,而不是一般的四边形),您可以利用圆形的优势,旋转所有物体的坐标,使盒子最终轴对齐,然后然后使用此代码。
我想使用集成——这似乎是个好主意。 让我们从编写一个用于绘制圆的明显公式开始:
这很好,但我无法在
x
或y
上积分该圆的面积; 这些是不同的数量。 我只能在theta
角度上积分,产生披萨片区域。 不是我想要的。 让我们尝试改变一下论点:这更像是这样。 现在给定 x 的范围,我可以对 y 进行积分,以获得圆上半部分的面积。 这仅适用于
[center.x - radius, center.x + radius]
中的x
(其他值将导致虚数输出),但我们知道该范围之外的区域为零,因此很容易处理。 为了简单起见,我们假设单位圆,稍后我们可以随时将圆心和半径插回:该函数确实具有 pi/2 的积分,因为它是单位圆的上半部分(面积半圆的面积是
pi * r^2 / 2
,我们已经说过单位,这意味着r = 1
)。 来计算站在x轴上的半圆和无限高的盒子的交集面积(圆心也位于x轴上):现在我们可以通过对
y
积分 可能不是很有用,因为无限高的盒子不是我们想要的。 我们需要再添加一个参数,以便能够释放无限高盒子的底部边缘:其中
h
是无限盒子的底部边缘与 x 轴的(正)距离。section
函数计算单位圆与由y = h
给出的水平线相交的(正)位置,我们可以通过求解来定义它:现在我们可以得到事情的进展。 那么如何计算与 x 轴上方单位圆相交的有限盒子的交集面积:
这很好。 那么如果盒子不在 x 轴上方呢? 我想说不是所有的盒子都是。 出现三种简单的情况:
足够简单吗? 让我们编写一些代码:
以及一些基本的单元测试:
其输出是:
这对我来说似乎是正确的。 如果您不信任编译器会为您完成内联函数,您可能需要内联这些函数。
对于不与 x 轴相交的框,使用 6 sqrt、4 asin、8 div、16 mul 和 17 个相加,对于与 x 轴相交的框,使用该值的两倍(以及另外 1 个相加)。 请注意,除法是按半径进行的,可以减少为两次除法和一堆乘法。 如果相关框与 x 轴相交但不与 y 轴相交,则可以将所有内容旋转
pi/2
并按原始成本进行计算。我使用它作为调试亚像素精度抗锯齿圆形光栅器的参考。 它太慢了:),我需要计算圆的边界框中每个像素与圆的相交面积以获得alpha。 您可以看到它有效,并且似乎没有出现数字伪影。 下图是一堆半径从 0.3 px 增加到约 6 px 的圆,呈螺旋状排列。
I realize this was answered a while ago but I'm solving the same problem and I couldn't find an out-of-the box workable solution I could use. Note that my boxes are axis aligned, this is not quite specified by the OP. The solution below is completely general, and will work for any number of intersections (not only two). Note that if your boxes are not axis-aligned (but still boxes with right angles, rather than general quads), you can take advantage of the circles being round, rotate the coordinates of everything so that the box ends up axis-aligned and then use this code.
I want to use integration - that seems like a good idea. Let's start with writing an obvious formula for plotting a circle:
This is nice, but I'm unable to integrate the area of that circle over
x
ory
; those are different quantities. I can only integrate over the angletheta
, yielding areas of pizza slices. Not what I want. Let's try to change the arguments:That's more like it. Now given the range of
x
, I can integrate overy
, to get an area of the upper half of a circle. This only holds forx
in[center.x - radius, center.x + radius]
(other values will cause imaginary outputs) but we know that the area outside that range is zero, so that is handled easily. Let's assume unit circle for simplicity, we can always plug the center and radius back later on:This function indeed has an integral of
pi/2
, since it is an upper half of a unit circle (the area of half a circle ispi * r^2 / 2
and we already said unit, which meansr = 1
). Now we can calculate area of intersection of a half-circle and an infinitely tall box, standing on the x axis (the center of the circle also lies on the the x axis) by integrating overy
:This may not be very useful, as infinitely tall boxes are not what we want. We need to add one more parameter in order to be able to free the bottom edge of the infinitely tall box:
Where
h
is the (positive) distance of the bottom edge of our infinite box from the x axis. Thesection
function calculates the (positive) position of intersection of the unit circle with the horizontal line given byy = h
and we could define it by solving:Now we can get the things going. So how to calculate the area of intersection of a finite box intersecting a unit circle above the x axis:
That's nice. So how about a box which is not above the x axis? I'd say not all the boxes are. Three simple cases arise:
Easy enough? Let's write some code:
And some basic unit tests:
The output of this is:
Which seems correct to me. You may want to inline the functions if you don't trust your compiler to do it for you.
This uses 6 sqrt, 4 asin, 8 div, 16 mul and 17 adds for boxes that do not intersect the x axis and a double of that (and 1 more add) for boxes that do. Note that the divisions are by radius and could be reduced to two divisions and a bunch of multiplications. If the box in question intersected the x axis but did not intersect the y axis, you could rotate everything by
pi/2
and do the calculation in the original cost.I'm using it as a reference to debug subpixel-precise antialiased circle rasterizer. It is slow as hell :), I need to calculate the area of intersection of each pixel in the bounding box of the circle with the circle to get alpha. You can sort of see that it works and no numerical artifacts seem to appear. The figure below is a plot of a bunch of circles with the radius increasing from 0.3 px to about 6 px, laid out in a spiral.
我希望对这样一个老问题发表答案并不是坏事。 我查看了上述解决方案,并制定了一个与丹尼尔斯第一个答案类似的算法,但更严格一些。
简而言之,假设整个区域都在矩形中,减去外部半平面中的四个线段,然后添加四个外部象限中的任何区域,并在此过程中丢弃琐碎的情况。
伪cde(我的实际代码只有~12行..)
顺便说一句,平面象限中包含的圆面积的最后一个公式很容易导出为圆弧段、两个直角三角形和一个矩形的总和。
享受。
I hope its not bad form to post an answer to such an old question. I looked over the above solutions and worked out an algorithm which is similar to Daniels first answer, but a good bit tighter.
In short, assume the full area is in the rectangle, subtract off the four segments in the external half planes, then add any the areas in the four external quadrants, discarding trivial cases along the way.
pseudocde (my actual code is only ~12 lines..)
Incidentally, that last formula for the area of a circle contained in a plane quadrant is readily derived as the sum of a circular segment, two right triangles and a rectangle.
Enjoy.
下面介绍如何计算圆与矩形的重叠面积,其中圆心位于矩形之外。 其他情况可以简化为这个问题。
面积可以通过积分圆方程 y = sqrt[a^2 - (xh)^2] + k 来计算,其中 a 是半径,(h,k) 是圆心,找到曲线下面积。 您可以使用计算机集成,将区域划分为许多小矩形并计算它们的总和,或者在这里仅使用封闭形式。
这里是实现上述概念的 C# 源代码。 请注意,有一种特殊情况,即指定的 x 位于圆的边界之外。 我在这里只是使用一种简单的解决方法(在所有情况下都不会产生正确的答案)
注意:此问题与 Google Code Jam 2008 资格赛问题:苍蝇拍。 您也可以单击分数链接下载解决方案的源代码。
The following is how to calculate the overlapping area between circle and rectangle where the center of circle lies outside the rectangle. Other cases can be reduced to this problem.
The area can be calculate by integrating the circle equation y = sqrt[a^2 - (x-h)^2] + k where a is radius, (h,k) is circle center, to find the area under curve. You may use computer integration where the area is divided into many small rectangle and calculating the sum of them, or just use closed form here.
And here is a C# source implementing the concept above. Note that there is a special case where the specified x lies outside the boundaries of the circle. I just use a simple workaround here (which is not producing the correct answers in all cases)
Note: This problem is very similar to one in Google Code Jam 2008 Qualification round problem: Fly Swatter. You can click on the score links to download the source code of the solution too.
感谢您的回答,
我忘了提及面积估计就足够了。
那; 这就是为什么最后,在查看了所有选项之后,我采用了蒙特卡罗估计,在圆圈中生成随机点并测试它们是否在框中。
就我而言,这可能性能更高。 (我在圆上放置了一个网格,我必须测量属于每个网格单元的圆的比率。)
谢谢
Thanks for the answers,
I forgot to mention that area estimatations were enough.
That; s why in the end, after looking at all the options, I went with monte-carlo estimation where I generate random points in the circle and test if they're in the box.
In my case this is likely more performant. (I have a grid placed over the circle and I have to measure the ratio of the circle belonging to each of the grid-cells. )
Thanks
也许您可以使用这个问题的答案< /a>,询问圆和三角形之间的交点面积。 将矩形分成两个三角形并使用此处描述的算法。
另一种方法是在两个交点之间画一条线,这会将您的区域分割为一个多边形(3 或 4 条边)和一个 圆弧段,您应该能够更轻松地找到库或自己进行计算。
Perhaps you can use the answer to this question, where the area of intersection between a circle and a triangle is asked. Split your rectangle into two triangles and use the algorithms described there.
Another way is to draw a line between the two intersection points, this splits your area into a polygon (3 or 4 edges) and a circular segment, for both you should be able to find libraries easier or do the calculations yourself.
这是该问题的另一种解决方案:
Here is another solution for the problem: