latitude and longitude from a sphere
Blitz3D Forums/Blitz3D Programming/latitude and longitude from a sphere
| ||
Hello, I have being trying to get a latitude and longitude from a sphere. I found some algorithms for n-vector on Wikipedia, but they give me skewed results. I have seen http://www.blitzbasic.com/Community/posts.php?topic=69504#780578 but it is no good at the moment as I am trying to go from XYZ to long and lat, not the other way around. although I intend to use the other code soon I am stuck at the moment as the program is giving me skewed info. lat1 = ASin (z);lat long1 = ATan (y / x);long lat2 = ATan (z / Sqr (x^2 + y^2));lat Text 0,10,"|lat1 " + lat1 + " |long1 " + long1 + " |lat2 " + lat2 Does anyone know anything better than http://en.wikipedia.org/wiki/N-vector#Converting_latitude.2Flongitude_to_n-vector. |
| ||
Looks about right to me- assumes a sphere of unit radius. Is your sphere unit radius? |
| ||
It better be a unit sphere or ASin( z ) already makes no sense. Notice that replacing x with -x and y with -y moves the point to the opposite side of the earth ( but same latitude ) changing longitude 180 degrees. But y / x and -y / -x are the same number, so ATan( y / x ) = ATan( -y / -x ). ATan() has a range of only 180 degrees, not the 360 we need. This is exactly why ATan2 was invented. Just replace ATan( y / x ) with ATan2( y , x ). |
| ||
And I've just remembered that a tiny bug has crept into the ATan2 function at some point. It should, by definition, return a value in the range ( -180, +180 ]. Note the -180 is excluded. But Blitz3D's ATan2 sometimes returns -180 instead of +180. In typical usage it probably doesn't matter since all you care about is the angle. -180 and +180 are different numbers, but represent the same angle. But it's still wrong. |
| ||
Floyd what is a unit sphere? Also here is the full code. Click on the sphere to place a marker and press b twice to get the maker location info. Type event Field x Field y Field z Field id End Type Graphics3D 800,600,16,2 SetBuffer BackBuffer () Global zoom = 90 Global tool = 0, viewmode = 1 Color 255,255,255 earthmask = LoadTexture ("earth.jpg") earth = CreateSphere (32) pivot = CreatePivot () camera = CreateCamera (pivot) sun = CreateLight (2) ScaleEntity earth, 50,50,50 EntityTexture earth,earthmask PositionEntity pivot, 70,70,0 ;PositionEntity camera,70,70,0 PositionEntity earth,2,2,2 PositionEntity sun, 600,0,0 PointEntity pivot, earth PointEntity camera, earth EntityPickMode earth,2 ;AmbientLight 200,200,200 Repeat Cls If MouseHit (1) Then Gosub newevent If KeyDown (203) MoveEntity pivot,-10,0,0 roll = EntityRoll (pivot) PointEntity pivot, earth,roll End If If KeyDown (205) MoveEntity pivot, 10,0,0 roll = EntityRoll (pivot) PointEntity pivot, earth,roll EndIf If KeyDown (200) And EntityPitch (pivot) < 87 MoveEntity pivot, 0,10,0 roll = EntityRoll (pivot) PointEntity pivot, earth,roll EndIf If KeyDown (208) And EntityPitch (pivot) > -87 MoveEntity pivot, 0,-10,0 roll = EntityRoll (pivot) PointEntity pivot, earth,roll EndIf If KeyHit (48) Then debug = debug + 1 If debug > 2 Then debug = 0 If KeyDown (17) Then TurnEntity camera,-1,0,0 If KeyDown (31) Then TurnEntity camera,1,0,0 If KeyDown (30) Then TurnEntity pivot,0,0,1 If KeyDown (32) Then TurnEntity pivot,0,0,-1 If EntityDistance (pivot,earth) > zoom Then MoveEntity pivot,0,0,EntityDistance (pivot,earth) - zoom If EntityDistance (pivot,earth) < zoom Then MoveEntity pivot,0,0,EntityDistance (pivot,earth) - zoom If KeyDown (12) Then zoom = zoom + 1 If KeyDown (13) Then zoom = zoom - 1 If zoom < 51 Then zoom = 51 If zoom > 300 Then zoom = 300 Delay 40 UpdateWorld RenderWorld If debug <> 1 Then Goto skipworldinfo Text 0,0,"Cam X " + EntityX (camera,1) Text 0,11,"Cam Y " + EntityY (camera,1) Text 0,22,"Cam Z " + EntityZ (camera,1) Text 0,33,"Cam Pitch " + EntityPitch (camera,1) Text 0,44,"Cam Roll " + EntityRoll (camera,1) Text 0,55,"Cam Yaw " + EntityYaw (camera,1) Text 0,77,"Piv X " + EntityX (pivot,1) Text 0,88,"Piv Y " + EntityY (pivot,1) Text 0,99,"Piv Z " + EntityZ (pivot,1) Text 0,110,"Piv Pitch " + EntityPitch (pivot,1) Text 0,121,"Piv Roll " + EntityRoll (pivot,1) Text 0,132,"Piv Yaw " + EntityYaw (pivot,1) Text 0,154,"Zoom " + zoom .skipworldinfo If debug <> 2 Then Goto skipobjinfo r = 0 For cat.event = Each event rid = cat\id lat1 = ASin (cat\z);lat long1 = ATan2 (cat\x,cat\y);long long2 = ATan (cat\y/cat\x) lat2 = ATan (cat\z / Sqr (cat\x^2 + cat\y^2));lat Text 0,10 * r, "Id " +rid + " |lat1 " + lat1 + " |lat2 " + lat2 + " |long1 " + long1 + " |long2 " + long2 r = r + 1 Next .skipobjinfo Flip Until KeyHit (1) End .newevent CameraPick (camera, MouseX (), MouseY()) c = c + 1 cat.event = New event cat\x = PickedX () cat\y = PickedY () cat\z = PickedZ () cat\id = c cat\id = CreateCube () PositionEntity cat\id,cat\x,cat\y,cat\z Return The earth picture can be found[a http://naturalearth.springercarto.com/ne3_data/8192/textures/3_no_ice_clouds_8k.jpg[/a] |
| ||
A "unit sphere" is a sphere of which the radius is 1. A "unit vector" is a vector of which the magnitude (length) is 1. Perhaps this could be helpful: http://en.wikipedia.org/wiki/UV_mapping#Finding_UV_on_a_sphere |
| ||
Thanks Kryzon, The u equation works and I multiplied it by 6.2 to get a longitude reading, but the v equation always returns -2147483628. u# = (0.5 + (ATan2(cat\z,cat\x)/(2 * Pi )))* 6.2 v = (0.5 - (ASin (cat\y)/Pi)) |
| ||
The math is much simpler if you leave the earth sphere at the original radius=1. The equations, such as ASin( z ), assume this. ASin is assuming z is the sine of an angle, which has a value in the range [-1,1]. So z needs to conform to this. I recommend leaving the earth at the origin, unscaled. Control the view by moving and zooming the camera. Also note it shouldn't really be z. The usual ( not computer graphics ) convention is that z is up. But in Blitz3D y is up, hence we need ASin( y ). And the x-axis points to the right, while the negative z-axis is at the front, closest to the viewer. Greenwich England is about in the middle ( left-right ) of the image, so it needs to go where the x-axis hits the sphere. That means the texture must be shifted a quarter of the way around the sphere, moving from -z axis to +x axis. That's why I used PositionTexture earthmask, 0.25, 0 The way I have done this positive latitude means North, positive longitude means West. Greenwich is at zero longitude. That's approximate. I just eyeballed it to determine how to position the texture. Here is a bare bones example. |
| ||
Thanks Floyd, it works now. Although longitude extends from 180.7 to -179.3 (fixed by subtracting 0.7). Also just wondering is there an easy way to download Google earth/maps terrain data and use it directly in a blitz application? |
| ||
I have a Rec2Pol converter that might work better. It is similar to this unit sphere thing, but probably wouldn't handle a squashed sphere, |
| ||
I would solve it with Pivots, TFormpoint and two ATan2s, it's very simple (the camera position above the sphere center is being measured here, but it'll work with other object positions too) |
| ||
My function is only 7 lines... |
| ||
Could you post the 7 lines? |
| ||
Sure- didn't mean to sound like bragging, I have a newer version somewhere that uses atan2, but this crappy thing worked well enough at the time: I use this type of function constantly. It's a bit iffy in this state. Simply visualize your sphere in a 2D state to make this work. (Where x1,y1 are the center of your sphere/circle) You can probably adjust it for oblate spheres via multiplying somewhere. You will now easily acquire latitude and longitude. Good day. |