Hi, I have this piece of code in a template file..

"wind0dir":"[wind0dir-act=.0]",

"wind0dirmin10":"[wind0dir-min10=.0]",

"wind0dirmax10":"[wind0dir-max10=.0]",

My question surrounds the min and max functions as they pertain to wind direction. It is easy to understand what min and max mean when applied to wind strength. But direction is a little more tricky.

If 4 values in a period were 275, 355, 010, & 020 degrees what would be the min and max? The answer you want is 275 & 020 - neither value being the numerical min or max.

Is this how these functions work???

Regards

Steve

## Min/Max wind direction **solved**

**Moderator:** Mattk

### Re: Min/Max wind direction

min/max are not defined for wind direction. Don't use it.

### Re: Min/Max wind direction **solved**

Thanks.

Any suggestions as to how to get a measure of wind direction variability?

Rgds

Ps. Other than looking at the last sequence of -valN’s, offsetting these so they don’t cross 360, analysing, and then offsetting back all in JavaScript. If the spread was more than 180 that would be an out of range boundary condition.

Any suggestions as to how to get a measure of wind direction variability?

Rgds

Ps. Other than looking at the last sequence of -valN’s, offsetting these so they don’t cross 360, analysing, and then offsetting back all in JavaScript. If the spread was more than 180 that would be an out of range boundary condition.

### Re: Min/Max wind direction **solved**

Have you thought about wind direction as a range (from/to) which is quite different to min/max etc. Obviously the longer the period then the more obscure range values can become.

### Re: Min/Max wind direction **solved**

a range... exactly. But how to calculate easily is the question.

Many of these calculations are much harder than they first look. Think about average speed. You'd think at first glance a simple sum of recorded speeds divided by the count would do the trick. But no, if the readings aren't taken at exactly regular intervals, or there are missing readings, then you need to take into account the individual interval lengths by weighting the values. But even that won't do the trick if the wind direction changes. Think of a balloon blowing in the wind taking an zig zag course to its final destination. Presumably an average speed multiplied by the time interval gives the distance from the start point. The average speed will always be less then even a weighted average. Maybe... Most books recommend doing what amounts to a sum of vectors calculation. But even this fails in the boundary conditions. Think about a wind blowing in a direction for a time and then in the opposite direction for the same length of time. The vector solution gives nothing but clearly the wind has been blowing. It all comes down to definition.

The problem with the range calculation, aside from the 359 degree/ 0 degree discontinuity which confuses the math is that you can't tell if the variation between two headings is due to a clockwise or anti-clockwise wind swing. As the variation delta gets closer to 180 degrees the probability of the swing being in the unexpected direction climbs. As an example - if I'm on 005T and the next reading is 190T, is the 190T a new high or low in my range?? From memory the standards say if you take readings every second then it is safe assume the swing is the shortest distance between these points which in my example the range would be 190-005 and not 005-190. The meteobridge is in a better position to do these calculations than a downstream calculation because it can deal with much more frequent readings.

Rgds

Many of these calculations are much harder than they first look. Think about average speed. You'd think at first glance a simple sum of recorded speeds divided by the count would do the trick. But no, if the readings aren't taken at exactly regular intervals, or there are missing readings, then you need to take into account the individual interval lengths by weighting the values. But even that won't do the trick if the wind direction changes. Think of a balloon blowing in the wind taking an zig zag course to its final destination. Presumably an average speed multiplied by the time interval gives the distance from the start point. The average speed will always be less then even a weighted average. Maybe... Most books recommend doing what amounts to a sum of vectors calculation. But even this fails in the boundary conditions. Think about a wind blowing in a direction for a time and then in the opposite direction for the same length of time. The vector solution gives nothing but clearly the wind has been blowing. It all comes down to definition.

The problem with the range calculation, aside from the 359 degree/ 0 degree discontinuity which confuses the math is that you can't tell if the variation between two headings is due to a clockwise or anti-clockwise wind swing. As the variation delta gets closer to 180 degrees the probability of the swing being in the unexpected direction climbs. As an example - if I'm on 005T and the next reading is 190T, is the 190T a new high or low in my range?? From memory the standards say if you take readings every second then it is safe assume the swing is the shortest distance between these points which in my example the range would be 190-005 and not 005-190. The meteobridge is in a better position to do these calculations than a downstream calculation because it can deal with much more frequent readings.

Rgds

### Re: Min/Max wind direction **solved**

I've written a javascript function to calculate the range. In essence it reads an array of wind directions, and counts for each point of the compass (x360) the number of times it is hit. It then finds the largest segment of the compass where there are no hits. If there isn't a gap of at least 180 degrees (which implies a swing of more than 180 degrees) the data is considered to be unreliable. The end of the gap (thinking clockwise) is the start of the range. The start of the gap is the end of the range. This isn't the most elegant approach but it does robustly handle the situation where the data is all over the place. It seems to work. No doubt others can improve my coding.

Steve

function frmtDir(i) {

// round to nearest 5 &

// insert leading zeros if required

i = 5 * (Math.round(i/5));

if (i<100) {

i = ("" + (1000 + parseInt(i))).substring(1);

}

else

{

i = "" + i;

}

return i;

}

function directionRange(vals, numVals) {

// work out wind range

var x = "n/a";

var pts = {};

// init all pts to zero

for (i=0; i < 360;i++) pts=0;

// flag each pt where reading was sighted

for (i=0; i < numVals; i++) { pts[Math.round(vals)]++; };

// search for largest gap with no readings

// go round twice (720deg) for good measure

var maxGap = 0;

var maxGapEnd = 0;

var ptr = 0;

var currGap = 0;

for (i = 0; i < 720; i++)

{

ptr++;

if (ptr>359) ptr=0;

if (pts[ptr] == 0) { //gap

currGap++;

if (currGap>maxGap) {

maxGap = currGap;

maxGapEnd = ptr;

}

}

else { // no gap

currGap = 0;

}

}

// now we have the biggest segment of no readings.

var fromDeg = maxGapEnd;

var toDeg = maxGapEnd-maxGap;

if (toDeg<0) toDeg+=360;

if (maxGap<120 || maxGap>359 || numVals < 2) {

x = "range n/a";

} else {

x = "" + frmtDir(fromDeg) +"v"+ frmtDir(toDeg);

};

return x;

}

Steve

function frmtDir(i) {

// round to nearest 5 &

// insert leading zeros if required

i = 5 * (Math.round(i/5));

if (i<100) {

i = ("" + (1000 + parseInt(i))).substring(1);

}

else

{

i = "" + i;

}

return i;

}

function directionRange(vals, numVals) {

// work out wind range

var x = "n/a";

var pts = {};

// init all pts to zero

for (i=0; i < 360;i++) pts=0;

// flag each pt where reading was sighted

for (i=0; i < numVals; i++) { pts[Math.round(vals)]++; };

// search for largest gap with no readings

// go round twice (720deg) for good measure

var maxGap = 0;

var maxGapEnd = 0;

var ptr = 0;

var currGap = 0;

for (i = 0; i < 720; i++)

{

ptr++;

if (ptr>359) ptr=0;

if (pts[ptr] == 0) { //gap

currGap++;

if (currGap>maxGap) {

maxGap = currGap;

maxGapEnd = ptr;

}

}

else { // no gap

currGap = 0;

}

}

// now we have the biggest segment of no readings.

var fromDeg = maxGapEnd;

var toDeg = maxGapEnd-maxGap;

if (toDeg<0) toDeg+=360;

if (maxGap<120 || maxGap>359 || numVals < 2) {

x = "range n/a";

} else {

x = "" + frmtDir(fromDeg) +"v"+ frmtDir(toDeg);

};

return x;

}