/// <summary> /// Handles WCS calculations based on CROTA2, CDELT and tangential projection /// </summary> /// <param name="crval1">Reference x pixel value</param> /// <param name="crval2">Reference y pixel value</param> /// <param name="crpix1">Reference pixel x</param> /// <param name="crpix2">Reference pixel y</param> /// <param name="cdelta1">per pixel increment along RA</param> /// <param name="cdelta2">per pixel increment along DEC</param> /// <param name="crota2">Rotation in degrees</param> /// <remarks>Vertically and horizontally flipped images don't work as of now</remarks> public WorldCoordinateSystem( double crval1, double crval2, double crpix1, double crpix2, double cdelta1, double cdelta2, double crota2 ) { Point = new Point(crpix1, crpix2); Coordinates = new Coordinates(Angle.ByDegree(crval1), Angle.ByDegree(crval2), Epoch.J2000); if (cdelta1 >= 0 || cdelta2 < 0) { Flipped = true; } if (!Flipped) { Rotation = Astrometry.EuclidianModulus(crota2, 360); } else { Rotation = Astrometry.EuclidianModulus(-crota2, 360); } PixelScaleX = Astrometry.DegreeToArcsec(Math.Abs(cdelta1)); PixelScaleY = Astrometry.DegreeToArcsec(Math.Abs(cdelta2)); }
/// <summary> /// Handles WCS calculations based on CDn_m matrix and tangential projection /// </summary> /// <param name="crval1">Reference x pixel value</param> /// <param name="crval2">Reference y pixel value</param> /// <param name="crpix1">Reference pixel x</param> /// <param name="crpix2">Reference pixel y</param> /// <param name="cd1_1">CDn_m tranformation matrix</param> /// <param name="cd1_2">CDn_m tranformation matrix</param> /// <param name="cd2_1">CDn_m tranformation matrix</param> /// <param name="cd2_2">CDn_m tranformation matrix</param> /// <remarks> /// http://hosting.astro.cornell.edu/~vassilis/isocont/node17.html /// https://www.astro.rug.nl/~gipsy/tsk/fitsreproj.dc1 /// Vertically and horizontally flipped images don't work as of now /// </remarks> public WorldCoordinateSystem( double crval1, double crval2, double crpix1, double crpix2, double cd1_1, double cd1_2, double cd2_1, double cd2_2 ) { Point = new Point(crpix1, crpix2); Coordinates = new Coordinates(Angle.ByDegree(crval1), Angle.ByDegree(crval2), Epoch.J2000); var determinant = cd1_1 * cd2_2 - cd1_2 * cd2_1; var sign = 1; if (determinant < 0) { sign = -1; } var cdelta1 = sign * Math.Sqrt(cd1_1 * cd1_1 + cd2_1 * cd2_1); var cdelta2 = Math.Sqrt(cd1_2 * cd1_2 + cd2_2 * cd2_2); if (cdelta1 >= 0 || cdelta2 < 0) { Flipped = true; } var rot1_cd = Math.Atan2(sign * cd1_2, cd2_2); var rot2_cd = Math.Atan2(sign * cd1_1, cd2_1) - Math.PI / 2d; var rotation = Astrometry.ToDegree(Flipped ? -rot2_cd : rot2_cd); var skew = Astrometry.ToDegree(Math.Abs(rot1_cd - rot2_cd)); //Approximation as the matrix can account for skewed axes Rotation = Astrometry.EuclidianModulus(rotation, 360); PixelScaleX = Astrometry.DegreeToArcsec(Math.Abs(cdelta1)); PixelScaleY = Astrometry.DegreeToArcsec(Math.Abs(cdelta2)); }