【问题标题】:Given a segmented circle and a point of impact, calculate the collided segment给定一个分段圆和一个撞击点,计算碰撞段
【发布时间】:2014-02-28 13:27:06
【问题描述】:

我有一个旋转的圆圈。例如,请参见下面的图片。圆被分成不同程度的线段,在这个例子中,我将圆分成三个相等的 120 度线段。

给定一个撞击点(圆外半径上的一个点),我计算圆心和撞击点之间的度数。然后,我需要确定受影响的细分市场。

我目前的解决方案是这样的:

var circleRotation = 270;
var segments = [120, 120, 120];
function segmentAtAngle(angle) {
    var sumTo = circleRotation;
    for (var i = 0, l = segments.length; l > i; i++) {
        if (sumTo <= angle && sumTo + segments[i] >= angle) {
            // return the segment
            return i;
        }
        sumTo += segments[i];
    }
}

我的解决方案并非在所有情况下都有效,假设有 270 的大偏移量,并且在请求影响程度为 45 的段时,我目前没有提供任何错误。

注意:为 segmentAtAngle 和 circleRotation 提供的角度也永远不会是负数或大于 360。我将度数标准化为 { degrees = degrees % 360; if (degrees &lt; 0) degrees += 360; return degrees; }

在给定偏移旋转的情况下,计算圆的命中段的正确方法是什么?

【问题讨论】:

    标签: math geometry trigonometry segment


    【解决方案1】:

    一个简单的临时解决方案是复制您的细分列表。然后你就覆盖了从 0° 到 2·360°=720° 的整个范围。如果 anglecircleRotation 介于 0° 和 360° 之间,如您所说,那么它们的总和将介于 0° 和 720° 之间,并且在所有情况下拥有两倍的段列表将产生匹配。如果生成的索引大于或等于原始未重复列表的长度,则可以减去该长度以从该原始列表中获取索引。

    【讨论】:

      【解决方案2】:

      首先,for 循环的条件看起来有点奇怪。 l 将始终大于零,因此循环将永远不会执行。其次,您可能应该在每次添加时标准化sumTo。第三,你在循环中返回angle,它永远不会改变。是否要返回受影响段的索引?

      var circleRotation = 270;
      var segments = [120, 120, 120];
      function standardize(degrees){
          degrees = degrees % 360; 
          if (degrees < 0) degrees += 360; 
          return degrees;
      }
      function segmentAtAngle(angle) {
          var sumTo = circleRotation;
          for (var i = 0; i<segments.length; i++) {
              if (sumTo <= angle && sumTo + segments[i] >= angle) {
                  return i;
              }
              sumTo = standardize(sumTo + segments[i]);
          }
      }
      

      【讨论】:

      • 我没有复制和粘贴我的代码,所以很明显我的帖子中有一些拼写错误。我将编辑我的原始帖子以修改这些错别字。
      • 标准化 sumTo 仍然无法处理我看到的用例。如果角度是 70 并且 circleRotation 是 342,那么您将直接跳过它,因为 sumTo > 角度开始,并且您只是在 if-for 循环中添加 sumTo 和 (sumTo
      【解决方案3】:

      函数atan2(DY, DX) 将给出从中心到任意点的角度。这个角度将在-pi to +pi 范围内。为了便于讨论,让我们将其转换为-180..+180° 范围。

      现在考虑分段的定界角度,就好像通过相同的函数获得:它们将对应于范围[-120..0][0..120][120, -120]。一切都很好,除了第三个区间跨越不连续性,它应该分成[120..180][-180..-120]

      最后,您应该考虑这个边界列表,以及相应的扇区:

         -180    -120      0      120     180
            Yellow |  Red  | Green | Yellow
      

      使用N 颜色,您需要考虑N+1 区间并与N 界限进行比较(无需检查极端值,它们已隐式实现)。您将通过线性或二分搜索(或在等距边界的情况下简单地重新缩放)来完成此操作。

      【讨论】:

        猜你喜欢
        • 2011-04-12
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多