35

有没有一种安全的方法,可以用最少的案例语句简单地处理角度环绕。

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

显然,您可以使用以下方法进行检查:

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

或类似的。但首先你需要大量的检查,其次如果你包装两次它就不起作用。

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

例如,假设我有一个 -170 度和 160 度的角度,我想介于它们之间。一种常见的方法是,ang1 + 0.5(ang2-ang1)但在我提供的示例中,它将导致角度为 -5 度,而它应该是 175 度。

在这些情况下是否有处理角度包络的常用方法?

4

6 回答 6

68

为了完整起见,我将同时包括规范化[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);
}

这应该在“较小”一侧平分一个角度。(警告:未完全测试)

于 2012-07-16T04:48:03.620 回答
20

我发现使用remainder()数学库很方便。给定一个角度a,将其限制为 -180, 180 你可以这样做:

remainder(a, 360.0);

并将弧度更改360.02.0 * M_PI

于 2012-07-16T11:44:54.847 回答
8

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

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

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

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

例子:

deg = -90-> [0, 360)

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

deg = 270-> [-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

于 2017-05-04T10:33:56.140 回答
5

因此,如果想出一种方法来有效地使用 Mystical 的方法来约束角度。这里是:

在此处输入图像描述

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

于 2012-07-17T00:14:44.240 回答
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++ 格式错误,它不是我的母语。

于 2021-03-25T22:02:43.093 回答
-1

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

angle_signed_short = angle_float / PI * 0x7FFFF;

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

angle_float = angle_signed_short * PI / 0x7FFFF;
于 2015-11-24T09:06:09.620 回答