【问题标题】:Finding if a circle is inside another circle查找一个圆圈是否在另一个圆圈内
【发布时间】:2012-02-28 17:13:30
【问题描述】:

我有点麻烦。我有一个任务,要求我找出第二个圆圈是否重叠、在里面,或者两个圆圈都没有。但是,我无法检查重叠以及第二个圆圈是否在第一个圆圈内。

(使用的变量是x1,x2,y1,y2,r1,r2,距离)

这是我所拥有的:

if (distance > (r1 + r2)) {
        // No overlap
        System.out.println("Circle2 does not overlap Circle1");
    } else if (distance <= Math.abs(r1 + r2)) {
        // Overlap
        System.out.println("Circle2 overlaps Circle1");
    } else if ((distance <= Math.abs(r1 - r2)) {
        // Inside
        System.out.println("Circle2 is inside Circle1");
}

我担心问题出在重叠检查和内部检查上,但我不知道如何正确设置它,因此我可以可靠地检查第二个圆圈是否在第一个圆圈内。

任何帮助或建议将不胜感激,因为我尝试了多种方法,但解决方案每次都让我无法理解。

【问题讨论】:

  • 首先 - 什么是距离?是圆心之间的距离吗?第二 - 找出哪个半径更大可能会有所帮助吗?
  • 所有变量均由用户输入。是的,距离就是两个圆的两个圆心之间的距离,用距离公式。
  • 我刚刚用谷歌搜索了这个问题并找到了这个gamedev.stackexchange.com/questions/7172/…
  • 我认为中心之间的距离是关键......以及你做测试的顺序......
  • 太棒了,谢谢,这会很有帮助。

标签: java math


【解决方案1】:

您只需要在重叠之前检查内部,因为内部的距离是

if (distance > (r1 + r2)) 
{
    // No overlap
    System.out.println("Circle2 does not overlap Circle1");
}
else if ((distance <= Math.abs(r1 - r2)) 
{
    // Inside
    System.out.println("Circle2 is inside Circle1");
}
else              // if (distance <= r1 + r2)
{
   // Overlap
   System.out.println("Circle2 overlaps Circle1");
} 

根据 Chris 的 cmets 修改答案

【讨论】:

  • 是的,那是我的问题。我以前尝试过一次,但我认为我用错误的比较命令它错了。再次感谢。
  • 你那里有不必要的代码。由于 r1 和 r2 都 >0 (我假设它们是半径),因此 r1+r2 不需要在它周围调用 abs 。然后,如果您将此检查与您的第一个检查进行比较,那么您会注意到如果第一个为 false,它将始终尝试,因此您可以跳过条件并将最后一个设置为普通 else。
  • 我知道我只是重新排列了原始问题中的代码,但这是一个很好的观点,我会发表评论。
  • 你所做的表明这是正确的测试,但它不是。如果你有正确的测试,那么你做它们的顺序并不重要。你的答案有效的唯一原因是你的最终测试碰巧总是评估为真。
【解决方案2】:

这个问题可能最容易先从视觉上解决,然后再编写代码。你看起来有正确的逻辑,不进入内部和完全进入内部。

解决这个问题的简单方法是,如果它们不是完全在里面,也不是完全在外面,那么它们一定是重叠的。这当然是我的编码方式。数学比其他两个要复杂一些。

if (distance > (r1 + r2)) {
    // No overlap
    System.out.println("Circle2 does not overlap Circle1");
} else if ((distance <= Math.abs(r1 - r2)) {
    // Inside
    System.out.println("Circle2 is inside Circle1");
{ else {
    // Overlap
    System.out.println("Circle2 overlaps Circle1");
}

实际情况是:

r2&gt;r1-dr2 &lt; r1+d

通过对称,我们不需要双向进行(如果你交换 r2 和 r1 并重新排列,你会得到相同的方程组)。

除非出于某种原因需要,否则最简单的方法是将其保留在“else”类别中,而不是对其进行编码。

【讨论】:

    【解决方案3】:

    好吧,如果距离和较小半径之和小于另一个半径,则较小的圆应该在较大的圆内。

    【讨论】:

    • 仅当中心彼此足够接近时,否则,您可能会有重叠甚至不重叠的圆圈。
    • @JonathanDrapeau。对不起,但这不是真的。好吧,至少,只要 distance 表示两个中心之间的距离。如果中心足够远以至于圆相交,那么我们可能有两种情况:a)一个圆的中心在另一个圆内 => d+r2 > r1 || d+r1 > r2 ;或 b) 没有圆心在另一个圆内 => d>r1 || d>r2 已经。
    【解决方案4】:

    你就快到了。只是条件的顺序不对。

    if (distance > (r1 + r2)) {
            // No overlap
            System.out.println("Circle2 does not overlap Circle1");
        } else if ((distance <= Math.abs(r1 - r2)) {
            // Inside
            System.out.println("Circle2 is inside Circle1");
        } else {
            // Overlap
            System.out.println("Circle2 overlaps Circle1");
    }
    

    在“非重叠”案例之后检查“内部”案例可确保它不会被意外视为重叠。那么其余的都必须是重叠的。

    【讨论】:

    • 你和 Dampsquid 是对的。我以前试过这个,但我搞砸了比较,所以每次都回来错了。
    【解决方案5】:

    通过评论代理进行编辑以确保显而易见性:

    到空间点之间的距离由毕达哥拉斯描述:

      distance = sqrt( travelled_x_squared + travelled_y_squared );
    

    这当然转化为代码

      distance = Math.sqrt(  (x1-x2)*(x1-x2) + (y1 - y2)*(y1 - y2) );
    

    距离在 r1 + r2 处接触。

    编辑前的线索: 你需要圆圈之间的角度。

    然后你计算从圆 1 到圆 2 的距离。如果它小于半径 1 + 半径 2,你就在里面。

    atan2 可能是一个感兴趣的函数。

    或者直接使用毕达哥拉斯距离。

    【讨论】:

    • 角度完全无关。您总是可以只考虑通过两个中心的线和沿这些线的距离(距离,r1,r2)。
    • @Chris 是的,这是毕达哥拉斯距离。
    • 我不确定这是否解释了您认为需要角度的原因。您只会使事情复杂化,而 atan2 确实对这个问题不感兴趣,并且会引导您走上错误解决方案的道路...
    • @Chris 我只是想对许多标记为 Java、数学和家庭作业的建议提供帮助。所有的途径都有自己的回报,没有一个错误的解决方案。我不知道你为什么写那个。
    • 我不相信任何可以被认为是正确的解决方案都会使用三角函数。我什至不确定您是否需要 xn,yn,因为我们得到了两点之间的距离。如果您开始使用角度,您很可能会做一些可以大大简化的事情。例如,即使假设我们已经没有距离,您也可以使用 arctan 从给定的 x 和 y 计算出角度,然后使用 sin/cos 计算出两点之间的距离,但这仍然不是一个好方法它(因此我会说错)因为你可以使用毕达哥拉斯定理来做到这一点(就像你所做的那样)。
    【解决方案6】:

    这是一个简单的任务,

    取两个圆的半径之和。说 r1+ r2 。 现在找到两个圆心之间的距离,即 sqrt((x1-x2)^2 + (y1-y2)^2) if r1+r2 = sqrt((x1-x2)^2 + (y1-y2)^2) they just touch each other. if r1+r2 > sqrt((x1-x2)^2 + (y1-y2)^2) the circle overlaps(intersect) if r1+ r2 < sqrt((x1-x2)^2 + (y1-y2)^2) the circle doesnot intersect

    【讨论】:

      【解决方案7】:
      /**
         *
         * @param values { x0, y0, r0, x1, y1, r1 }
         * @return true if circles is intersected
         */
        public static boolean isCircleIntersect(double... values)
        {
          /* check using mathematical relation: ABS(R0-R1) <= SQRT((x0-x1)^2+(y0-y1)^2) <= (R0+R1) */
          if (values.length == 6)
          {
            /* get values from first circle */
            double x0 = values[0];
            double y0 = values[1];
            double r0 = values[2];
            /* get values from second circle */
            double x1 = values[3];
            double y1 = values[4];
            double r1 = values[5];
            /* returun result */
            return (Math.abs(r0 - r1) <= Math.sqrt(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2)))
                    && (Math.sqrt(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2)) <= (r0 + r1));
          }
          else
          {
            /* return default result */
            return false;
          }
        }
      

      【讨论】:

      • 您应该使用代码按钮将其格式化为源代码。
      猜你喜欢
      • 1970-01-01
      • 2011-03-10
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 2021-07-27
      • 2018-12-15
      相关资源
      最近更新 更多