Changeset 5554
- Timestamp:
- Nov 21, 2005, 9:04:02 AM (21 years ago)
- File:
-
- 1 edited
-
branches/eam_rel8_b0/psLib/src/astro/psCoord.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_rel8_b0/psLib/src/astro/psCoord.c
r5547 r5554 10 10 * @author GLG, MHPCC 11 11 * 12 * @version $Revision: 1.88.4. 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2005-11- 18 20:22:35$12 * @version $Revision: 1.88.4.2 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-11-21 19:04:02 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 76 76 XXX: Use the ADD version which is based on determinants. 77 77 *****************************************************************************/ 78 psPlaneTransform *p_psPlaneTransformLinearInvert (psPlaneTransform *transform)78 psPlaneTransform *p_psPlaneTransformLinearInvert_MHPCC(psPlaneTransform *transform) 79 79 { 80 80 PS_ASSERT_PTR_NON_NULL(transform, 0); … … 104 104 } 105 105 106 psPlaneTransform *out = psPlaneTransformAlloc( 2, 2);106 psPlaneTransform *out = psPlaneTransformAlloc(1, 1); 107 107 108 108 /* This is sample code from IfA. It didn't work initially, and I did not 109 109 spend any time debugging it. 110 111 psF64 a = transform->x->coeff[1][0]; 112 psF64 b = transform->x->coeff[0][1];113 psF64 c = transform->y->coeff[1][0];114 psF64 d = transform->y->coeff[0][1];115 psF64 e = transform->x->coeff[0][0];116 psF64 f = transform->y->coeff[0][0];117 118 psF64 invDet = 1.0 / (a * d - b * c); // Inverse of the determinant 119 120 // Not entirely sure why this works, but it appears to do so....................................! 121 out->x->coeff[1][0] = invDet * a;122 out->x->coeff[0][1] = - invDet * b;123 out->y->coeff[1][0] = - invDet * c;124 out->y->coeff[0][1] = invDet * d;125 126 out->x->coeff[0][0] = - invDet * ( d * e + c * f);127 out->y->coeff[0][0] = - invDet * ( b * e + a * f);110 XXX EAM : here is the correct matrix inversion code 111 112 psF64 r11 = transform->x->coeff[1][0]; 113 psF64 r12 = transform->x->coeff[0][1]; 114 psF64 r21 = transform->y->coeff[1][0]; 115 psF64 r22 = transform->y->coeff[0][1]; 116 psF64 xo = transform->x->coeff[0][0]; 117 psF64 yo = transform->y->coeff[0][0]; 118 119 psF64 invDet = 1.0 / (r11 * r22 - r12 * r21); // Inverse of the determinant 120 121 out->x->coeff[1][0] = +invDet * r22; 122 out->x->coeff[0][1] = -invDet * r12; 123 out->y->coeff[1][0] = -invDet * r21; 124 out->y->coeff[0][1] = +invDet * r11; 125 126 out->x->coeff[0][0] = - invDet * (r22 * xo - r12 * yo); 127 out->y->coeff[0][0] = - invDet * (r11 * yo - r21 * xo); 128 128 */ 129 129 out->x->coeff[0][0] = (-D + ((F*A)/C)) / (E - ((F*B)/C)); … … 134 134 out->y->coeff[0][1] = 1.0 / (F - ((C*E)/B)); 135 135 136 return(out); 137 } 138 139 // XXX EAM : the above code yielded NaNs for the y coeffs. below is the code 140 // using the standard matrix representation. note that this inversion 141 // requires x->nX == 1, y->nY == 1 and x->nY <= 1, y->nX <= 1 142 psPlaneTransform *p_psPlaneTransformLinearInvert(psPlaneTransform *transform) 143 { 144 PS_ASSERT_PTR_NON_NULL(transform, 0); 145 PS_ASSERT_PTR_NON_NULL(transform->x, 0); 146 PS_ASSERT_PTR_NON_NULL(transform->y, 0); 147 148 if (transform->x->nX != 1) 149 return NULL; 150 if (transform->y->nY != 1) 151 return NULL; 152 if (transform->x->nY > 1) 153 return NULL; 154 if (transform->y->nX > 1) 155 return NULL; 156 157 // this choice is consistent with the nOrder form for the polynomials 158 psPlaneTransform *out = psPlaneTransformAlloc(1, 1); 159 160 // unless the cross terms are available, set these matrix elements to 0 161 psF64 r12 = 0.0; 162 if (transform->x->nY == 1) { 163 r12 = transform->x->coeff[0][1]; 164 } 165 psF64 r21 = 0.0; 166 if (transform->y->nX == 1) { 167 r21 = transform->y->coeff[1][0]; 168 } 169 psF64 r11 = transform->x->coeff[1][0]; 170 psF64 r22 = transform->y->coeff[0][1]; 171 psF64 xo = transform->x->coeff[0][0]; 172 psF64 yo = transform->y->coeff[0][0]; 173 174 psF64 invDet = 1.0 / (r11 * r22 - r12 * r21); 175 176 // apply the results back to the polynomials 177 out->x->coeff[0][0] = -invDet * (r22 * xo - r12 * yo); 178 out->y->coeff[0][0] = -invDet * (r11 * yo - r21 * xo); 179 out->x->coeff[1][0] = +invDet * r22; 180 out->y->coeff[0][1] = +invDet * r11; 181 if (transform->x->nY == 1) { 182 out->x->coeff[0][1] = -invDet * r12; 183 } 184 if (transform->y->nX == 1) { 185 out->y->coeff[1][0] = -invDet * r21; 186 } 136 187 return(out); 137 188 } … … 389 440 PS_ASSERT_PTR_NON_NULL(projection, NULL); 390 441 391 psF64 theta = 0.0; 392 psF64 phi = 0.0; 442 psF64 phi, theta; 443 psF64 sinDp, cosDp, sinAlpha, cosAlpha, sinDelta, cosDelta; 444 psF64 sinTheta, cosPhiCT, sinPhiCT, zeta; 445 446 bool zenithal = (projection->type == PS_PROJ_TAN) ||(projection->type == PS_PROJ_SIN); 393 447 394 448 // Allocate return value 395 449 psPlane* out = psPlaneAlloc(); 396 450 397 // Convert to projection spherical coordinate system 398 theta = asin( sin(coord->d)*sin(projection->D) + 399 cos(coord->d)*cos(projection->D)*cos(coord->r-projection->R)); 400 phi = atan2( -1.0*cos(coord->d)*sin(coord->r-projection->R), 401 sin(coord->d)*cos(projection->D) - cos(coord->d)*sin(projection->D)*cos(coord->r-projection->R) ); 451 if (zenithal) { 452 sinDp = sin(projection->D); 453 cosDp = cos(projection->D); 454 sinAlpha = sin(coord->r-projection->R); 455 cosAlpha = cos(coord->r-projection->R); 456 sinDelta = sin(coord->d); 457 cosDelta = cos(coord->d); 458 459 sinTheta = sinDelta*sinDp + cosDelta*cosDp*cosAlpha; 460 cosPhiCT = sinDelta*cosDp - cosDelta*sinDp*cosAlpha; 461 sinPhiCT = -cosDelta*sinAlpha; 462 } else { 463 phi = coord->r - projection->R; 464 theta = coord->d - projection->D; 465 } 402 466 403 467 // Perform the specified projection 404 // Gnomonic projection 405 if (projection->type == PS_PROJ_TAN) { 406 out->x = (cos(theta)*sin(phi))/sin(theta); 407 out->y = (-1.0*cos(theta)*cos(phi))/sin(theta); 468 switch (projection->type) { 469 case PS_PROJ_TAN: 470 // Gnomonic projection 471 out->x = +sinPhiCT / sinTheta; 472 out->y = -cosPhiCT / sinTheta; 473 break; 474 case PS_PROJ_SIN: 408 475 // Othrographic projection 409 } else if (projection->type == PS_PROJ_SIN) { 410 out->x = cos(theta)*sin(phi); 411 out->y = -1.0*cos(theta)*cos(phi); 476 out->x = +sinPhiCT; 477 out->y = -cosPhiCT; 478 break; 479 case PS_PROJ_AIT: 412 480 // Hammer-Aitoff projection 413 } else if ( projection->type == PS_PROJ_AIT) { 414 psF64 zeta = 1.0/sqrt(0.5*(1.0+cos(theta)*cos(phi/2.0))); 481 zeta = 1.0/sqrt(0.5*(1.0+cos(theta)*cos(phi/2.0))); 415 482 out->x = 2.0*zeta*cos(theta)*sin(phi/2.0); 416 483 out->y = zeta*sin(theta); 484 break; 485 case PS_PROJ_PAR: 417 486 // Parabolic projection 418 } else if ( projection->type == PS_PROJ_PAR) {419 487 out->x = phi*(2.0*cos(2.0*theta/3.0) - 1.0); 420 488 out->y = M_PI*sin(theta/3.0); 421 } else {489 default: 422 490 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 423 491 PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN, … … 441 509 PS_ASSERT_PTR_NON_NULL(projection, NULL); 442 510 511 psF64 rho = 0.0; 512 psF64 sinTheta = 0.0; 513 psF64 cosTheta = 0.0; 514 psF64 sinPhi = 0.0; 515 psF64 cosPhi = 0.0; 516 443 517 psF64 theta = 0.0; 444 518 psF64 phi = 0.0; … … 450 524 psF64 x = coord->x*projection->Xs; 451 525 psF64 y = coord->y*projection->Ys; 526 psF64 R = sqrt(x*x + y*y); 527 528 bool zenithal = (projection->type == PS_PROJ_TAN) ||(projection->type == PS_PROJ_SIN); 452 529 453 530 // Perform inverse projection 454 // Gnonomic deprojection 455 if ( projection->type == PS_PROJ_TAN) { 456 phi = atan(-1.0*x/y); 457 theta = atan(1.0/sqrt(x*x+y*y)); 531 switch (projection->type) { 532 case PS_PROJ_TAN: 533 // Gnonomic deprojection 534 rho = sqrt (1 + R*R); 535 sinTheta = 1 / rho; 536 cosTheta = R / rho; 537 sinPhi = (R == 0) ? 0.0 : +x / R; 538 cosPhi = (R == 0) ? 1.0 : -y / R; 539 break; 540 case PS_PROJ_SIN: 458 541 // Orhtographic deprojection 459 } else if ( projection->type == PS_PROJ_SIN) { 460 phi = atan((-1.0*x)/y); 461 theta = atan( sqrt(1.0-(x*x+y*y)) / sqrt(x*x+y*y)); 542 sinTheta = sqrt (1 - R*R); 543 cosTheta = R; 544 sinPhi = (R == 0) ? 0.0 : +x / R; 545 cosPhi = (R == 0) ? 1.0 : -y / R; 546 break; 547 case PS_PROJ_AIT: 462 548 // Hammer-Aitoff deprojection 463 } else if ( projection->type == PS_PROJ_AIT) { 464 psF64 z = sqrt(1.0 - ((x/4.0)*(x/4.0)) - ((y/2.0)*(y/2.0))); 465 phi = 2.0*atan((z*x) / (2.0*(2.0*z*z-1.0)) ); 466 theta = asin(y*z); 549 // XXX EAM : need range check on z^2 : must be > 0 550 // XXX EAM : old code, ADD, and elixir code are discrepant re x/4, y/2 551 rho = sqrt(1.0 - PS_SQR(x/4.0) - PS_SQR(y/2.0)); 552 phi = 2.0*atan2((2.0*rho*rho-1.0), x*rho); 553 theta = asin(y*rho); 554 break; 555 case PS_PROJ_PAR: 467 556 // Parabolic deprojection 468 } else if ( projection->type == PS_PROJ_PAR) { 469 psF64 rho = y/M_PI; 557 rho = y/M_PI; 470 558 phi = x/(1.0 - 4.0*rho*rho); 471 559 theta = 3.0*asin(rho); 472 // Invalid deprojection type473 } else {560 break; 561 default: 474 562 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 475 563 PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN, … … 479 567 } 480 568 481 // Convert from projection spherical coordinates 482 out->d = asin( sin(theta)*sin(projection->D) + 483 cos(theta)*cos(projection->D)*cos(phi) ); 484 out->r = projection->R + atan2( -1.0*cos(theta)*sin(phi), 485 sin(theta)*cos(projection->D) - 486 cos(theta)*sin(projection->D)*cos(phi) ); 569 if (zenithal) { 570 psF64 sinDp = sin(projection->D); 571 psF64 cosDp = cos(projection->D); 572 573 // Convert from projection spherical coordinates 574 psF64 delta = asin(sinTheta*sinDp + cosTheta*cosDp*cosPhi); 575 psF64 sinAlphaF = -cosTheta*sinPhi; 576 psF64 cosAlphaF = -cosTheta*cosPhi*sinDp + sinTheta*cosDp; 577 578 out->d = delta; 579 out->r = atan2(sinAlphaF, cosAlphaF) + projection->R; 580 } else { 581 out->r = phi + projection->R; 582 out->d = theta + projection->D; 583 } 487 584 488 585 // Return sphere coordinate
Note:
See TracChangeset
for help on using the changeset viewer.
