I have a celestial sphere with a plane in the centre and spheres (stars) aligned around the centre with a fixed radius.

Celestial Sphere Screenshot

In order to show the stars visible from a certain latitude and longitude from Earth, I need to rotate the plane accordingly.

To rotate the plane properly, I converted the latitude and longitude into 3D vectors, then utilised the LookAt() method to point the plane at this vector.

The following is the code which calculated the vectors from the coordinates, and utilises the LookAt() Method:

public void positionLand(double latitude, double longitude)
    double latitude_rad = (math.PI / 180) * latitude;
    double longitude_rad = (math.PI / 180) * longitude;

    Vector3 markerPositioning = new Vector3();
    markerPositioning.x = (float)-((math.cos(latitude_rad)) * (math.cos(longitude_rad)));
    markerPositioning.y = (float)((math.cos(latitude_rad)) * (math.sin(longitude_rad)));
    markerPositioning.z = (float)((math.sin(latitude_rad)));


To test if this would work, I used the coordinates of London, UK, latitude: 51.509865 and longitude: -0.118092. And this was the result:

London coordinates LookAt

With the LookAt() method changed to the following: groundPlane.transform.LookAt(markerPositioning, Vector3.forward);

This is the result:


Replacing groundPlane.transform.LookAt(markerPositioning); with groundPlane.transform.up = markerPositioning; results in the following:

enter image description here

As you can see, the plane is not properly rotating. Initially, I thought maybe the LookAt() method is using the incorrect forward vector of the plane gameobject, but this isn't the case as there is no connection between the way the plane rotated and the coordinates of London as the plane is near vertical at 89 degrees.

What am I doing wrong and how can I fix this?

  • \$\begingroup\$ Remember a plane's forward vector lies in the plane, not perpendicular to it. So when calling LookAt you're pointing part of the horizon at your chosen point, which is the opposite of what you want to do. You want to point the plane normal at your chosen point in the celestial sphere, so that the horizon traces out a great circle perpendicular to this direction. \$\endgroup\$
    – DMGregory
    Jul 5, 2020 at 11:12
  • \$\begingroup\$ Does this mean I have to compensate by subtracting the Z-axis rotation by the latitude value in degrees? \$\endgroup\$
    – SidS
    Jul 5, 2020 at 11:16
  • \$\begingroup\$ Have you considered groundPlane.transform.up = markerPositioning;? \$\endgroup\$
    – DMGregory
    Jul 5, 2020 at 11:17
  • \$\begingroup\$ I have tried this, this sets the groundPlane rotation to X:51.51, Y:51.60, Z:90.12. This doesn't seem correct as the groundPlane object is positioned vertically. See the edit to the original question to see what this looks like \$\endgroup\$
    – SidS
    Jul 5, 2020 at 11:31

1 Answer 1


Your spherical coordinate functions are written for a z-up coordinate system. Unity is a y-up coordinate system.

You want something more like this (assuming the prime meridian faces z+):

normal.x = - Mathf.Cos(latitude_rad) * Mathf.Sin(longitude_rad);
normal.y =   Mathf.Sin(latitude_rad);
normal.z =   Mathf.Cos(latitude_rad) * Mathf.Cos(longitude_rad);

transform.up = normal;

Or, as a one-liner, letting Unity handle the trig for you:

transform.localEulerAngles = new Vector3(90f - latitude_deg, -longitude_deg, 0);
  • \$\begingroup\$ Say if I want to remove the negative sign from the x-axis, how can I change the one-liner to reflect this? \$\endgroup\$
    – SidS
    Jul 5, 2020 at 12:33
  • \$\begingroup\$ It depends what you mean geometrically by "remove the negative sign from the x-axis". Can you describe what you want to change about the net rotation? \$\endgroup\$
    – DMGregory
    Jul 5, 2020 at 12:36
  • \$\begingroup\$ initially, I had included the negative sign in the x-axis calculation to mirror everything in the x-axis. Am I right to think this? \$\endgroup\$
    – SidS
    Jul 5, 2020 at 12:39
  • \$\begingroup\$ Also, I can confirm that this code works. I only activated the stars in the Scorpius constellation and compared the layout with that from another stargazing app called Stellarium. The constellation was align properly \$\endgroup\$
    – SidS
    Jul 5, 2020 at 12:41
  • \$\begingroup\$ Does that mean you don't need to apply additional mirroring to the code above? Or are you still looking to mirror the longitude? \$\endgroup\$
    – DMGregory
    Jul 5, 2020 at 12:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .