Rotate a object in LatLng coordinate system

546

So here's the rub. The problem I mentioned before is that a latitude-longitude pair are a pair of angles, not a 2D vector of a point on a graph, so trying to use them to rotate a point in 3D space on the surface of a sphere is going to run into its own problems. One thing that turns out, however, is that as long as you don't pick points that cross either the international date line or the poles, you can still use this trick by just pretending the angle pair is a 2D vector.

The real problem is that you are wanting to rotate the points around the midpoint, but your math is merely performing a straight rotation which will be rotating them around the origin instead (i.e. 0,0). You need to offset your "points" by the point you are using as a reference.

import 'dart:math';

LatLng rotate(LatLng coord, LatLng midpoint, double angle) {
  // Make this constant so it doesn't have to be repeatedly recalculated
  const piDiv180 = pi / 180;

  // Convert the input angle to radians
  final r = angle * piDiv180;

  // Create local variables using appropriate nomenclature
  final x = coord.longitude;
  final y = coord.latitude;
  final mx = midpoint.longitude;
  final my = midpoint.latitude;
  
  // Offset input point by the midpoint so the midpoint becomes the origin
  final ox = x - mx;
  final oy = y - my;

  // Cache trig results because trig is expensive
  final cosr = cos(r);
  final sinr = sin(r);

  // Perform rotation
  final dx = ox * cosr - oy * sinr;
  final dy = ox * sinr + oy * cosr;

  // Undo the offset
  return LatLng(dy + my, dx + mx);
}

Using this approach, I ended up with the following results:

Formula results on Google Maps

The blue points are the input, the green point is the calculated midpoint, and the red points are each of the blue points passed through a 90 degree rotation.

(Note that the distance between the blue points appears to be farther than the distance between the red points. This is because I visualized the results in Google Maps which uses the Mercator projection, and that had the result of screwing with where the points appear to be relative to each other. If you were to visualize this on a globe, the points should appear the correct distance from each other.)

Share:
546
Curious99
Author by

Curious99

Updated on December 30, 2022

Comments

  • Curious99
    Curious99 over 1 year

    Hey there I am trying to rotate a line around its own center within the latlng system.

    I got the angle and the two points. So I tried to append the rotation matrix, like this (following method takes the latitude and longitude of a point and the angle):

     LatLng rotate(double lat, double long, double angle){
       double rad = angle*pi/180;
       double newLong = long*cos(rad)-lat*sin(rad);
       double newLat = long* sin(rad) + lat*cos(rad);
    
      return LatLng(newLat,newLong);
    
      }
    

    For example I got the point A (latitude:x,longitude:y) and the point B(latitude:x,longitude:y). Connecting these two points leads to a line. Now I want two rotate the line around it's own center with the above method, by calling:

    LatLng newA = rotate(A.latitude,A.longitude);
    LatLng newB = rotate(B.latitude,B.longitude);
    

    But when I connect the two Points newA and NewB there is not the desired effect.

    As @Abion47 clarified in his answer I need a rotation in 3-dimension, but how to do so? And is it possible with 2-dimension if it is a very small line?

    • eyoeldefare
      eyoeldefare almost 3 years
      Well, its hard to know what this code is doing. All we see is the x and y coordinates of a possible circle at a certain angle. If you're rotating something, that will require a transformation these coordinate offsets of the line. This code you posted means nothing really
    • Abion47
      Abion47 almost 3 years
      You are converting your degrees to radians but then using degrees for the following calculations. Change angle to rad in the trigonometric functions.
    • Abion47
      Abion47 almost 3 years
      Also, latitude and longitude represent coordinates in three dimensions, meaning any arbitrary rotation requires at least two rotation scalars unless all you're doing is simply rotating the sphere on one axis. It would help if you described what you're actually trying to accomplish with your rotation.
    • Curious99
      Curious99 almost 3 years
      Sorry guys I try to specify my question
    • Abion47
      Abion47 almost 3 years
      And finally, latitude and longitude themselves already represent angles, so performing a simple rotation on either of them means simply adding the new angle to the existing latitude/longitude value.
    • Curious99
      Curious99 almost 3 years
      @Abion I edited the question. And just adding values to the longs or lats doesn't work cause I want to rotate on the area.
  • Curious99
    Curious99 almost 3 years
    Holy **** thats the best answer I've ever read. Thanks for the effort!