检查一个圆是否完全包含在其他圆的区域内的算法
Algorithm to check if a Circle is totally contained in the area of other circles
检查如下蓝色圆圈是否完全包含在其他圆圈(白色圆圈)的区域内的算法是什么?我想要蓝色圆圈为 TRUE,红色圆圈为 FALSE
所有圆的输入是它们的坐标和半径。
这看起来很简单(编辑:但事实并非如此):如果给定圆的每条弧的每个点都包含在至少一个其他圆中,则包含整个圆。然后,您必须找到所有交点 (algorithm to detect if a Circles intersect with any other circle in the same plane),并检查这些交点指定的所有弧。如果圆A的弧A1-A2与圆B的给定两个交点(弧B1-B2,其中点A1=B1和A2=B2)的任何"inside"点包含在圆B中,则整个圆弧包含在圆 B 中,反之亦然。如有不妥请指正
编辑:好的,我已经知道,我错了,正如 maxim1000 所示。这比我想象的要复杂。我想在我的答案中添加一些内容,但我不确定这是否是一个解决方案。不过,我希望它有所帮助。即:我想确定我们心目中的圈子与所有其他圈子之间的交集总面积。我们在我们的圆圈内找到所有分离的交叉点——所有包含相同点的部分,被所有相交的弧线分开——并找到它们的面积。吴总结了他们。如果它等于我们圆的面积,那么我们的圆就包含在其他圆中。确定这个区域本身可能是一个问题,但正如我所说,它可能会引导到正确的方向。让我也想想..
编辑:经过一段时间的思考。确定(多个)相交圆中的所有区域只是添加或减去三角形或......嗯......如何称呼它们? ...图片中的黄色部分 :)
我认为没有简单的解决方案。
我会依次计算每个圆圈,并对所有其他圆圈执行布尔减法来解决这个问题。 (足够远的圆 - R0 + R1 < D12 - 不会干扰。)
吃完块后,圆变成由圆弧组成的曲线多边形,或者一组这样的多边形,因为连通性可以被打破。多边形可以由构成其轮廓弧的圆列表表示,弧端点由两个连续邻居的公共交点或目标圆和邻居的公共交点定义。请注意,同一个邻居可以出现多次。
为了让事情更血腥,多边形可以有洞,你也需要表现出来。
那么关键的操作就是曲线多边形减圆。您需要检测完全位于新圆圈内的圆弧和穿过新圆圈的圆弧。得到弧线的剩余部分后,您需要重新排列剩余的弧线和新的弧线。
我想所有这些操作都可以从一个单一的基元构建,该基元找到圆弧内的圆弧部分(由三个圆圈定义)。
这是一个粗略的解决方案:
- 取所有圆并找到所有个交点在测试圆T上或内部。分割相应的边和构建边图:
对于每条边,跟踪创建它的圆。
- 使用最小循环算法(Find all non-overlapping polygons in a list of edges/vertices)找到圆内所有非重叠区域。
对于你找到的每个区域R的每条边界线E,取E所属的圆C。如果 C 是 not T(红色)- 即 E 是蓝色,检查 R 的其他边缘上的点是否在 C:
内
- 如果是,则 C 覆盖 R。继续下一个区域。
- 如果它们不是,则 R 不被 C 覆盖。循环围绕 R 的其他蓝色边缘。
- 如果最后 R 仍然 没有被覆盖,那么 T 就没有被完全覆盖 - return false.
上图中,C包含B,所以覆盖了R;但是C不包含A,所以不覆盖S
- 如果您在此阶段还没有 returned,那么 return true.
附带案例:
- 如果某个圈子里有T,就忽略它
- 如果 T 包含 it,则 延迟 通过将其存储在列表中来进行交集测试。最后重做测试并拆分它的边缘。
这个算法非常效率低下,我不能 100% 确定是否还有更退化的情况;如果有人有任何建议,请告诉我。
检查如下蓝色圆圈是否完全包含在其他圆圈(白色圆圈)的区域内的算法是什么?我想要蓝色圆圈为 TRUE,红色圆圈为 FALSE
所有圆的输入是它们的坐标和半径。
这看起来很简单(编辑:但事实并非如此):如果给定圆的每条弧的每个点都包含在至少一个其他圆中,则包含整个圆。然后,您必须找到所有交点 (algorithm to detect if a Circles intersect with any other circle in the same plane),并检查这些交点指定的所有弧。如果圆A的弧A1-A2与圆B的给定两个交点(弧B1-B2,其中点A1=B1和A2=B2)的任何"inside"点包含在圆B中,则整个圆弧包含在圆 B 中,反之亦然。如有不妥请指正
编辑:好的,我已经知道,我错了,正如 maxim1000 所示。这比我想象的要复杂。我想在我的答案中添加一些内容,但我不确定这是否是一个解决方案。不过,我希望它有所帮助。即:我想确定我们心目中的圈子与所有其他圈子之间的交集总面积。我们在我们的圆圈内找到所有分离的交叉点——所有包含相同点的部分,被所有相交的弧线分开——并找到它们的面积。吴总结了他们。如果它等于我们圆的面积,那么我们的圆就包含在其他圆中。确定这个区域本身可能是一个问题,但正如我所说,它可能会引导到正确的方向。让我也想想..
编辑:经过一段时间的思考。确定(多个)相交圆中的所有区域只是添加或减去三角形或......嗯......如何称呼它们? ...图片中的黄色部分 :)
我认为没有简单的解决方案。
我会依次计算每个圆圈,并对所有其他圆圈执行布尔减法来解决这个问题。 (足够远的圆 - R0 + R1 < D12 - 不会干扰。)
吃完块后,圆变成由圆弧组成的曲线多边形,或者一组这样的多边形,因为连通性可以被打破。多边形可以由构成其轮廓弧的圆列表表示,弧端点由两个连续邻居的公共交点或目标圆和邻居的公共交点定义。请注意,同一个邻居可以出现多次。
为了让事情更血腥,多边形可以有洞,你也需要表现出来。
那么关键的操作就是曲线多边形减圆。您需要检测完全位于新圆圈内的圆弧和穿过新圆圈的圆弧。得到弧线的剩余部分后,您需要重新排列剩余的弧线和新的弧线。
我想所有这些操作都可以从一个单一的基元构建,该基元找到圆弧内的圆弧部分(由三个圆圈定义)。
这是一个粗略的解决方案:
- 取所有圆并找到所有个交点在测试圆T上或内部。分割相应的边和构建边图:
对于每条边,跟踪创建它的圆。
- 使用最小循环算法(Find all non-overlapping polygons in a list of edges/vertices)找到圆内所有非重叠区域。
对于你找到的每个区域R的每条边界线E,取E所属的圆C。如果 C 是 not T(红色)- 即 E 是蓝色,检查 R 的其他边缘上的点是否在 C:
内- 如果是,则 C 覆盖 R。继续下一个区域。
- 如果它们不是,则 R 不被 C 覆盖。循环围绕 R 的其他蓝色边缘。
- 如果最后 R 仍然 没有被覆盖,那么 T 就没有被完全覆盖 - return false.
上图中,C包含B,所以覆盖了R;但是C不包含A,所以不覆盖S
- 如果您在此阶段还没有 returned,那么 return true.
附带案例:
- 如果某个圈子里有T,就忽略它
- 如果 T 包含 it,则 延迟 通过将其存储在列表中来进行交集测试。最后重做测试并拆分它的边缘。
这个算法非常效率低下,我不能 100% 确定是否还有更退化的情况;如果有人有任何建议,请告诉我。