I have a table with the wind direction (among other weather values) every 10 seconds on a new row. The direction is stored as degrees: 0 - 360.
Purpose
What is the meaning of this average? The database stores every 10 seconds a row with information. For performance issues I want to aggregate the data older then 5 days to one (average) line per hour.
With the temperature it is easy to accomplish: avg(temp) does the trick as the temperature would not be jumping between to much different values.
With the prevailing wind it's a lot harder to get this 'average'.
Calculating the average wind direction in degrees is not as simple as using the aggregate function avg() as it's a circle, e.g.:
dir1 = 10; dir2 = 350;
avg() = (10+350)/2 = 180;
Which is not accurate; it should be: 0 or 360.
So with my trigonometry classes in university in the back of my head it thought, If i convert it to Radians, and calculate the x and y component I would be able to recalculate the avg direction.
in php with $w['w'] being the direction stored in the database.
while($w = $stmt->fetch()){
$x += cos(deg2rad($w['w']));
$y += sin(deg2rad($w['w']));
}
$angle = atan2($y, $x);
$angle = 360 + round(rad2deg($angle));
Is this formula correct?
If this formula is correct; ideally I would like to get the complete function to MySQL. I made this out of it; but I find a lot of ()'s...
(360 + degrees(atan2(sum(sin(radians(W))), sum(cos(radians(W))))))) AS angle
If we draw the directions on a circle, we see that the "average" that you're after in this case falls on the halfway of the shorter segment of the circle (green segment). The halfway point of the longer segment is on the exact opposite side of the other segment's halfway point.
A simple
(A+B)/2calculation gives either the longer or the shorter segment's halfway point. If it's the longer segment, the shorter segment can be found withS1 = (S2+180) % 360whereS2is the longer segment (and%is the modulo operator).Now all that's left to do is to determine when we get the longer segment and when we get the shorter segment, and that is whenever
ABS(B-A) > 180.Put all this together and the calculation would be:
This is most likely much faster than trigonometric functions.
As mentioned in the comments, if the two directions are exactly opposite of each other (like 0° and 180°), the "average" could be on either side of the circle (90° or 270°). You'll just have to decide which one to pick. The above formula would pick 90° in this case. If you want 270° instead, change the comparison from
>to>=.