Jump to content

SkySurveyBanner.jpg.21855908fce40597655603b6c9af720d.jpg

Anyone know how Astronomy app (e.g. Google star map) work?


yong54321

Recommended Posts

Hi all,

A smart phone is able to tell you which part of the sky it is pointing to. Here is a mystery that I have pondered for quite some time, I wonder how the program in star map app work? The most interesting part is the astronomy model. Below is the crucial part of the program which is available at https://github.com/sky-map-team/stardroid 

 

private void calculateLocalNorthAndUpInCelestialCoords(boolean forceUpdate) {
  long currentTime = clock.getTimeInMillisSinceEpoch();
  if (!forceUpdate &&
      Math.abs(currentTime - celestialCoordsLastUpdated) <
      MINIMUM_TIME_BETWEEN_CELESTIAL_COORD_UPDATES_MILLIS) {
    return;
  }
  celestialCoordsLastUpdated = currentTime;
  updateMagneticCorrection();
  RaDec up = calculateRADecOfZenith(getTime(), location);
  upCelestial = GeocentricCoordinates.getInstance(up);
  Vector3 z = AXIS_OF_EARTHS_ROTATION; // (0,0,1)
  float zDotu = scalarProduct(upCelestial, z);
  trueNorthCelestial = addVectors(z, scaleVector(upCelestial, -zDotu));
  trueNorthCelestial.normalize();
  trueEastCelestial = Geometry.vectorProduct(trueNorthCelestial, upCelestial);

  // Apply magnetic correction.  Rather than correct the phone's axes for
  // the magnetic declination, it's more efficient to rotate the
  // celestial axes by the same amount in the opposite direction.
  Matrix33 rotationMatrix = Geometry.calculateRotationMatrix(
      magneticDeclinationCalculator.getDeclination(), upCelestial);

  Vector3 magneticNorthCelestial = Geometry.matrixVectorMultiply(rotationMatrix,
                                                                 trueNorthCelestial);
  Vector3 magneticEastCelestial = vectorProduct(magneticNorthCelestial, upCelestial);

  axesMagneticCelestialMatrix = new Matrix33(magneticNorthCelestial,
                                             upCelestial,
                                             magneticEastCelestial);
}

 

If you understand what is happening, please explain to me as I am in the dark for months!... Thanks in advance!

1. Why is " trueNorthCelestial = addVectors(z, scaleVector(upCelestial, -zDotu))" in the above code? So why is true North equals to upCelestial (zenith) dot product z and added to z axis? Where do this come from?

2. Why need to normalise the trueNorthCelestial.normalize(); ?

/**
 * Updates the astronomer's 'pointing', that is, the direction the phone is
 * facing in celestial coordinates and also the 'up' vector along the
 * screen (also in celestial coordinates).
 *
 * <p>This method requires that {@link #axesMagneticCelestialMatrix} and
 * {@link #axesPhoneInverseMatrix} are currently up to date.
 */
private void calculatePointing() {
  if (!autoUpdatePointing) {
    return;
  }

  calculateLocalNorthAndUpInCelestialCoords(false);
  calculateLocalNorthAndUpInPhoneCoordsFromSensors();

  Matrix33 transform = matrixMultiply(axesMagneticCelestialMatrix, axesPhoneInverseMatrix);

  Vector3 viewInSpaceSpace = matrixVectorMultiply(transform, POINTING_DIR_IN_PHONE_COORDS);
  Vector3 screenUpInSpaceSpace = matrixVectorMultiply(transform, screenInPhoneCoords);

  pointing.updateLineOfSight(viewInSpaceSpace);
  pointing.updatePerpendicular(screenUpInSpaceSpace);
}

3. Why is the transform in the relationship axesCelestial = T * axesPhone as described below? How is the axis of the phone related to the axis of the celestial martrix? Is this related to coordinate axis transform?

/**
 * The model of the astronomer.
 *
 * <p>Stores all the data about where and when he is and where he's looking and
 * handles translations between three frames of reference:
 * <ol>
 * <li>Celestial - a frame fixed against the background stars with
 * x, y, z axes pointing to (RA = 90, DEC = 0), (RA = 0, DEC = 0), DEC = 90
 * <li>Phone - a frame fixed in the phone with x across the short side, y across
 * the long side, and z coming out of the phone screen.
 * <li>Local - a frame fixed in the astronomer's local position. x is due east
 * along the ground y is due north along the ground, and z points towards the
 * zenith.
 * </ol>
 *
 * <p>We calculate the local frame in phone coords, and in celestial coords and
 * calculate a transform between the two.
 * In the following, N, E, U correspond to the local
 * North, East and Up vectors (ie N, E along the ground, Up to the Zenith)
 *
 * <p>In Phone Space: axesPhone = [N, E, U]
 *
 * <p>In Celestial Space: axesSpace = [N, E, U]
 *
 * <p>We find T such that axesCelestial = T * axesPhone
 *
 * <p>Then, [viewDir, viewUp]_celestial = T * [viewDir, viewUp]_phone
 *
 * <p>where the latter vector is trivial to calculate.
 *
 * <p>Implementation note: this class isn't making defensive copies and
 * so is vulnerable to clients changing its internal state.
 *
 * @author John Taylor
 */

 

4. Finally the axes of the phone is given in rotation Matrix. So I wonder how is axes being represented in a rotation matrix? 

I would also be happy is you can point me to where I can read up more. As I do not know where to start?

Best regards and happy star gazing!

Yongchong

Edited by yong54321
Link to comment
Share on other sites

  • yong54321 changed the title to Anyone know how Astronomy app (e.g. Google star map) work?
1 hour ago, yong54321 said:

1. Why is " trueNorthCelestial = addVectors(z, scaleVector(upCelestial, -zDotu))" in the above code? So why is true North equals to upCelestial (zenith) dot product z and added to z axis? Where do this come from?

Maybe this diagram will help:

image.png.e8e24249b4cd2bc897332d187ec6a4e2.png

Given some vector that represents direction of zenith from where you standing - you want vector in direction of where is north - again along the surface of the earth.

That vector is 90° away from Celestial Up - but in direction of Zenith.

Green arrow is projection of Z along Celestial up and you need to reverse that and add to Z to get Celestial north vector.

float zDotu = scalarProduct(upCelestial, z);

part calculates full dot product which is cos(angle) * len(celestial_up) * len(z)

If you scale celestial up with that value - len(celestial_up) cancels and you get only cos(angle) * len(z) - which is projection of Z along celestial up. Minus sign in trueNorthCelestial = addVectors(z, scaleVector(upCelestial, -zDotu)) serves to point green vector the other way so it can be added with Z.

1 hour ago, yong54321 said:

2. Why need to normalise the trueNorthCelestial.normalize(); ?

It won't be normalized from above calculations. Z is unit length - and from above diagram - you can see that celestial north is shorter than Z - so it is not unit length. If unit length vector along celestial north is needed in rest of the code - it is just simply normalized.

 

1 hour ago, yong54321 said:

3. Why is the transform in the relationship axesCelestial = T * axesPhone as described below? How is the axis of the phone related to the axis of the celestial martrix? Is this related to coordinate axis transform?

Have no idea what you are asking here, but if you have two coordinate systems - like celestial one related to person holding the phone and phone coordinate system - related to phone orientation, then transformation from one to other is rotation, and rotation is multiplication by rotation matrix.

So in order to transform from one to another - you need to calculate rotation matrix and multiply with it.

1 hour ago, yong54321 said:

4. Finally the axes of the phone is given in rotation Matrix. So I wonder how is axes being represented in a rotation matrix? 

Axes of phone are just regular X,Y and Z and they are not given by rotation Matrix.

Rotation matrix serves to transform given vector from one space to other space by rotating it (same way that phone is rotated - or rather inverse of that).

Here is simple diagram again:

image.png.ec1e029642cde8f3700a83c11c0d4ece.png

Right coordinate system is rotated by 45° - but right person sees arrow as pointing straight UP - so it has (0,1) coordinates in that coordinate system. But in left coordinate system it is no longer pointing up - it is pointing at 45° and has coordinates (0.71, 0.71) (or which ever is right number there).

It is same vector on image, but if we want do draw it we need to draw it at an angle, but if rotated person wants to draw it - they need to draw it straight up - they have (0,1) coordinates, we have (0.71,0.71) coordinates - in order to switch between these two, one must use multiplication matrix that goes something like

sqrt(2)/2   0

0            sqrt(2)/2

(as sin(45) and cos(45) are square root of 2 /2 or 1/sqrt(2)).

Link to comment
Share on other sites

Hi vlaiv

 

Thank you very much for your answer. I have come to understand it. Just to clarify this part.

You say "If you scale celestial up with that value - len(celestial_up) cancels and you get only cos(angle) * len(z)". How does len(celestial_up) cancels when you scale celestial up with the zDotUp? It seems to me up is a vector and zDotU is a scalar...

 

Best regards 

Edited by yong54321
Link to comment
Share on other sites

3 hours ago, yong54321 said:

How does len(celestial_up) cancels when you scale celestial up with the zDotUp? It seems to me up is a vector and zDotU is a scalar...

zDotUp is scalar value, but look what it is:

image.png.7441880f1e2f7d60d7ca253c9ce8e9a5.png

It is product of length of both vectors and cosine of angle between them.

a is celestial up and b is z.

z has unit length so ||b|| is equal to one.

a*b = ||a|| cos(theta)

scaling is multiplication / division of length of vector with some scalar value.  If you divide vector with its length - you get unit vector in that direction.

What does scaleVector function do with its parameters?

 

Link to comment
Share on other sites

Hi vlaiv

Thanks very much! After reading your reply, I manage to work out the reason why N = Z - Z.U x U

I have upload my diagram in case anyone is interested. 

IMG_0097.jpg.4bfd38a7f92d45a0fc2c91f1a6fe4f76.jpg

Because |U| is also 1.

So Z.U = |Z||U|cos angle

Assuming angle is 45 degree,

Z.U = 1x1x0.707

It is 0.707 of the whole U vector. 

And N = Z - 0.707U as in the diagram. 

Thanks again to vlaiv. 

 

Edited by yong54321
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.