Math 给定一个分段圆和一个碰撞点,计算碰撞的分段

Math 给定一个分段圆和一个碰撞点,计算碰撞的分段,math,geometry,trigonometry,segment,Math,Geometry,Trigonometry,Segment,我有一个旋转的圆。例如,请参见下面的图片。圆被划分为不同度数的段,在本例中,我将圆划分为三个相等的120度段 给定一个撞击点(圆外半径上的一点),我计算圆心和撞击点之间的度数。然后我需要确定哪个部分受到影响 我当前的解决方案是这样的: var circleRotation = 270; var segments = [120, 120, 120]; function segmentAtAngle(angle) { var sumTo = circleRotation; for

我有一个旋转的圆。例如,请参见下面的图片。圆被划分为不同度数的段,在本例中,我将圆划分为三个相等的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];
    }
}
var循环旋转=270;
var段=[120,120,120];
功能段角度(角度){
var sumTo=循环旋转;
对于(变量i=0,l=segments.length;l>i;i++){
如果(sumTo=角度){
//返回段
返回i;
}
sumTo+=段[i];
}
}
我的解决方案并非在所有情况下都有效,假设偏移量很大,比如270,并且当请求冲击度为45的分段时,我目前没有提供任何信息

注:提供的节段角度角度和圆周旋转也永远不会为负或大于360。我通过
{degrees=degrees%360;if(degrees<0)degrees+=360;return degrees;}


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

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

首先,您的
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]);
    }
}
var循环旋转=270;
var段=[120,120,120];
功能标准化(度){
度=360度;
如果(度<0)度+=360;
返回度;
}
功能段角度(角度){
var sumTo=循环旋转;
对于(var i=0;i函数
atan2(DY,DX)
将给出从中心到任意点的角度。该角度将在
-pi到+pi的范围内。为了便于讨论,让我们将其转换为
-180..+180°
范围

现在考虑你的段的定界角,好像通过相同的函数得到的:它们将对应于范围<代码> [-C.[/Cord],<代码> [0…120 ] < /> >和<代码> [120,-120 ] < /代码>。除了第三个间隔跨越不连续性外,一切都很好,并且应该被分成<代码> [120…180 ] < /代码>和<代码>。[-180..-120]

最后,您应该考虑这个界限,对应的扇区:

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

使用<代码> N< /代码>颜色,您需要考虑<代码> N+ 1 间隔,并与<代码> N< /代码>界限(不需要检查极端值,它们被隐式实现)。您将通过线性或二分查找(或者在等距边界的情况下简单的重新缩放)来实现这一点。.

我没有复制和粘贴我的代码,因此我的帖子中显然有一些拼写错误。我将编辑我的原始帖子以修改这些拼写错误。标准化sumTo仍然不能处理我看到的用例。如果角度是70,圆圈旋转是342,那么您将直接跳过它,因为sumTo>angle开始,而您只是添加到sumTo和(sumTo)