latitude and longitude from a sphere

Blitz3D Forums/Blitz3D Programming/latitude and longitude from a sphere

Heliotrope(Posted 2014) [#1]
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.


Who was John Galt?(Posted 2014) [#2]
Looks about right to me- assumes a sphere of unit radius. Is your sphere unit radius?


Floyd(Posted 2014) [#3]
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 ).


Floyd(Posted 2014) [#4]
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.


Heliotrope(Posted 2014) [#5]
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]


Kryzon(Posted 2014) [#6]
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


Heliotrope(Posted 2014) [#7]
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))



Floyd(Posted 2014) [#8]
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.





Heliotrope(Posted 2014) [#9]
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?


Mikorians(Posted 2014) [#10]
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,


Krischan(Posted 2014) [#11]
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)




Mikorians(Posted 2014) [#12]
My function is only 7 lines...


Krischan(Posted 2014) [#13]
Could you post the 7 lines?


Mikorians(Posted 2014) [#14]
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.