# SphericalCoordinates

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Author: Bérenger.

## Description

This a class to manipulate an object's position with spherical coordinates instead of cartesian coordinates (Vector3). This is heavily based upon this implementation : http://blog.nobel-joergensen.com/2010/10/22/spherical-coordinates-in-unity/. Here is the description given there : Spherical coordinate system is an alternative coordinate system, where two orthogonale coordinate axis define the world space in 3D.

The zenith axis points upwards and the azimuth axis points to the side. To define a point in this system the following is needed:

```* Radius: the distance from the origin to the point
* Elevation angle: the angle between the plane (with zenith axis as normal) and the line from the origin to the point
* Polar angle: the rotation around the zenith axis
```

Elevation angle and polar angles are basically the same as latitude and longitude. Note that a point specified in spherical coordinates may not be unique. The spherical coordinate system I’ll be looking at, is the one where the zenith axis equals the Y axis and the azimuth axis equals the X axis.

## Usage

Once the instance is created, you can manipulate it through the Rotate functions or the Translate functions. Here is an example for a camera script :

```using UnityEngine;

public class CamRotate : MonoBehaviour
{
public float rotateSpeed = 1f, scrollSpeed = 50f;
public Vector3 pivot;

public SphericalCoordinates sc;

private void Start()
{
sc = new SphericalCoordinates( transform.position );
}

void Update ()
{
float h, v;
h = Input.GetAxis( "Horizontal" );
v = Input.GetAxis( "Vertical" );

if( h*h > .1f || v*v > .1f )
transform.position = sc.Rotate( h * rotateSpeed * Time.deltaTime, v * rotateSpeed * Time.deltaTime ).toCartesian + pivot;

float sw = -Input.GetAxis("Mouse ScrollWheel");
if( sw*sw > Mathf.Epsilon )
transform.position = sc.TranslateRadius( sw * Time.deltaTime * scrollSpeed ).toCartesian + pivot;

transform.LookAt( pivot );
}
}```

## C# - SphericalCoordinates.cs

```using UnityEngine;

//http://blog.nobel-joergensen.com/2010/10/22/spherical-coordinates-in-unity/
//http://en.wikipedia.org/wiki/Spherical_coordinate_system
public class SphericalCoordinates
{
public float radius{ get; private set; }
public float polar{ get; private set; } // radians, [0, 2PI]
public float elevation { get; private set; } // radians, [0, 2PI]

public SphericalCoordinates(){}
public SphericalCoordinates( float _radius, float _polar, float _elevation )
{
SetRotation(_polar, _elevation);
}
public SphericalCoordinates(Transform T) : this(T.position) { }
public SphericalCoordinates(Vector3 cartesianCoordinate)
{
FromCartesian( cartesianCoordinate );
}

public Vector3 toCartesian
{
get
{
float a = radius * Mathf.Cos(elevation);
return new Vector3(a * Mathf.Cos(polar), radius * Mathf.Sin(elevation), a * Mathf.Sin(polar));
}
}

public SphericalCoordinates FromCartesian(Vector3 cartesianCoordinate)
{
if( cartesianCoordinate.x == 0f )
cartesianCoordinate.x = Mathf.Epsilon;

polar = Mathf.Atan(cartesianCoordinate.z / cartesianCoordinate.x);

if( cartesianCoordinate.x < 0f )
polar += Mathf.PI;

return this;
}

public SphericalCoordinates RotatePolarAngle(float x) { return Rotate(x, 0f); }
public SphericalCoordinates RotateElevationAngle(float x) { return Rotate(0f, x); }
public SphericalCoordinates Rotate(float _polar, float _elevation){ return SetRotation( polar + _polar, elevation + _elevation ); }
public SphericalCoordinates SetPolarAngle(float x) { return SetRotation(x, elevation); }
public SphericalCoordinates SetElevationAngle(float x) { return SetRotation(x, elevation); }
public SphericalCoordinates SetRotation(float _polar, float _elevation)
{
polar = Mathf.Repeat(_polar, Mathf.PI * 2f);
elevation = Mathf.Repeat(_elevation, Mathf.PI * 2f);
return this;
}

{
return this;
}

public override string ToString()
{
return "[Radius] " + radius + ". [Polar] " + polar + ". [Elevation] " + elevation + ".";
}
}```