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