【问题标题】:Find the midpoint of overlap between circle and rectangle找到圆形和矩形之间重叠的中点
【发布时间】:2012-03-28 08:03:24
【问题描述】:

我正在开发一个小型游戏几何库,在许多其他方法中,我希望能够找到圆和矩形之间的交点。但是,我很难想到一个快速算法来做到这一点。有谁知道这样做的好算法吗?

如果这意味着算法会明显更快,我愿意牺牲完美的准确性。

我表示每个形状的基本方式是:

圈子

  • 浮动 x, y(中心)
  • float r(半径)

矩形

  • 浮动 x, y(中心)
  • float w, h(宽度和高度值,它们代表从中心到各自边缘的 x 和 y 距离)。

编辑:

由于我所说的“中点”似乎有些混淆,让我澄清一下:

鉴于圆形和矩形相交,它们的重叠创建了一个区域。我希望确定该区域的地理中心(准确或确定近似值)。

示例:http://en.wikipedia.org/wiki/Centroid


编辑#2:

你们给了我一些想法,让我努力实现其中的一些,我会回复你的。


结语:

我将 Gareth 的答案标记为已接受的答案,因为它给了我最终的想法,但我的最终实现与他的不同,所以我会在这里解释一下。

我想出了两种通用的方法:一种是完全准确的(但需要更复杂的编程和更多的数学运算),另一种更简单/更快的方法,一直都非常接近。我最终选择了后者,但这里有两种方法:

方法一:形状碎片化:

基本上,这个想法是将重叠区域分解成离散的部分,可以轻松计算它们的中点和面积,然后对整个结果进行加权平均。

此处显示的示例包含三个子部分:一个中心矩形占据了大部分区域,两个曲线段用于圆的边缘。

方法2:线插值

首先,您需要计算矩形中的一个点,该点将作为基本位置。这应该是一个易于计算且处于重叠中的点。我对这一点使用的是圆形和矩形的所有边缘交叉点的平均值(如果不存在边缘交叉点,我默认为圆的位置,因为这意味着一个形状包含在另一个形状中)。

C计算圆心和那个点之间的直线。然后,计算位于重叠区域内的线段。该区域的中点被视为该线段的中点。

这种方法不准确,但总是在两个对象内产生一个点,并且结果点通常靠近中间(所以它“看起来”不错)。它也更简单、更快,所以我选择了它。

【问题讨论】:

  • “中点”是什么意思?你想要centroid吗?
  • 相交区域的中心。
  • 另外,请记住,圆形和矩形可以以多种不同方式相交。
  • @CodeBunny:好的,定义“相交区域的中心”。
  • 如果您需要一些非常快但不准确的东西,您可以用它的边界框来表示球体。

标签: algorithm geometry 2d intersection area


【解决方案1】:

一种方法是将其分解为案例:

  1. 圆完全在矩形内
  2. 矩形完全在圆内
  3. 圆与矩形的一侧相交
  4. 圆与矩形的两条相邻边相交(包括和不包括角)。
  5. 圆与矩形的两条相对边相交
  6. 圆与矩形的三个边相交
  7. 圆与矩形的四个边相交。

然后,找到每种情况的质心。例如,在第三种情况下,交点是一个圆弧段,您可以使用标准公式找到它的质心。在第四种情况下,您最终会得到一个三角形和一个圆形线段。您可以通过将每个部分的面积乘以其各自的质心然后除以总面积来找到组合区域的质心。

【讨论】:

  • 这种做法似乎过于简单了。例如,第四种情况可能看起来要复杂得多;取决于圆与两侧相交的频率,您不会逃脱一个三角形和一个圆弧段。
  • @WolframH:是的。我已经更新了我的清单。我现在在想,将它更像是一个多边形/多边形交叉点会更好。也许按顺序找到所有边缘/圆的交点。您最终会得到一些边是线段,一些边是圆段。
  • 这只是一个例子... 5 类似,我不确定 6 和 7 有多复杂。 (根据我的经验,通常很难完全枚举所有可能的几何问题。我真的会尽量避开那条路。)
【解决方案2】:

如果我正确理解您的要求,您希望找到两个形状重叠区域的中心?

对吗?

有一个圆心为 (x,y),半径为 r。 有一个以 (x,y) 为中心,宽为 w,高为 h 的矩形

所以这是第一个差距:

您不能在 x,y 平面中定义仅具有中心点和宽度和高度的矩形。矩形朝向哪个方向?

上面描述的圆的方程是 (x-a)^2 + (y-b)^2=r^2

可以同时求解这个方程和一条直线的方程以获得交点。

第二个差距:

一条线可能在 2 个点与一个圆相交,一个点或无点 - 你确定圆和矩形将始终重叠,所以线的两个点与圆相交吗?

假设是,从这一点(找到两个交点)计算交点之间的中点,然后计算与该中点垂直的线的中点应该不会太难到圆的边缘(形状相交区域的中点)

这绝不是一个“这就是答案”的答案,但我希望这会有所帮助?

史蒂夫

【讨论】:

  • 矩形没有旋转,与笛卡尔平面齐平。
【解决方案3】:

如果您对近似值感到满意,请尝试抽样。将矩形划分为若干个正方形,并为每个正方形估计它是否大部分在圆内(也许只是通过测试它的中心是否在圆内)。

然后申请the centroid formula

平面图形的质心可以通过将其划分为有限数量的简单图形来计算,计算每个部分的质心Ci和面积Ai,然后计算 Σ Ci Ai / Σ Ai.

在这种情况下特别简单,因为正方形的质心是它的中心,并且所有的 Ai 都是相等的。

suggested by Vaughn Cato 的几何剖析会得到准确的答案,但这种近似方法的优点是简单:编程不正确会困难得多。)


CodeBunny 在 cmets 中要求“更简单、基于方程的结果”。以下是使用方程式计算结果的方法,但我认为它并不“更简单”。

首先,您必须通过将圆与矩形的每条边相交并计算相交的数量来确定您所处的几何情况。我相信,这会让您面临以下十四种情况之一:

然后,对于每种情况,您将交集分解为圆形段和凸多边形的总和。计算每一个的面积和质心(有关公式,请参见维基百科:areacentroid 圆弧段;area and centroid of convex polygon)并使用我上面给出的质心公式将它们组合起来。

这绝不是简单的:几何案例的枚举很棘手(我很容易错过一两个案例:在我第一次尝试时,我只发现了 11 个案例),并且计算编程很精细(很容易只在其中一种情况下犯了错误而没有注意到)。

【讨论】:

  • 这会给我一个准确的答案,但是太复杂了。我希望得到一个更简单、基于方程的结果。
【解决方案4】:

也许为时已晚……

有一种简单、精确、快速的方法:

考虑到在每个矩形边缘AB 和圆心O 之间形成的三角形ABO,您必须按顺时针方向循环矩形。

然后,您必须考虑该三角形ABO 与圆的交点。最多,你会得到ABO 分为两个圆形扇区(APOQBO)和一个子三角形(PQO)。对于这些扇区和子三角形中的每一个,您都可以计算其中点和面积,当OAOB 之间的角度为逆时针时,您可以将面积视为负数。

然后,要获得矩形和圆相交处的中点,您必须计算扇区和子三角形中点的中值,并按其符号面积加权。

【讨论】:

    猜你喜欢
    • 2013-03-27
    • 1970-01-01
    • 2011-07-13
    • 2023-01-26
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    相关资源
    最近更新 更多