static AstroVector DirectionVector(AstroTime time, Observer observer, double altitude, double azimuth) { // Convert horizontal angles to a horizontal unit vector. var hor = new Spherical(altitude, azimuth, 1.0); AstroVector hvec = Astronomy.VectorFromHorizon(hor, time, Refraction.None); // Find the rotation matrix that converts horizontal vectors to equatorial vectors. RotationMatrix rot = Astronomy.Rotation_HOR_EQD(time, observer); // Rotate the horizontal (HOR) vector to an equator-of-date (EQD) vector. AstroVector evec = Astronomy.RotateVector(rot, hvec); return(evec); }
static int HorizontalCoords( out Spherical hor, double ecliptic_longitude, AstroTime time, RotationMatrix rot_ecl_hor) { var eclip = new Spherical( 0.0, /* being "on the ecliptic plane" means ecliptic latitude is zero. */ ecliptic_longitude, 1.0 /* any positive distance value will work fine. */ ); /* Convert ecliptic angular coordinates to ecliptic vector. */ AstroVector ecl_vec = Astronomy.VectorFromSphere(eclip, time); /* Use the rotation matrix to convert ecliptic vector to horizontal vector. */ AstroVector hor_vec = Astronomy.RotateVector(rot_ecl_hor, ecl_vec); /* Find horizontal angular coordinates, correcting for atmospheric refraction. */ hor = Astronomy.HorizonFromVector(hor_vec, Refraction.Normal); return(0); /* success */ }
static int CameraImage(Observer observer, AstroTime time) { const double tolerance = 1.0e-15; // Calculate the topocentric equatorial coordinates of date for the Moon. // Assume aberration does not matter because the Moon is so close and has such a small relative velocity. Equatorial moon_equ = Astronomy.Equator(Body.Moon, time, observer, EquatorEpoch.OfDate, Aberration.None); // Also calculate the Sun's topocentric position in the same coordinate system. Equatorial sun_equ = Astronomy.Equator(Body.Sun, time, observer, EquatorEpoch.OfDate, Aberration.None); // Get the Moon's horizontal coordinates, so we know how much to pivot azimuth and altitude. Topocentric moon_hor = Astronomy.Horizon(time, observer, moon_equ.ra, moon_equ.dec, Refraction.None); Console.WriteLine($"Moon horizontal position: azimuth = {moon_hor.azimuth:F3}, altitude = {moon_hor.altitude:F3}"); // Get the rotation matrix that converts equatorial to horizontal coordintes for this place and time. RotationMatrix rot = Astronomy.Rotation_EQD_HOR(time, observer); // Modify the rotation matrix in two steps: // First, rotate the orientation so we are facing the Moon's azimuth. // We do this by pivoting around the zenith axis. // Horizontal axes are: 0 = north, 1 = west, 2 = zenith. // Tricky: because the pivot angle increases counterclockwise, and azimuth // increases clockwise, we undo the azimuth by adding the positive value. rot = Astronomy.Pivot(rot, 2, moon_hor.azimuth); // Second, pivot around the leftward axis to bring the Moon to the camera's altitude level. // From the point of view of the leftward axis, looking toward the camera, // adding the angle is the correct sense for subtracting the altitude. rot = Astronomy.Pivot(rot, 1, moon_hor.altitude); // As a sanity check, apply this rotation to the Moon's equatorial (EQD) coordinates and verify x=0, y=0. AstroVector vec = Astronomy.RotateVector(rot, moon_equ.vec); // Convert to unit vector. double radius = vec.Length(); vec.x /= radius; vec.y /= radius; vec.z /= radius; Console.WriteLine($"Moon check: x = {vec.x}, y = {vec.y}, z = {vec.z}"); if (!double.IsFinite(vec.x) || Math.Abs(vec.x - 1.0) > tolerance) { Console.WriteLine("Excessive error in moon check (x)."); return(1); } if (!double.IsFinite(vec.y) || Math.Abs(vec.y) > tolerance) { Console.WriteLine("Excessive error in moon check (y)."); return(1); } if (!double.IsFinite(vec.z) || Math.Abs(vec.z) > tolerance) { Console.WriteLine("Excessive error in moon check (z)."); return(1); } // Apply the same rotation to the Sun's equatorial vector. // The x- and y-coordinates now tell us which side appears sunlit in the camera! vec = Astronomy.RotateVector(rot, sun_equ.vec); // Don't bother normalizing the Sun vector, because in AU it will be close to unit anyway. Console.WriteLine($"Sun vector: x = {vec.x:F6}, y = {vec.y:F6}, z = {vec.z:F6}"); // Calculate the tilt angle of the sunlit side, as seen by the camera. // The x-axis is now pointing directly at the object, z is up in the camera image, y is to the left. double tilt = RAD2DEG * Math.Atan2(vec.z, vec.y); Console.WriteLine($"Tilt angle of sunlit side of the Moon = {tilt:F3} degrees counterclockwise from up."); IllumInfo illum = Astronomy.Illumination(Body.Moon, time); Console.WriteLine($"Moon magnitude = {illum.mag:F2}, phase angle = {illum.phase_angle:F2} degrees."); double angle = Astronomy.AngleFromSun(Body.Moon, time); Console.WriteLine($"Angle between Moon and Sun as seen from Earth = {angle:F2} degrees."); return(0); }