Lio*_*gan 18 algorithm math geometry
我想计算一组角度的平均值,它代表源轴承(0到360度) - (类似于风向)
我知道之前已经讨论过(好几次).接受的答案是从角度计算单位向量并取其平均值的角度.
然而,这个答案以非直观的方式定义了平均值.平均0,0和90将是atan((sin(0)+ sin(0)+ sin(90))/(cos(0)+ cos(0)+ cos(90)))= atan(1/2)= 26.56度
我希望0,0和90的平均值为30度.
所以我认为再问这个问题是公平的:你如何计算平均值,所以这些例子将给出直观的预期答案.
编辑2014:
在提出这个问题后,我发布了一篇关于CodeProject的文章,该文章提供了全面的分析.本文探讨了以下参考问题:
pet*_*ust 18
[ 注意 OP的问题(但不是标题)似乎已经变成了一个相当专业的问题("...每个连续加法与运行平均值相差超过指定数量的角度序列的平均值." ) - 见@MaR评论和我的.我的以下答案涉及OP的标题以及与之相关的大部分讨论和答案.]
这不是逻辑或直觉的问题,而是定义的问题.在没有任何真正共识的情况下,已在SO上对此进行了讨 角度应该在一个范围内定义(可能是-PI到+ PI,或0到2*PI或者可能是-Inf到+ Inf.答案在每种情况下都会有所不同.
世界的"角度"会引起混乱,因为它意味着不同的东西.的视角是一个无符号的数量(和通常是PI> THETA> 0在此情况下,"正常的"平均可能是有用的.旋转角度(例如,如果一个滑冰总旋转)可能会或可能不会被签名,并且可能包括theta> 2*PI和theta <-2*PI.
这里定义的是angle = direction whihch需要向量.如果你使用"方向"而不是"角度"这个词,你将获得OP(明显的原始)意图,它将有助于摆脱标量.
当角度被循环定义时,维基百科显示正确的方法
theta = theta+2*PI*N = theta-2*PI*N
Run Code Online (Sandbox Code Playgroud)
平均值的答案不是标量而是矢量.OP可能不觉得这很直观,但它是唯一有用的正确方法.我们不能将-4的平方根重新定义为-2,因为它更具有本质 - 它必须是+ -2*i.类似地,轴承-90度和+90度的平均值是零长度的矢量,而不是0.0度.
维基百科(http://en.wikipedia.org/wiki/Mean_of_circular_quantities)有一个特殊的部分和状态(方程式是LaTeX,可以在维基百科中看到):
大多数通常的方法都失败了圆形量,如角度,白天,实数的小数部分.对于那些数量,您需要平均数量的圆形.
由于算术平均值对角度无效,因此可以使用以下方法获得平均值和角度方差的度量:
将所有角度转换为单位圆上的对应点,例如α到(cosα,sinα).这是将极坐标转换为笛卡尔坐标.然后计算这些点的算术平均值.结果点将位于单位磁盘上.将该点转换回极坐标.角度是输入角度的合理平均值.如果所有角度相等,则得到的半径为1.如果角度均匀分布在圆上,则得到的半径将为0,并且没有圆形平均值.换句话说,半径测量角度的浓度.
给定角度\ alpha_1,\ dots,\ alpha_n,均值由计算得出
Run Code Online (Sandbox Code Playgroud)M \alpha = \operatorname{atan2}\left(\frac{1}{n}\cdot\sum_{j=1}^n\ sin\alpha_j,\ frac {1} {n}\cdot\sum_ {j = 1} ^ n\cos\alpha_j\right)
使用arctangent函数的atan2变体,或
Run Code Online (Sandbox Code Playgroud)M \alpha = \arg\left(\frac{1}{n}\cdot\sum_{j=1}^n\ EXP(I\CDOT\alpha_j)\右)
使用复数.
请注意,在OP的问题中,角度0完全是任意的 - 从0到0而不是180的风来说没有什么特别的(除了在这个半球,它在自行车上更冷).尝试将0,0,90更改为289,289,379并查看简单算法如何不再起作用.
(这里有一些发行,其中的0和PI的角度有着特殊的意义,但他们不是在这里的范围).
以下是一些激烈的先前讨论,反映了当前的观点传播:-)
http://mathforum.org/library/drmath/view/53924.html
http://forums.xkcd.com/viewtopic.php?f=17&t=22435
http://www.allegro.cc/forums/thread/595008
谢谢大家帮助我更清楚地看到我的问题.
我找到了我要找的东西.它被称为Mitsuta方法.
输入和输出在[0..360]范围内.
该方法适用于平均使用恒定采样间隔采样的数据.
该方法假设连续样本之间的差异小于180度(这意味着如果我们不能足够快地采样,则采样信号中的330度变化将被错误地检测为另一个方向上的30度变化并且将在计算中插入错误).奈奎斯特 - 香农采样定理任何人?
这是一个c ++代码:
double AngAvrg(const vector<double>& Ang)
{
vector<double>::const_iterator iter= Ang.begin();
double fD = *iter;
double fSigD= *iter;
while (++iter != Ang.end())
{
double fDelta= *iter - fD;
if (fDelta < -180.) fD+= fDelta + 360.;
else if (fDelta > 180.) fD+= fDelta - 360.;
else fD+= fDelta ;
fSigD+= fD;
}
double fAvrg= fSigD / Ang.size();
if (fAvrg >= 360.) return fAvrg -360.;
if (fAvrg < 0. ) return fAvrg +360.;
return fAvrg ;
}
Run Code Online (Sandbox Code Playgroud)
第51页的http://www.epa.gov/scram001/guidance/met/mmgrma.pdf对此进行了解释
感谢MaR发送链接作为评论.
如果采样数据是常数,但我们的采样设备具有Von Mises分布的不准确性,则单位矢量计算将是合适的.