Skip to content

Instantly share code, notes, and snippets.

@andrew-raphael-lukasik
Last active September 28, 2023 18:52
Show Gist options
  • Select an option

  • Save andrew-raphael-lukasik/26d14f6c9abd0c410d83305222ca829b to your computer and use it in GitHub Desktop.

Select an option

Save andrew-raphael-lukasik/26d14f6c9abd0c410d83305222ca829b to your computer and use it in GitHub Desktop.
Geographical (spherical approximation) to cartesian coordinates, Unity3d
// src*: https://gist.github.com/andrew-raphael-lukasik/26d14f6c9abd0c410d83305222ca829b
using UnityEngine;
using Math = System.Math;
public class GeoCoordToCart : MonoBehaviour
{
[SerializeField] Vector3 _worldSize = new Vector3(100,0,100);
[SerializeField] Vector3 _worldOrigin = new Vector3(0,0,0);
[SerializeField] bool _originFromPlayerPosition = false;
[SerializeField] GeoCoord _playerPosition = new GeoCoord{ label="Player 0" , latitude=48.195932 , longitude=16.339999 };
#if UNITY_EDITOR
[SerializeField] float _worldPointSize = 1f;
[SerializeField][Min(0.01f)] float _gizmoScale = 10f;
void OnValidate ()
{
if( _originFromPlayerPosition )
{
UnityEditor.Undo.RecordObject( this , "Origin From Player Position" );
MoveOrigin( _playerPosition );
}
}
void OnDrawGizmos ()
{
Vector3 origin = transform.position;
// draw sphere:
Gizmos.color = Color.cyan;
Gizmos.DrawWireSphere( origin , _gizmoScale );
Gizmos.color = new Color(0,1,1,0.05f);
Gizmos.DrawSphere( origin , _gizmoScale );
// draw rect:
Gizmos.color = Color.cyan;
Vector2 rect = new Vector2( _gizmoScale*4f , _gizmoScale*2f );
Vector3 rectCenterWorld = origin - Vector3.right*_gizmoScale*4f;
Gizmos.DrawWireCube( rectCenterWorld , new Vector3(rect.x,rect.y,0) );
// draw game world bounds:
Gizmos.DrawWireCube( _worldOrigin , _worldSize );
Gizmos.color = Color.yellow;
var labelStyle = new GUIStyle(){ normal = new GUIStyleState(){ textColor = Color.yellow } };
for( int i=_coordinates.Length-1 ; i!=-1 ; i-- )
{
var coord = _coordinates[i];
// sphere:
{
Vector3 spherePoint = coord.ToVector3UnitSphere();
Vector3 worlPos = origin + spherePoint*_gizmoScale;
Gizmos.DrawSphere( worlPos , _gizmoScale*0.01f );
UnityEditor.Handles.Label( worlPos , coord.ToString() , labelStyle );
}
// rect:
{
Vector2 v2point = coord.ToVector2();
Vector3 worlPos = rectCenterWorld + Vector3.Scale(v2point,rect*0.5f);
Gizmos.DrawSphere( worlPos , _gizmoScale*0.01f );
UnityEditor.Handles.Label( worlPos , coord.ToString() , labelStyle );
}
// game world:
{
Vector3 v3point = coord.ToVector3();
Vector3 worlPos = _worldOrigin + Vector3.Scale(v3point,_worldSize*0.5f);
Gizmos.color = Color.green;
Gizmos.DrawCube( worlPos , new Vector3(_worldPointSize,_worldPointSize,_worldPointSize) );
UnityEditor.Handles.Label( worlPos , coord.ToString() , labelStyle );
}
}
}
#endif
void MoveOrigin ( GeoCoord coord ) => _worldOrigin = -Vector3.Scale( coord.ToVector3() , _worldSize*0.5f );
[SerializeField] GeoCoord[] _coordinates = new GeoCoord[]{
new GeoCoord{ label="" , latitude=0 , longitude=0 } ,
new GeoCoord{ label="Reykjavík" , latitude=64.1335484 , longitude=-21.9224813 } ,
new GeoCoord{ label="Kraków" , latitude=50.0468548 , longitude=19.9348336 } ,
new GeoCoord{ label="Paris" , latitude=48.8589507 , longitude=2.2770204 } ,
new GeoCoord{ label="Buenos Aires" , latitude=-34.6156625 , longitude=-58.503338 } ,
new GeoCoord{ label="Ho Chi Minh" , latitude=10.7553411 , longitude=106.4150395 } ,
new GeoCoord{ label="İstanbul" , latitude=41.0054958 , longitude=28.8720965 } ,
new GeoCoord{ label="Nairobi" , latitude=-1.3030364 , longitude=36.7773568 } ,
new GeoCoord{ label="Dublin" , latitude=53.3244431 , longitude=-6.3857857 } ,
new GeoCoord{ label="London" , latitude=51.5287718 , longitude=-0.2416804 } ,
new GeoCoord{ label="New York" , latitude=40.6976637 , longitude=-74.119764 } ,
new GeoCoord{ label="Starbase" , latitude=25.9884963 , longitude=-97.1632233 } ,
new GeoCoord{ label="Vancouver" , latitude=49.2578263 , longitude=-123.1939434 } ,
new GeoCoord{ label="Honolulu" , latitude=21.1579153 , longitude=-158.5605044 } ,
new GeoCoord{ label="Mumbai" , latitude=19.0825223 , longitude=72.7411016 } ,
new GeoCoord{ label="Tehran" , latitude=35.6970118 , longitude=51.2097352 } ,
new GeoCoord{ label="Hongkong" , latitude=22.3529913 , longitude=113.9876156 } ,
new GeoCoord{ label="Sydney" , latitude=-33.8479255 , longitude=150.6511036 } ,
new GeoCoord{ label="Dakar" , latitude=14.7110139 , longitude=-17.5360369 } ,
new GeoCoord{ label="Natal" , latitude=-4.8730191 , longitude=-34.9832028 } ,
new GeoCoord{ label="Ushuaia" , latitude=-54.8228355 , longitude=-68.3797813 } ,
new GeoCoord{ label="Caracas" , latitude=10.4683841 , longitude=-66.9605778 } ,
new GeoCoord{ label="Cape Town" , latitude=-33.9152193 , longitude=18.3751883 } ,
new GeoCoord{ label="Якутск" , latitude=62.0312622 , longitude=129.5613624 } ,
new GeoCoord{ label="Roma" , latitude=41.9099856 , longitude=12.3955715 } ,
new GeoCoord{ label="Gibraltar" , latitude=36.129508 , longitude=-5.3708525 } ,
new GeoCoord{ label="Longyearbyen" , latitude=79.2639353 , longitude=4.3014832 } ,
new GeoCoord{ label="Lima" , latitude=-12.0185972 , longitude=-77.1280131 } ,
new GeoCoord{ label="Santiago" , latitude=-33.4727088 , longitude=-70.7702586 } ,
new GeoCoord{ label="Atqasuk" , latitude=70.539337 , longitude=-157.9874001 } ,
new GeoCoord{ label="Douala" , latitude=4.0359007 , longitude=9.6715926 } ,
new GeoCoord{ label="Stazione Mario Zucchelli" , latitude=-74.6958608 , longitude=164.0881707 } ,
new GeoCoord{ label="Alert" , latitude=82.5058286 , longitude=-62.5571841 } ,
new GeoCoord{ label="Vienna p0" , latitude=48.195932 , longitude=16.339999 } ,
new GeoCoord{ label="Vienna p1" , latitude=48.202385 , longitude=16.361278 } ,
};
}
[System.Serializable]
public struct GeoCoord
{
public string label;
public double latitude;
public double longitude;
public override string ToString () => this.label;
public Vector2 ToVector2 () => new Vector2( (float) Math.Sin( this.longitude * Deg2Rad * 0.5 ) , (float) Math.Sin( this.latitude * Deg2Rad ) );
public Vector3 ToVector3 ( float elevation = 0 ) => new Vector3( (float) Math.Sin( this.longitude * Deg2Rad * 0.5 ) , elevation , (float) Math.Sin( this.latitude * Deg2Rad ) );
public Vector3 ToVector3UnitSphere () => Quaternion.Euler(0,-(float)this.longitude,0) * ( Quaternion.Euler(-(float)this.latitude,0,0) * Vector3.forward );
const double Deg2Rad = Math.PI / 180.0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment