vide_public/external/healpix/cxxsupport/trafos.cc
2012-10-30 13:56:48 -04:00

158 lines
5 KiB
C++

/*
* This file is part of libcxxsupport.
*
* libcxxsupport is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* libcxxsupport is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file trafos.cc
* Celestial coordinate transformations.
*
* Copyright (C) 2005 Max-Planck-Society
* \author Martin Reinecke
*/
#include "trafos.h"
#include "lsconstants.h"
using namespace std;
vec3 Trafo::xcc_dp_precess (const vec3 &iv, double iepoch,
double oepoch)
{
// Z-axis rotation by OBL_LONG:
double Tm = ((oepoch+iepoch)*0.5 - 1900.) *0.01;
double gp_long = degr2rad * ((oepoch-iepoch) * (50.2564+0.0222*Tm) / 3600.);
double obl_long =
degr2rad * (180. - (173. + (57.06+54.77*Tm) / 60.)) + gp_long*0.5;
double dco = cos(obl_long), dso = sin(obl_long);
vec3 ov (iv.x*dco-iv.y*dso, iv.x*dso+iv.y*dco, iv.z);
// X-axis rotation by dE:
double dE = degr2rad * ((oepoch-iepoch) * (0.4711-0.0007*Tm) / 3600.);
double dce = cos(dE), dse = sin(dE);
double temp = ov.y*dce - ov.z*dse;
ov.z = ov.y*dse + ov.z*dce;
ov.y = temp;
// Z-axis rotation by GP_LONG - OBL_LONG:
double dL = gp_long - obl_long;
double dcl = cos(dL), dsl = sin(dL);
temp = ov.x*dcl - ov.y*dsl;
ov.y = ov.x*dsl + ov.y*dcl;
ov.x = temp;
return ov;
}
double Trafo::get_epsilon (double epoch)
{
double T = (epoch - 1900.) * 0.01;
return
degr2rad * (23.452294 - 0.0130125*T - 1.63889e-6*T*T + 5.02778e-7*T*T*T);
}
/*! Routine to convert from ecliptic coordinates to equatorial (celestial)
coordinates at the given epoch. Adapted from the COBLIB routine by Dr.
E. Wright. */
vec3 Trafo::xcc_dp_e_to_q (const vec3 &iv, double epoch)
{
double epsilon=get_epsilon(epoch);
double dc = cos(epsilon), ds = sin(epsilon);
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
}
vec3 Trafo::xcc_dp_q_to_e (const vec3 &iv, double epoch)
{
double epsilon=-get_epsilon(epoch);
double dc = cos(epsilon), ds = sin(epsilon);
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
}
/*! Routine to convert galactic coordinates to ecliptic (celestial)
coordinates at the given epoch. First the conversion to ecliptic
2000 is done, then if necessary the results are precessed. */
vec3 Trafo::xcc_dp_g_to_e (const vec3 &iv, double epoch)
{
static const rotmatrix T (-0.054882486, 0.494116468, -0.867661702,
-0.993821033, -0.110993846, -0.000346354,
-0.096476249, 0.862281440, 0.497154957);
vec3 hv=T.Transform(iv);
if (!approx(epoch,2000.))
hv=xcc_dp_precess(hv,2000.,epoch);
return hv;
}
/*! Routine to convert ecliptic (celestial) coordinates at the given
epoch to galactic coordinates. The ecliptic coordinates are first
precessed to 2000.0, then converted. */
vec3 Trafo::xcc_dp_e_to_g (const vec3 &iv, double epoch)
{
static const rotmatrix T (-0.054882486, -0.993821033, -0.096476249,
0.494116468, -0.110993846, 0.862281440,
-0.867661702, -0.000346354, 0.497154957);
vec3 hv=iv;
if (!approx(epoch,2000.))
hv=xcc_dp_precess(hv,epoch,2000.);
return T.Transform(hv);
}
/*! Function to convert between standard coordinate systems, including
precession. */
vec3 Trafo::xcc_v_convert(const vec3 &iv, double iepoch, double oepoch,
coordsys isys,coordsys osys)
{
vec3 xv;
if (isys == Ecliptic)
xv=iv;
else if (isys == Equatorial)
xv = xcc_dp_q_to_e(iv,iepoch);
else if (isys == Galactic)
xv = xcc_dp_g_to_e(iv,iepoch);
else
planck_fail("Unsupported input coordinate system");
vec3 yv = approx(iepoch,oepoch) ? xv : xcc_dp_precess(xv,iepoch,oepoch);
vec3 ov;
if (osys == Ecliptic)
ov = yv;
else if (osys == Equatorial)
ov = xcc_dp_e_to_q(yv,oepoch);
else if (osys == Galactic)
ov = xcc_dp_e_to_g(yv,oepoch);
else
planck_fail("Unsupported output coordinate system");
return ov;
}
void Trafo::coordsys2matrix (double iepoch, double oepoch,
coordsys isys, coordsys osys, rotmatrix &matrix)
{
vec3 v1p = xcc_v_convert(vec3(1,0,0),iepoch,oepoch,isys,osys),
v2p = xcc_v_convert(vec3(0,1,0),iepoch,oepoch,isys,osys),
v3p = xcc_v_convert(vec3(0,0,1),iepoch,oepoch,isys,osys);
v1p.Normalize(); v2p.Normalize(); v3p.Normalize();
matrix=rotmatrix(v1p,v2p,v3p);
}