Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modulus to limit latitude and longitude values

I have doubles that represent latitudes and longitudes.
I can easily limit longitudes to (-180.0, 180.0] with the following function.

double limitLon(double lon)
{
  return fmod(lon - 180.0, 360.0) + 180.0;
}

This works because one end is exclusive and the other is inclusive. fmod includes 0 but not -360.0.

Can anyone think of an elegant method for latitude?
The required interval is [-90.0, 90.0]. A closed form solution would be best, i.e. no loop. I think fmod() is probably a non-starter because both ends are inclusive now.

Edit: As was pointed out, one can't go to 91 degrees latitude anyway. Technically 91 should map to 89.0. Oh boy, that changes things.

like image 724
William Avatar asked Nov 13 '12 20:11

William


1 Answers

There is a much, much more efficient way to do this than using sin and arcsin. The most expensive operation is a single division. The observation that the required interval is closed is key.

  • Divide by 360 and take the remainder. This yields a number in the interval [0, 360), which is half-open, as observed.

  • Fold the interval in half. If the remainder is >=180, subtract it from 360. This maps the interval [180, 360) to the interval (0, 180]. The union of this interval with the bottom half is the closed interval [0, 180].

  • Subtract 90 from the result. This interval is [-90, 90], as desired.

This is, indeed, the exact same function as arcsin(sin(x)), but without the expense or any issue with numeric stability.

like image 180
eh9 Avatar answered Oct 13 '22 15:10

eh9