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?
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:
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.)