IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 29, 2005, 4:00:11 PM (21 years ago)
Author:
desonia
Message:

merged eam_r8.0_b2 into CVS trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/astro/psCoord.c

    r5588 r5624  
    1010*  @author GLG, MHPCC
    1111*
    12 *  @version $Revision: 1.93 $ $Name: not supported by cvs2svn $
    13 *  @date $Date: 2005-11-23 23:54:43 $
     12*  @version $Revision: 1.94 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2005-11-30 02:00:00 $
    1414*
    1515*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    6161should rename this.
    6262 
    63 To derive this transformation, start with the simple 2-by-2 matrix inversion
    64 based on discriminants.  This will invert the
    65     (x_2, y_2) = matrix(a b c d) * vector (x, y)
    66 where there are no constant terms.  Then you substitute
    67     x_2 = x_1 - e
    68     y_2 = y_1 - f
    69 for (x_2, y_2) to get the desired inverse.
     63XXX: Use the ADD version which is based on determinants.
    7064 *****************************************************************************/
     65
     66// XXX EAM : below is the code using the standard matrix representation.
     67//           note that this inversion requires x->nX == 1, y->nY == 1 and
     68//           x->nY <= 1, y->nX <= 1
    7169psPlaneTransform *p_psPlaneTransformLinearInvert(psPlaneTransform *transform)
    7270{
     
    130128    //    printf("HMMM: out->y: (%f %f %f)\n", out->y->coeff[0][0], out->y->coeff[1][0], out->y->coeff[0][1]);
    131129
     130
     131    // unless the cross terms are available, set these matrix elements to 0
     132    psF64 r12 = 0.0;
     133    if (transform->x->nY == 1) {
     134        r12 = transform->x->coeff[0][1];
     135    }
     136    psF64 r21 = 0.0;
     137    if (transform->y->nX == 1) {
     138        r21 = transform->y->coeff[1][0];
     139    }
     140    psF64 r11 = transform->x->coeff[1][0];
     141    psF64 r22 = transform->y->coeff[0][1];
     142    psF64 xo  = transform->x->coeff[0][0];
     143    psF64 yo  = transform->y->coeff[0][0];
     144
     145    psF64 invDet = 1.0 / (r11 * r22 - r12 * r21);
     146
     147    // apply the results back to the polynomials
     148    out->x->coeff[0][0] = -invDet * (r22 * xo - r12 * yo);
     149    out->y->coeff[0][0] = -invDet * (r11 * yo - r21 * xo);
     150    out->x->coeff[1][0] = +invDet * r22;
     151    out->y->coeff[0][1] = +invDet * r11;
     152    if (transform->x->nY == 1) {
     153        out->x->coeff[0][1] = -invDet * r12;
     154    }
     155    if (transform->y->nX == 1) {
     156        out->y->coeff[1][0] = -invDet * r21;
     157    }
    132158    return(out);
    133159}
     
    327353XXX: Private Function.
    328354 
    329 piNormalize(): take an input angle in radians and convert it to the range
    330 0:2*PI.
     355piNormalize(): take an input angle in radians and convert it to the range 0:2*PI.
    331356 *****************************************************************************/
    332357psF32 piNormalize(psF32 angle)
     
    380405    PS_ASSERT_PTR_NON_NULL(projection, NULL);
    381406
    382     psF64   theta = 0.0;
    383     psF64   phi   = 0.0;
     407    psF64 phi, theta;
     408    psF64 sinDp, cosDp, sinAlpha, cosAlpha, sinDelta, cosDelta;
     409    psF64 sinTheta, cosPhiCT, sinPhiCT, zeta;
     410
     411    bool zenithal = (projection->type == PS_PROJ_TAN) ||(projection->type == PS_PROJ_SIN);
    384412
    385413    // Allocate return value
     
    391419    }
    392420
    393     // Convert to projection spherical coordinate system
    394     theta = asin( sin(coord->d)*sin(projection->D) +
    395                   cos(coord->d)*cos(projection->D)*cos(coord->r-projection->R));
    396     phi = atan2( -1.0*cos(coord->d)*sin(coord->r-projection->R),
    397                  sin(coord->d)*cos(projection->D) - cos(coord->d)*sin(projection->D)*cos(coord->r-projection->R) );
     421    if (zenithal) {
     422        sinDp = sin(projection->D);
     423        cosDp = cos(projection->D);
     424        sinAlpha = sin(coord->r-projection->R);
     425        cosAlpha = cos(coord->r-projection->R);
     426        sinDelta = sin(coord->d);
     427        cosDelta = cos(coord->d);
     428
     429        sinTheta =  sinDelta*sinDp + cosDelta*cosDp*cosAlpha;
     430        cosPhiCT =  sinDelta*cosDp - cosDelta*sinDp*cosAlpha;
     431        sinPhiCT = -cosDelta*sinAlpha;
     432    } else {
     433        phi = coord->r - projection->R;
     434        theta = coord->d - projection->D;
     435    }
    398436
    399437    // Perform the specified projection
    400     // Gnomonic projection
    401     if (projection->type == PS_PROJ_TAN) {
    402         out->x = (cos(theta)*sin(phi))/sin(theta);
    403         out->y = (-1.0*cos(theta)*cos(phi))/sin(theta);
     438    switch (projection->type) {
     439    case PS_PROJ_TAN:
     440        // Gnomonic projection
     441        out->x = +sinPhiCT / sinTheta;
     442        out->y = -cosPhiCT / sinTheta;
     443        break;
     444    case PS_PROJ_SIN:
    404445        // Othrographic projection
    405     } else if (projection->type == PS_PROJ_SIN) {
    406         out->x = cos(theta)*sin(phi);
    407         out->y = -1.0*cos(theta)*cos(phi);
     446        out->x = +sinPhiCT;
     447        out->y = -cosPhiCT;
     448        break;
     449    case PS_PROJ_AIT:
    408450        // Hammer-Aitoff projection
    409     } else if ( projection->type == PS_PROJ_AIT) {
    410         psF64 zeta = 1.0/sqrt(0.5*(1.0+cos(theta)*cos(phi/2.0)));
     451        zeta = 1.0/sqrt(0.5*(1.0+cos(theta)*cos(phi/2.0)));
    411452        out->x = 2.0*zeta*cos(theta)*sin(phi/2.0);
    412453        out->y = zeta*sin(theta);
     454        break;
     455    case PS_PROJ_PAR:
    413456        // Parabolic projection
    414     } else if ( projection->type == PS_PROJ_PAR) {
    415457        out->x = phi*(2.0*cos(2.0*theta/3.0) - 1.0);
    416458        out->y = M_PI*sin(theta/3.0);
    417     } else {
     459    default:
    418460        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    419461                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
     
    424466
    425467    // Apply plate scales
    426     out->x *= projection->Xs;
    427     out->y *= projection->Ys;
     468    out->x /= projection->Xs;
     469    out->y /= projection->Ys;
    428470
    429471    // Return output
     
    444486    PS_ASSERT_PTR_NON_NULL(coord, NULL);
    445487    PS_ASSERT_PTR_NON_NULL(projection, NULL);
     488
     489    psF64 rho      = 0.0;
     490    psF64 sinTheta = 0.0;
     491    psF64 cosTheta = 0.0;
     492    psF64 sinPhi   = 0.0;
     493    psF64 cosPhi   = 0.0;
    446494
    447495    psF64  theta = 0.0;
     
    458506
    459507    // Remove plate scales
    460     // XXX: Verify this.  EAM suggested we do a multiply, however that does
    461     // not make sense if we also do the multiply in psProject().
    462     psF64  x = coord->x/projection->Xs;
    463     psF64  y = coord->y/projection->Ys;
     508    psF64  x = coord->x*projection->Xs;
     509    psF64  y = coord->y*projection->Ys;
     510    psF64  R = sqrt(x*x + y*y);
     511
     512    bool zenithal = (projection->type == PS_PROJ_TAN) ||(projection->type == PS_PROJ_SIN);
    464513
    465514    // Perform inverse projection
    466     // Gnonomic deprojection
    467     if ( projection->type == PS_PROJ_TAN) {
    468         phi = atan(-1.0*x/y);
    469         theta = atan(1.0/sqrt(x*x+y*y));
     515    switch (projection->type) {
     516    case PS_PROJ_TAN:
     517        // Gnonomic deprojection
     518        rho      = sqrt (1 + R*R);
     519        sinTheta = 1 / rho;
     520        cosTheta = R / rho;
     521        sinPhi   = (R == 0) ? 0.0 : +x / R;
     522        cosPhi   = (R == 0) ? 1.0 : -y / R;
     523        break;
     524    case PS_PROJ_SIN:
    470525        // Orhtographic deprojection
    471     } else if ( projection->type == PS_PROJ_SIN) {
    472         phi = atan((-1.0*x)/y);
    473         theta = atan( sqrt(1.0-(x*x+y*y)) / sqrt(x*x+y*y));
     526        sinTheta = sqrt (1 - R*R);
     527        cosTheta = R;
     528        sinPhi   = (R == 0) ? 0.0 : +x / R;
     529        cosPhi   = (R == 0) ? 1.0 : -y / R;
     530        break;
     531    case PS_PROJ_AIT:
    474532        // Hammer-Aitoff deprojection
    475     } else if ( projection->type == PS_PROJ_AIT) {
    476         psF64 z = sqrt(1.0 - ((x/4.0)*(x/4.0)) - ((y/2.0)*(y/2.0)));
    477         phi = 2.0*atan((z*x) / (2.0*(2.0*z*z-1.0)) );
    478         theta = asin(y*z);
     533        // XXX EAM : need range check on z^2 : must be > 0
     534        // XXX EAM : old code, ADD, and elixir code are discrepant re x/4, y/2
     535        rho = sqrt(1.0 - PS_SQR(x/4.0) - PS_SQR(y/2.0));
     536        phi = 2.0*atan2((2.0*rho*rho-1.0), x*rho);
     537        theta = asin(y*rho);
     538        break;
     539    case PS_PROJ_PAR:
    479540        // Parabolic deprojection
    480     } else if ( projection->type == PS_PROJ_PAR) {
    481         psF64 rho = y/M_PI;
     541        rho = y/M_PI;
    482542        phi = x/(1.0 - 4.0*rho*rho);
    483543        theta = 3.0*asin(rho);
    484         // Invalid deprojection type
    485     } else {
     544        break;
     545    default:
    486546        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    487547                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
     
    491551    }
    492552
    493     // Convert from projection spherical coordinates
    494     out->d = asin( sin(theta)*sin(projection->D) +
    495                    cos(theta)*cos(projection->D)*cos(phi) );
    496     out->r = projection->R + atan2( -1.0*cos(theta)*sin(phi),
    497                                     sin(theta)*cos(projection->D) -
    498                                     cos(theta)*sin(projection->D)*cos(phi) );
     553    if (zenithal) {
     554        psF64 sinDp = sin(projection->D);
     555        psF64 cosDp = cos(projection->D);
     556
     557        // Convert from projection spherical coordinates
     558        psF64 delta = asin(sinTheta*sinDp + cosTheta*cosDp*cosPhi);
     559        psF64 sinAlphaF = -cosTheta*sinPhi;
     560        psF64 cosAlphaF = -cosTheta*cosPhi*sinDp + sinTheta*cosDp;
     561
     562        out->d = delta;
     563        out->r = atan2(sinAlphaF, cosAlphaF) + projection->R;
     564    } else {
     565        out->r = phi   + projection->R;
     566        out->d = theta + projection->D;
     567    }
    499568
    500569    // Return sphere coordinate
Note: See TracChangeset for help on using the changeset viewer.