计算旋转 > 360 度。情况

发布于 2024-08-26 18:32:30 字数 574 浏览 8 评论 0原文

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

通常在处理角度时,如果角度超过 360 度,则该角度会继续旋转并有效地“重置”——即角度“重新开始”,例如 357 度、358 度、359 度、0 度、1 度等。我想要发生的是继续增加的度数 - 即 357 度、358 度、359 度、360 度、361 度等。我想修改我的数据,以便在其中包含转换后的数据。

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

具有 360 度的倍数(正数和负数) ,我希望度数继续,例如 720 度等。

关于采取什么方法有什么建议吗?毫无疑问,有一种令人沮丧的简单方法可以做到这一点,但我目前的解决方案至少可以说是笨拙的......!迄今为止,我最好的尝试是查看角度 n 和角度 n - 1 之间的百分比差异。如果这是一个很大的差异 - 例如 > > 1。 60%——则需要根据之前的角度值对当前值添加或减去 360 度来进行修改。也就是说,如果前一个角度为负,则减去 360,如果前一个角度为正,则加 360。

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

I'm trying to work out a problem I'm having with degrees. I have data that is a list of of angles, in standard degree notation -- e.g. 26 deg.

Usually when dealing with angles, if an angle exceeds 360 deg then the angle continues around and effectively "resets" -- i.e. the angle "starts again", e.g. 357 deg, 358 deg, 359 deg, 0 deg, 1 deg, etc. What I want to happen is the degree to continue increasing -- i.e. 357 deg, 358 deg, 359 deg, 360 deg, 361 deg, etc. I want to modify my data so that I have this converted data in it.

When numbers approach the 0 deg limit, I want them to become negative -- i.e. 3 deg, 2 deg, 1 deg, 0 deg, -1 deg, -2 deg, etc.

With multiples of 360 deg (both positive and negative), I want the degrees to continue, e.g. 720 deg, etc.

Any suggestions on what approach to take? There is, no doubt, a frustratingly simple way of doing this, but my current solution is kludgey to say the least .... ! My best attempt to date is to look at the percentage difference between angle n and angle n - 1. If this is a large difference -- e.g. > 60% -- then this needs to be modified, by adding or subtracting 360 deg to the current value, depending on the previous angle value. That is, if the previous angle is negative, substract 360, and add 360 if the previous angle is positive.

Any suggestions on improving this? Any improvements?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

难如初 2024-09-02 18:32:30

您所说的是一种 unwrap 算法,它具有概括性(不特定于数字 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;
}

这是一个示例输出:

js>unwrap([100, 200, 348, 359, 23, 37, 46, 10, 350, 190], 360)
100,200,348,359,383,397,406,370,350,190

另一个 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;
}

What you're talking about is an unwrap algorithm, which generalizes (not specific to the number 360... you could do it in radians with m=2*pi). Here's one in 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;
}

And here's a sample output:

js>unwrap([100, 200, 348, 359, 23, 37, 46, 10, 350, 190], 360)
100,200,348,359,383,397,406,370,350,190

another one with 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

FYI: In C/Java/etc. a similar algorithm exists for bit extension, where the inputs are, say, 16 bits and the output is 32 bits, and the wraparound modulus m = 65536 = the span of input values. You don't need an "smod" function, just use signed math:

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;
}
咋地 2024-09-02 18:32:30

您能否继续添加/减去所有度数,然后对最终结果使用 MODULUS 运算符 360。这将为您提供剩余的度数。

Can you just keep adding / subtracting all of your degrees and then use a MODULUS operator on the final result with 360. This will give you the remaining degrees.

一向肩并 2024-09-02 18:32:30

使用某种方法计算每个角度与前一个角度的差值,以确保在两个方向穿过 0/360 时获得正确的符号。然后将此差异添加到不滚动的累计总额中。

Take the difference of each angle and the previous one using some method to ensure you get the correct sign when crossing 0/360 in both directions. Then add this difference to a running total that does not roll over.

同展鸳鸯锦 2024-09-02 18:32:30

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

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

然后在循环结束时,数据集将包含所有数据,按照您指定的方式添加。

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

If I understand the problem correctly, this might work:

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

Then at the end of the loop, the dataset will contain all of the data, added up as you've specified.

So basically loop through the dataset, and add the difference to the running total. The running total becomes each data piece as you iterate.

混吃等死 2024-09-02 18:32:30

该 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);
}

This C program takes a list of angles in the range 0 to 359 degrees from standard input and
prints unbounded values to standard output by accumulating changes in angles. Wrap around is detected by assuming a maximum possible change in angle per input.

#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);
}
夏花。依旧 2024-09-02 18:32:30

使用模函数

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);

Use modulous function

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文