Math 在>;360度情况

Math 在>;360度情况,math,rotation,trigonometry,Math,Rotation,Trigonometry,我正在努力解决我的学位问题。我有一个角度列表的数据,用标准度表示法——例如26度 通常,在处理角度时,如果角度超过360度,则该角度继续旋转并有效地“重置”——即角度“再次开始”,例如357度、358度、359度、0度、1度等。我希望发生的是继续增加的角度——即357度、358度、359度、360度、361度,等。我想修改我的数据,使我有这个转换后的数据在其中 当数字接近0度极限时,我希望它们变成负数——即3度、2度、1度、0度、-1度、-2度等 对于360度的倍数(正负),我希望度数继续,例如

我正在努力解决我的学位问题。我有一个角度列表的数据,用标准度表示法——例如26度

通常,在处理角度时,如果角度超过360度,则该角度继续旋转并有效地“重置”——即角度“再次开始”,例如357度、358度、359度、0度、1度等。我希望发生的是继续增加的角度——即357度、358度、359度、360度、361度,等。我想修改我的数据,使我有这个转换后的数据在其中

当数字接近0度极限时,我希望它们变成负数——即3度、2度、1度、0度、-1度、-2度等

对于360度的倍数(正负),我希望度数继续,例如720度,等等

关于采取什么方法有什么建议吗?毫无疑问,这是一种令人沮丧的简单方法,但至少可以说,我目前的解决方案是困难的!到目前为止,我最好的尝试是观察角度n和角度n-1之间的百分比差异。如果这是一个很大的差异(例如>60%),则需要根据之前的角度值,通过向当前值添加或减去360度来修改此差异。也就是说,如果上一个角度为负,则减去360,如果上一个角度为正,则添加360


有什么改进的建议吗?有什么改进吗?

您可以继续添加/减去所有度数,然后在最终结果上使用模运算符360。这将为您提供剩余的度数。

如果我正确理解问题,这可能会起作用:

int prev=[first data piece in data set]
int total=prev
foreach data in [the rest of the data set]
    total+=data-prev
    prev=data
    data=total
然后在循环结束时,数据集将包含所有数据,这些数据按照您指定的方式相加


因此,基本上循环遍历数据集,并将差异添加到运行总数中。当您迭代时,运行总数将成为每个数据块。

使用某种方法获取每个角度与上一个角度的差值,以确保在两个方向上通过0/360时得到正确的符号。然后将此差异添加到不翻滚的运行总数中。

此C程序从标准输入和输出获取0到359度范围内的角度列表 通过累积角度变化,将无界值打印到标准输出。通过假设每个输入角度的最大可能变化来检测环绕

#include <stdio.h>
#include <stdlib.h>

int
main()
{
    const float MAX_DELTA = 180.f;          /* highest expected change */
    float previous, next, delta, output;

    /* set the initial value */
    if (EOF == scanf("%f", &next))
        exit(0);   
    previous = next;
    output = previous;

    do {
        /* calculate the change in angle and adjust if too big */
        delta = next - previous;
        if (MAX_DELTA < delta)
            delta -= 360.f;
        else if (-MAX_DELTA > delta)
            delta += 360.f;

        /* accumlate the changes without wrap-around */
        output += delta;
        printf("%f\n", output);

        /* store the value for calculating the next delta */
        previous = next;

        /* read angle values until end of file is reached */
    } while (EOF != scanf("%f", &next));

    exit(0);
}
#包括
#包括
int
main()
{
常量浮点最大值_DELTA=180.f;/*最高预期变化*/
浮动上一个、下一个、增量、输出;
/*设置初始值*/
如果(EOF==scanf(“%f”,&next))
出口(0);
上一个=下一个;
输出=以前的输出;
做{
/*计算角度变化,如果太大,则进行调整*/
delta=下一个-上一个;
如果(最大增量<增量)
δ-=360.f;
否则如果(-MAX_DELTA>DELTA)
δ+=360.f;
/*累积更改而不进行环绕*/
输出+=增量;
printf(“%f\n”,输出);
/*存储用于计算下一个增量的值*/
上一个=下一个;
/*读取角度值,直到到达文件末尾*/
}而(EOF!=scanf(“%f”,&next));
出口(0);
}
使用模块化函数

static inline float GetAbsoluteModulous(float input ,float devisor )
{
    double output = (devisor==0)?input:fmod(input, devisor);
    return (output>0)?output:devisor+output;
} 

angle = GetAbsoluteModulous(angle,360);

你所说的是一个
展开算法,它概括了(不特定于360这个数字…你可以用m=2*pi的弧度来做)。以下是javascript中的一个:

/*  symmetric modulo: 
 *  y = smod(x,m) = x+k*m where k is an integer,
 *  and y is always in the range [-0.5,0.5)*m
 */
function smod(x, m)
{
  return x-((Math.floor(x/m + 0.5))*m);
}

/*  unwrap:
 *  for all i, y[i] = x[i] + k*m where k is an integer,
 *  and for i > 0, the increment y[i]-y[i-1] is in the
 *  range [-0.5,0.5)*m as in smod().
 *
 *  the "init" parameter is optional (default to 0)
 *  and specifies the starting value for the unwrap state.
 */ 

function unwrap(x, m, init)
{
  var yi = init || 0;
  var y = [];
  for (i = 0; i < x.length; ++i)
  {
     yi += smod(x[i]-yi, m);
     y[i] = yi;
  }    
  return y;
}
另一个m=100:

js>unwrap([99,1,7,60,80,22,30,20,90,88,61,23,2,87,50,12], 100, 1000)
999,1001,1007,960,980,1022,1030,1020,990,988,961,923,902,887,850,812
仅供参考:在C/Java/etc中,存在一种类似的位扩展算法,其中输入为16位,输出为32位,环绕模m=65536=输入值的范围。您不需要“smod”函数,只需使用符号数学:

typedef short int16_t;
typedef long  int32_t;
// do typedefs as appropriate on your CPU

int32_t unwrap_extend(int32_t prev, int16_t input)
{
  int16_t delta = input - prev;
  return prev + delta;
}

我想我理解你的问题,但是一个简短的输入和期望输出的例子将非常有助于澄清问题。你能提供更多关于你拥有的数据的信息吗?你能提供一些样本数据吗?每个数据段都是一个旋转,还是一个新的旋转度?我可以认为这是含糊不清的,除非对每一条数据之间的程度差异存在限制。编辑:+1@法官击败了我:)可以对角度的变化率做出什么假设?换句话说,你测量的是什么物理角度?从359到2时,data prev不起作用。解决方案是正确的,除了不做这个区别。??这是相当模糊的,我不认为这是OP所要求的。很好的答案,smod在直接使用弧度时非常有用。为我做的工作!谢谢
typedef short int16_t;
typedef long  int32_t;
// do typedefs as appropriate on your CPU

int32_t unwrap_extend(int32_t prev, int16_t input)
{
  int16_t delta = input - prev;
  return prev + delta;
}