I am representing wind directions using integer values (an Enum) ranging from 0 for North, through to 15 for North-North-West.
I need to check if a given wind direction (integer value between 0 and 15) is within a certain range. I specify my WindDirectionFrom
value first moving clockwise to WindDirectionTo
to specify the range of allowable wind direction.
Obviously if WindDirectionFrom=0
and WindDirectionTo开发者_运维百科=4
(between N and E direction) and the wind direction is NE (2) the calculation is simply
int currentWindDirection = 2;
bool inRange = (WindDirectionFrom <= currentWindDirection && currentWindDirection <= WindDirectionTo);
//(0 <= 2 && 2 <= 4) simple enough...
However for a different case where say WindDirectionFrom=15
, WindDirectionTo=4
and wind direction is NE (2) again, the calculation immediately breaks...
bool inRange = (WindDirectionFrom <= currentWindDirection && currentWindDirection <= WindDirectionTo);
//(15 <= 2 && 2 <= 4) oops :(
I'm sure this can't be too difficult, but I'm having a real mental block with this one.
What you want is modular arithmetic. Do your arithmetic mod 16, and check to see if the difference is from (say) at least 14 (the modular equivalent of -2) or at most 2.
How to do modular arithmetic will vary between languages. With C or C++, you would find x mod 16 as follows:
int xm = x % 16;
if (xm < 0) xm += 16;
(Thanks to msw for pointing out that arithmetic on enum
s is frequently not allowed, and for good reasons. An enum
normally represents objects or conditions that are discrete and not related arithmetically.)
I would do it like this:
int normedDirection( int direction, int norm )
{
return (NumberOfDirections + currentDirection - norm) % NumberOfDirections;
}
int normed = normedDirection( currentWindDirection, WindDirectionFrom );
bool inRange = (0 <= normed && normed <= normedDirection( WindDirectionTo, WindDirectionFrom );
精彩评论