Ну, я очень опоздал на вечеринку, но подумал, что добавлю свои 2 цента, потому что не смог найти окончательного ответа. В конце я реализовал следующую Java-версию метода Mitsuta, которая, я надеюсь, предоставляет простое и надежное решение. В частности, стандартное отклонение обеспечивает как дисперсию измерения, так и, если sd == 90, указывает, что входные углы приводят к неоднозначному среднему значению.
РЕДАКТИРОВАТЬ: На самом деле я понял, что моя первоначальная реализация может быть еще более упрощена, на самом деле, на удивление просто, учитывая все разговоры и тригонометрию, происходящие в других ответах.
/**
* The Mitsuta method
*
* @param angles Angles from 0 - 360
* @return double array containing
* 0 - mean
* 1 - sd: a measure of angular dispersion, in the range [0..360], similar to standard deviation.
* Note if sd == 90 then the mean can also be its inverse, i.e. 360 == 0, 300 == 60.
*/
public static double[] getAngleStatsMitsuta(double... angles) {
double sum = 0;
double sumsq = 0;
for (double angle : angles) {
if (angle >= 180) {
angle -= 360;
}
sum += angle;
sumsq += angle * angle;
}
double mean = sum / angles.length;
return new double[]{mean <= 0 ? 360 + mean: mean, Math.sqrt(sumsq / angles.length - (mean * mean))};
}
... и для всех вас (Java) гиков, вы можете использовать вышеупомянутый подход, чтобы получить средний угол в одной строке.
Arrays.stream(angles).map(angle -> angle<180 ? angle: (angle-360)).sum() / angles.length;