Changeset 5624 for trunk/psLib/src/astro/psCoord.c
- Timestamp:
- Nov 29, 2005, 4:00:11 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/astro/psCoord.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astro/psCoord.c
r5588 r5624 10 10 * @author GLG, MHPCC 11 11 * 12 * @version $Revision: 1.9 3$ $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 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 61 61 should rename this. 62 62 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. 63 XXX: Use the ADD version which is based on determinants. 70 64 *****************************************************************************/ 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 71 69 psPlaneTransform *p_psPlaneTransformLinearInvert(psPlaneTransform *transform) 72 70 { … … 130 128 // printf("HMMM: out->y: (%f %f %f)\n", out->y->coeff[0][0], out->y->coeff[1][0], out->y->coeff[0][1]); 131 129 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 } 132 158 return(out); 133 159 } … … 327 353 XXX: Private Function. 328 354 329 piNormalize(): take an input angle in radians and convert it to the range 330 0:2*PI. 355 piNormalize(): take an input angle in radians and convert it to the range 0:2*PI. 331 356 *****************************************************************************/ 332 357 psF32 piNormalize(psF32 angle) … … 380 405 PS_ASSERT_PTR_NON_NULL(projection, NULL); 381 406 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); 384 412 385 413 // Allocate return value … … 391 419 } 392 420 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 } 398 436 399 437 // 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: 404 445 // 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: 408 450 // 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))); 411 452 out->x = 2.0*zeta*cos(theta)*sin(phi/2.0); 412 453 out->y = zeta*sin(theta); 454 break; 455 case PS_PROJ_PAR: 413 456 // Parabolic projection 414 } else if ( projection->type == PS_PROJ_PAR) {415 457 out->x = phi*(2.0*cos(2.0*theta/3.0) - 1.0); 416 458 out->y = M_PI*sin(theta/3.0); 417 } else {459 default: 418 460 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 419 461 PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN, … … 424 466 425 467 // Apply plate scales 426 out->x *= projection->Xs;427 out->y *= projection->Ys;468 out->x /= projection->Xs; 469 out->y /= projection->Ys; 428 470 429 471 // Return output … … 444 486 PS_ASSERT_PTR_NON_NULL(coord, NULL); 445 487 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; 446 494 447 495 psF64 theta = 0.0; … … 458 506 459 507 // 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); 464 513 465 514 // 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: 470 525 // 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: 474 532 // 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: 479 540 // Parabolic deprojection 480 } else if ( projection->type == PS_PROJ_PAR) { 481 psF64 rho = y/M_PI; 541 rho = y/M_PI; 482 542 phi = x/(1.0 - 4.0*rho*rho); 483 543 theta = 3.0*asin(rho); 484 // Invalid deprojection type485 } else {544 break; 545 default: 486 546 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 487 547 PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN, … … 491 551 } 492 552 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 } 499 568 500 569 // Return sphere coordinate
Note:
See TracChangeset
for help on using the changeset viewer.
