I want to draw an arrow between two points using kml in Google Earth.
Using planar coordinates the calculation looks right if I do it like this:
Line: (x1,y1),(x2,y2)
w = 0.1 (Width of the shaft of the arrow (for example)) n = 2 (Number of w's the point of the arrow should extend (for example)) x = x2 - x1 (Extent of line in x direction) y = y2 - y1 (Extent of line in y direction) d = sqrt((x*x)+(y*y)) (Length of line) wx = y * wy / x (Extent of shoulder in x direction) wy = w * x / d (Extent of shoulder in y direction) nw = n * w (Length of point) nwx = nw * x / d (Extent of point in x direction) nwy = y * nwx / x (Extent of point in y direction)
When I place this arrow in google earth it looks 'skewed'. I have attached a sample kml file to look at. Just open Google Earth and paste it from a text editor.
I am guessing I am not taking into account the fact that the coordinates in kml are spherical.
What changes do I need to make to the calculations to make it look better in Google Earth?
w = 0.1 (Width of the shaft of the arrow (for example)) n = 2 (Number of w's the point of the arrow should extend (for example)) x = cos(lat)*(x2 - x1) (Extent of line in x direction) y = y2 - y1 (Extent of line in y direction) d = sqrt((x*x)+(y*y)) (Length of line) wx = w * y / d / cos(lat) (Extent of shoulder in x direction) wy = w * x / d (Extent of shoulder in y direction) nwx = n * wx (Extent of point in x direction) nwy = n * wy (Extent of point in y direction)
it may be better to have a different cos(lat) for each of (x1-wx,y1-wy) (x1+wx,y1+wy) (x2-nwx+wx,y2+nwy+wy) (x2-nwx+wx+wx,y2+nwy+wy+wy) (x2,y2) (x2-nwx-wx-wx,y2+nwy+wy+wy) (x2-nwx-wx,y2+nwy+wy) (x1-wx,y1-wy) but if the arrow is long enough or close enough to a pole for that difference to be significant, then it may be better to use a different approach than tweaking a planar solution
Strangely, that made it worse, but just to 'see what happens' I tried 'x = (x2 - x1)/cos(lat)' and it looks significantly better. The shoulders of the arrow at least now look square to the shaft. The head looks a bit strange though.
What would you suggest as an alternative to 'tweaking a planar solution'? My schoolboy maths reminds me that Pythagoras and some trig doesn't strictly apply on a sphere. I guess a simple mapping of the original endpoints to cylindrical coordinates may be a good start but can we work purely in spherical? How does one calculate a perpendicular vector in spherical coordinates?
If the choice is arbitrary I would choose the same as Google Earth which is
x (Longitude) e 180 and <= 180 y (Latitude) e 90 and d 90
x=0 at Greenwich meridian y=0 at equator.
Given a solution I should be able to work on the coordinate system if it is not what I want. I have done some maths since school but not a huge amount. :-)
So you would translate the endpoints into true 3d (x,y,z) cartesians, draw the arrow between them and map the results back onto the sphere? How would you project it back to the sphere?
I was considering rotating the sphere so the arrow is north-south, draw the arrow, rotate back to original position. The 1/cos(lat) adjustment can still be applied if required but at least the true shape should be preserved which is my primary aim. This 'should' only require conversion from r/theta/phi to lat/long as the first rotation is purely notional.
To project a point P = (x, y, z) onto a sphere, radius r, centred at the origin O:
1. Find the length of OP = R = sqrt(x^2 + y^2 + z^2).
2. Scale the co-ordinates of P to get a point, P', such that P' lies on OP and |OP'| = r - i.e. P' = P * r / R.
3. Translate the co-ordinates of P' = (x', y', z') into a latitude and longitude on the sphere.
Obviously you could combine all three steps into one calculation, and even apply it to the equation of the line joining your two endpoints, but that might start to look ugly.
The two KML.xls spreadsheets you posted seem to have identical wx values can you post the values for the one that strangely made it worse?
I think I may have misunderstood what nwx and nwy were supposed to represent. and maybe they should have been wx = (w * y / d) / cos(lat) (Extent of shoulder in x direction) wy = w * x / d (Extent of shoulder in y direction) nwx = (nw * x / d) / cos(lat) (Extent of point in x direction) nwy = nw * y / d (Extent of point in y direction)
You can get a perpendicular vector to the line that is also tangent to the sphere by taking the cross product of the line with the vector from the point to the centre of the sphere?
Here's the latest spreadsheet and the kml it produces. This is very close. The only problem now is that the arrow point seems to be slightly off-center. In fact the point is in exactly the right place, its the whole of the arrow that seem to have been offset but I cant see where the problem is.
Here I use a different scale at each end (wxa and wxb) but as yet I am not doing a 'perfect' scale by scaling ALL x coordinates, only wx. I guess that would cause some other difficulties such as the end points moving unless the scale is performed centred on the line.
Hi Confusing,
The aim here is to get the arrow to look right on the sphere. A direct mapping onto the sphere from a perfect cartesian arrow would require correctly shaping the arrow for lattidude squeeze which is the problem I have right now. Thanks for the suggestions.