heal.cpp

Go to the documentation of this file.
00001 /* ====================================================================================
00002 HEALPix-related local routines.
00003 ==================================================================================== */
00004 /*
00005                         Fetch header files.
00006 */
00007 #include <iostream>
00008 #include <math.h>
00009 #include "heal.h"
00010 #include "map_exception.h"
00011 
00012 using namespace std;
00013 /*
00014                         Constants.
00015 */
00016 const double lambda0 = 0;       // offset
00017 /* ----------------------------------------------------------------------------
00018 'xy2pix' converts an x-y coordinate into a pixel number.
00019 
00020 Arguments:
00021         ix,iy - The x-y coordinates.
00022 
00023 Returned:
00024         pix - The pixel number.
00025 
00026 Written by Nicholas Phillips.
00027 ---------------------------------------------------------------------------- */
00028 long xy2pix(long ix, long iy)
00029 {
00030         static int x2pix[128];
00031         static int y2pix[128];
00032         static bool xy2pix_called = false;
00033         if( ! xy2pix_called ) {
00034                 mk_xy2pix(x2pix, y2pix);
00035         xy2pix_called = true;
00036         }
00037         //int ix_low = (int)fmod(ix,128);
00038         int ix_low = ix % 128;
00039         int ix_hi  = ix / 128;
00040         int iy_low = iy % 128;
00041         int iy_hi  = iy / 128;
00042         return (x2pix[ix_hi]+y2pix[iy_hi]) * (128 * 128)
00043                         + (x2pix[ix_low]+y2pix[iy_low]);
00044 }
00045 /* ----------------------------------------------------------------------------
00046 'toMollweide' converts phi/lambda into x/y and theta, implementing a conversion
00047 into the Molleweide projection.
00048 
00049 Arguments:
00050         phi,lambda - The input coordinates (colatitude and longitude), in radians.
00051         x,y        - The output cartesian coordinates.
00052 
00053 Returned:
00054         theta - The auxiliary angle.
00055 
00056 Written by Nicholas Phillips.
00057 ---------------------------------------------------------------------------- */
00058 double toMollweide(const double phi, const double lambda, double &x, double &y)
00059 {
00060         const double r2 = sqrt(2.);
00061         double theta;
00062         x = phi;
00063         y = lambda;
00064 /*
00065                         Start by solving 2theta + sin(2theta) == pi sin(phi), for theta
00066 
00067                                 Upper limit.
00068 */
00069         if( fabs(x - M_PI/2) < 1e-6) {
00070                 theta = M_PI/2;
00071         }
00072 /*
00073                                 Lower limit
00074 */
00075         else if (fabs(x + M_PI/2) < 1e-6 ) {
00076                 theta = -M_PI/2;
00077         }
00078         else {
00079 /*
00080                                 Iterative computation using Newton's method.
00081 */
00082                 const int nmax = 20;            // max number of iterations for Newton's method
00083                 const double eps = 1e-6;        // how well we solve for theta
00084                 int i;
00085                 double dtheta;
00086                 double f,df;
00087                 theta = x/2;                                                                    // The initial guess.
00088                 f = 2*theta + sin(2*theta) - M_PI*sin(phi);     // Solve for this function.
00089                 for(i = 0; i < nmax; i++) {
00090                         if( fabs(f) < eps)
00091                                 break;
00092                         df = 2*(1+cos(2*theta));
00093                         dtheta = -f/df;
00094                         theta += dtheta;
00095                         f = 2*theta + sin(2*theta) - M_PI*sin(x);
00096                 }
00097         }
00098 /*
00099                         Now that we have the theta, we can compute the cartesian coordinates.
00100 */
00101         x = 2. * r2 * (y - lambda0) * cos(theta) / M_PI;
00102         y = r2 * sin(theta);
00103         
00104         return theta;
00105 }
00106 /* ----------------------------------------------------------------------------
00107 'fromMollweide' converts x/y into phi/lambda, implementing a conversion from
00108 the Molleweide projection.
00109 
00110 Arguments:
00111         x,y        - The input cartesian coordinates.
00112         phi,lambda - The output coordinates (colatitude and longitude), in radians.
00113 
00114 Returned:
00115         theta - The auxiliary angle.
00116 
00117 Written by Michael R. Greason, ADNET, 05 September 2007.
00118 ---------------------------------------------------------------------------- */
00119 double fromMollweide(const double x, const double y, double &phi, double &lambda)
00120 {
00121         const double r2 = sqrt(2.);
00122         const double pi2 = M_PI / 2.;
00123         double theta;
00124         if (fabs(y) > r2) throw MapException(MapException::Other);
00125         theta  = asin(y / r2);
00126         phi    = pi2 - asin(((2. * theta) + sin(2. * theta)) / M_PI);
00127         lambda = lambda0 + ((M_PI * x) / (2. * r2 * cos(theta)));
00128         return theta;
00129 }

Generated on Fri Feb 6 15:32:42 2009 for Skyviewer by  doxygen 1.4.7