【问题标题】:Average of two angles with wrap around [duplicate]环绕的两个角度的平均值[重复]
【发布时间】:2009-07-21 12:33:15
【问题描述】:

可能重复:
How do you calculate the average of a set of circular data?

我有两个角度,a=20 度和 b=350 度。这两个角度的平均值是 185 度。但是,如果我们考虑最大角度为 360 度并允许环绕,我们可以看到 5 度是更接近的平均值。

在计算平均值时,我很难想出一个很好的公式来处理这个问题。有人有任何提示吗?

或者我是在踢自己的脚吗?这在数学中被认为是“坏习惯”吗?

【问题讨论】:

  • 它确实和我的问题很相似,奇怪的是我找不到它。
  • 不是重复的。它与模算术有关,而不是特别是角度,并且由于必须处理任意数量的值的平均值,因此具有相当大的复杂性。
  • 这个问题本身是封闭的,因为它“没有重点”,它的最佳答案实际上回答了这个当前的问题,而不是那个问题。
  • 因此我认为我们应该重新提出这个问题。对于拥有权限的用户,有一个 [重新打开] 按钮。

标签: math average angle


【解决方案1】:

如果您看一下角圆,您会发现有 2 个相反的“角度”对应于您的“平均”。

所以 185° 和 5° 都是正确的。

但你提到了更接近的平均值。所以在这种情况下,你可以选择更接近的角度。

通常,角度的“平均值”涉及逆时针方向。如果您切换两个角度(或者如果您使用顺时针方向),“平均”就不一样了。

例如,对于a=20°b=350°,您正在寻找a 之后和b 之前的角度逆时针方向185° 就是答案.如果您正在寻找逆时针方向上ab 之后(或逆时针方向a 之后和b 之前)的角度, 就是答案。

this post的答案是正确的做法。

所以解决方案的伪代码是

if (a+180)mod 360 == b then
  return (a+b)/2 mod 360 and ((a+b)/2 mod 360) + 180 (they are both the solution, so you may choose one depending if you prefer counterclockwise or clockwise direction)
else
  return arctan(  (sin(a)+sin(b)) / (cos(a)+cos(b) )

【讨论】:

  • 是的,我正在寻找更接近的平均值。
  • a 为 180,b 为 270,我得到 math:atan( (math:sin(180)+math:sin(270)) / (math:cos(180)+math:因为(270)))。 -1.1946710584651132 没有预期
  • 我已经测试过了,它是正确的。但不幸的是,我们必须使用所有这些三角函数。
【解决方案2】:

只需取一个正常的平均值,然后取模 180。在您的示例中,这给出了 5 度,正如预期的那样。

【讨论】:

  • Stecys 回答状态采用 mod 360,这在我尝试的几次尝试中似乎有效。360 失败而 180 成功的地方在哪里?
  • 取平均值如 (a+b)/2 然后 mod 180 与先做 (a+b) mod 360 然后除以 2 完全相同。两者是等价的。
  • 这不起作用。示例:角度 1 = 280,角度 2 = 10,它们的平均值为 325。您的公式给出 145。
  • 不完全。从某种意义上说,平均值是平分两个角度的角度,您可以借助一个简单的图表看到两个答案是等价的..
  • 我投了反对票,因为公式不起作用。这个问题看似很难。
【解决方案3】:

试试这个(C# 中的示例):

    static void Main(string[] args)
    {
        Console.WriteLine(GetAngleAverage(0,0));
        Console.WriteLine(GetAngleAverage(269, 271));
        Console.WriteLine(GetAngleAverage(350, 20));
        Console.WriteLine(GetAngleAverage(361, 361));
    }

    static int GetAngleAverage(int a, int b)
    {
        a = a % 360;
        b = b % 360;

        int sum = a + b;
        if (sum > 360 && sum < 540)
        {
            sum = sum % 180;
        }
        return sum / 2;
    }

我认为它有效,输出是

0
270
5
1

【讨论】:

  • 我认为您想删除 if() 块内的“返回”。 GetAngleAverage(350,20) 应该是 5,而不是 10。
  • “sum > 360”行应该是“sum >= 360”。否则 350 度和 10 度的平均角度会变成 180 度,这不是您想要的。
  • 这种方法190和190的平均值也会变成10。所以...我认为这种方法行不通。
  • 我同意,这种方法行不通。请投反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多