在c ++代码中处理Angle Wrap

时间:2012-07-16 04:38:15

标签: c++ math

是否有安全方法,只需使用最少数量的case语句处理角度换行。

当使用角度的特定表示(0-360度或-180-180度(或等效弧度))并且包裹角度时,会发生角度换行。例如,假设您的角度为-170,则减去50度。你在数学上加起来到-220但实际上应该是+140度。

显然你可以使用以下方式检查:

if (deg < -180) { 180 - abs(deg + 180); }

或类似的。但首先你需要进行大量检查,其次如果你换了两次就不行。

这种情况普遍存在的第二种情况是两个角度之间的插值。

例如,假设我的角度为-170度和160度,我想要它们之间的中间位置。执行此操作的常见方法是ang1 + 0.5(ang2-ang1),但在我提供的示例中,如果角度为175,则会导致角度为-5度。

在这些情况下是否有一种处理角度换行的常用方法?

6 个答案:

答案 0 :(得分:55)

为了完整性,我将同时包含[0, 360)[-180, 180)规范化。

您需要#include <math.h>


标准化为[0,360)

double constrainAngle(double x){
    x = fmod(x,360);
    if (x < 0)
        x += 360;
    return x;
}

标准化为[-180,180)

double constrainAngle(double x){
    x = fmod(x + 180,360);
    if (x < 0)
        x += 360;
    return x - 180;
}

模式应该足够容易识别以概括为弧度。


角度分割:

double angleDiff(double a,double b){
    double dif = fmod(b - a + 180,360);
    if (dif < 0)
        dif += 360;
    return dif - 180;
}
double bisectAngle(double a,double b){
    return constrainAngle(a + angleDiff(a,b) * 0.5);
}

这应该将“较小”侧的角度平分。 (警告:尚未完全测试)

答案 1 :(得分:11)

我发现使用数学库中的remainder()很方便。给定角度a,要将其约束为-180,180,您可以这样做:

remainder(a, 360.0);

并将360.0更改为2.0 * M_PI以获得弧度

答案 2 :(得分:5)

因此,如果找到一种方法来有效地做我想要的使用Mystical的方法来约束角度。这是:

enter image description here

这似乎适用于我能想到的任何例子。

答案 3 :(得分:3)

将角度标准化为范围[-180, 180)

deg -= 360. * std::floor((deg + 180.) * (1. / 360.));

将角度标准化为范围[0, 360)

deg -= 360. * std::floor(deg * (1. / 360.));

示例:

deg = -90 - &gt; [0, 360)

deg -= 360. * std::floor(-90 / 360.);
deg -= 360. * -1;
deg = 270

deg = 270 - &gt; [-180, 180)

deg -= 360. * std::floor((deg + 180.) / 360.);
deg -= 360. * std::floor(480. / 360.);
deg -= 360. * 1.;
deg = -90;

请参阅:http://en.cppreference.com/w/cpp/numeric/math/floor

答案 4 :(得分:0)

我知道这是一个旧线程,但试试这个:

double angleRef(double thtIn, double thtRef){
  tht = fmod(thtIn + (180-thtRef),360) + (thtRef-180);
  return tht;
}

就像在你的例子中,如果 A=-170 和 B=160,那么它们中间的角度是 A + 0.5*(angleRef(B,A) - A) = -185

或者如果您更喜欢 A=160 和 B=-170 A + 0.5*(angleRef(B,A) - A) = 175

请原谅任何 c++ 格式错误,它不是我的母语。

答案 5 :(得分:-1)

将角度(+ PI~-PI)映射到有符号的int值(或短值):

angle_signed_short = angle_float / PI * 0x7FFFF;

然后您可以正常添加或子值。然后回映:

angle_float = angle_signed_short * PI / 0x7FFFF;