zoukankan      html  css  js  c++  java
  • 循环的角度求均值

    为什么会讨论到这么简单的问题?

    举几个样例,角度范围为0~360度,0度和360度是重合的,最好还是先算法以下角度的均值,

    [10, 30] = 20 结果正确

    [20, 100] = 60 结果正确

    [160, 200]= 180 结果正确

    [0, 360] = 180 由于360度和0度重合,这个结果貌似不是我们想要的,结果360度才合理

    [20, 300] = 160 要能求得均值为340度就好了

    不知看出什么问题没有——角度求均值不再是简单的算术均值!

    修正的0~360度求均值方案

    从上面的结果也能够知道,有些情况下角度均值就是算术平均值,那什么情况下不是求算术平均值呢?

    1

    如上图,当α<β时,当β-α > 180时,(α+β)/2不再是要求的结果;同理,α<β时,α-β > 180时不再是求算术平均值。

    综合这两种情况,当|α-β|>180情况下不是求算术平均值。这样的情况下期望的角度均值为(以α小于β为例):

    同理,由于上面的表达式中的α与β对称,所以α大于β计算的结果也一样。因此可知,非算术平均值的情况仅仅要在算术平均值的基础上加180就能够了,因此归纳例如以下:

    上面仅是两个角度值的平均,通过两个角度的差值做判别条件确定是否是算术均值,然而,多个的呢?

    多个的角度均值显得有些复杂,这须要用户对输入输出角度范围提供约束,这里最好还是将命题变成:考虑到相邻角度在时间上的相关性,设相邻的两个输入角度值偏移值不会大于180度,在这样的情况下,仅仅要考虑0~360度的突变情况就能够了。

    直接看matlab程序吧(參考资料2),

    function [avg] = avg_degree(angles)
    % 计算角度平均值,注意0-360度情况
    
    last = angles(1);
    sum = angles(1);
    for i=2:length(angles)
        diff = mod(angles(i)-angles(i-1)+180,360)-180;
        last = last + diff;
        sum = sum + last;
    end
    avg = mod(sum/length(angles), 360);
    
    end
    

    给个自己使用的C程序也有,仅仅只是求模用条件运算替换了,

    #define ANGLE_DIFF(diff, x2, x1) 
    do {  
        diff = x2-x1+180; 
        if (diff < 0) {  
            diff = diff + 360 - 180;  
        } else if (diff > 360) {  
            diff = diff - 360 - 180;  
        } else {  
            diff = diff - 180;  
        }  
    } while(0)
    
    float angle_avg(float *angle, uint32_t n)
    {
        float diff = 0;
        float last = angle[0];
        float sum  = angle[0];
        uint32_t i = 0;
    
        for (i=1; i<n; i++) {
            /* diff = mod(angle[i]-angle[i-1]+180,360)-180 */
            ANGLE_DIFF(diff, angle[i], angle[i-1]);
            last += diff;
            sum  += last;
        } 
    
        return sum/n;
    }
    

    当中的DIFF宏定义用于计算两个角度差值。

    文献综述

    维基百科角度出现循环的变量为圆周量,如上面的角度值、一天的24小时等。

    Wikipedia中计算平均角度的方法:

    參考文献1中给出了关于圆周变量更仔细的数学分析与描写叙述,是一份难得的资料,參考文献2是StackOverflow上关于圆周角度的探讨,作为对该问题的理解非常有帮助。

    參考

    1. CodeProject: Circular Values Math and Statistics with C++11
    2. Stackoverflow: How do you calculate the average of a set of angles?
    3. Wikipedia
  • 相关阅读:
    1022词法分析的感想
    0909 对编译原理的看法
    0909 编译原理
    oracle安装不容易啊
    2016.8.24
    vue配置config ‘./.../.../***/**.vue’路径别名
    vue 路由过渡效果(1)
    域名配置DNS解析A记录,映射到主机
    vue 线上,本地,不同变量配置
    No 'Access-Control-Allow-Origin'跨域问题- (mysql-thinkphp) (6)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4004778.html
Copyright © 2011-2022 走看看