获取360和1之间的平均度数方向

时间:2015-11-17 03:23:50

标签: java math

我试图从0到359采取一组角度并获得角度的平均方向。我到处搜索过一些例子,但由于某种原因,我的代码不起作用。

例如{355,355,15,15}的平均值应该是5度,但我得到了一堆不同的答案,这些答案没有多大意义。

我使用这个等式来提供维基: https://en.wikipedia.org/wiki/Mean_of_circular_quantities

public static void main(String[] args) {

    //ATAN2(sum_of_sin(theta), sum_of_cos(theta))

    double[] numbers = {355,355,15,15};
    double sin=0.0, cos=0.0, theta=0.0;

    for(double d : numbers) {
        sin += Math.sin(d);
        cos += Math.cos(d);
    }

    sin = sin / ((double)numbers.length);
    cos = cos / ((double)numbers.length);

    // Using only atan2
    System.out.println("Atan2 Only: " + Math.toDegrees(Math.atan2(sin, cos)));
    // Atan2 Only: 159.71920992022936

    // Using the wiki solution
    if (sin > 0 && cos > 0) {
        theta = Math.atan(sin/cos);
    } else if(cos < 0) {
        theta = Math.atan(sin/cos) + 180;
    } else if(sin < 0 && cos > 0) {
        theta = Math.atan(sin/cos) + 360;
    }
    System.out.println("Wiki Answer: " + theta);
    // Wiki Answer: 179.6460334382022
}

3 个答案:

答案 0 :(得分:1)

Java中的数学方法假设您使用的是弧度,而不是度。尝试将所有值转换为弧度,方法是将它们乘以π/ 180,看看是否能解决这些问题。

答案 1 :(得分:1)

您需要将输入的度数转换为弧度,然后将结果再转换为结果:

    double[] numbers = {355, 5, 15 };
    double sin=0.0, cos=0.0, theta=0.0;

    for(double d : numbers) {
        double s = Math.sin(Math.toRadians(d));
        sin += s;

        double c = Math.cos(Math.toRadians(d));
        cos += c;
    }

    sin = sin / ((double)numbers.length);
    cos = cos / ((double)numbers.length);

    // Using only atan2
    System.out.println("Atan2 Only: " + Math.toDegrees(Math.atan2(sin, cos)));
    // Atan2 Only: 159.71920992022936

    // Using the wiki solution
    if (sin > 0 && cos > 0) {
        theta = Math.atan(sin/cos);
    } else if(cos < 0) {
        theta = Math.atan(sin/cos) + 180;
    } else if(sin < 0 && cos > 0) {
        theta = Math.atan(sin/cos) + 360;
    }
    System.out.println("Wiki Answer: " + theta);
    System.out.println("Wiki Answer in degrees: " + Math.toDegrees(theta));

输出:

Atan2 Only: 4.9999999999999964
Wiki Answer: 0.08726646259971642
Wiki Answer in degrees: 4.9999999999999964

答案 2 :(得分:0)

注意:这种方法存在相当大的缺陷;留下这个答案,以便其他人了解这些缺陷。有关详细信息,请参阅@LutzL和我之间的评论(@Nadesri)。

也许我错过了一些东西...... 我认为你应该能够添加所有数字,取模数为360(假设度数),然后除以n

private double avgOfAngles(List<int> numbers) {
    int n = numbers.size();
    int sum = 0;
    for (int i=0; i<numbers; i++) {
        sum += numbers.get(i);
    }
    return (double) (sum % 360) / n;
}

当然,以上假设可接受的答案介于0到359之间(包括0和359);如果你喜欢不同的范围(例如-180到179),那么上述解决方案需要偏移适当的数量。

wiki注意到[0,360]可能是违反直觉的例子(因为算术平均值是180,尽管360度对于大多数目的来说与0度相同);我认为上述解决方案至少仍然处理这个例子。