Changeset 39688
- Timestamp:
- Sep 11, 2016, 2:36:01 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/20160809/Ohana/src/libdvo/src/coordops.c
r39608 r39688 84 84 85 85 /** extra polynomial terms **/ 86 // for ZPN, these are used to modify the radial distance and not the X,Y coords 86 87 if ((coords[0].Npolyterms > 1) && (proj != PROJ_ZPN)) { 87 88 X2 = X*X; … … 157 158 ctht = 0.0; 158 159 } else { 159 T = DEG_RAD / R; 160 stht = T / sqrt ( 1.0 + T*T); 161 ctht = 1.0 / sqrt ( 1.0 + T*T); 160 // T = DEG_RAD / R; // T in 1/radians 161 // stht = T / sqrt ( 1.0 + T*T); 162 // ctht = 1.0 / sqrt ( 1.0 + T*T); 163 164 T = RAD_DEG * R; 165 stht = 1.0 / sqrt ( 1.0 + T*T); 166 ctht = T / sqrt ( 1.0 + T*T); 162 167 } 168 break; 169 case PROJ_SIN: 170 // R = (180/pi) cos (theta) 171 ctht = RAD_DEG * R; 172 stht = sqrt (1 - ctht*ctht); 163 173 break; 164 174 case PROJ_STG: … … 167 177 ctht = sqrt (1 - stht*stht); 168 178 break; 169 case PROJ_SIN:170 // R = (180/pi) cos (theta)171 ctht = RAD_DEG * R;172 stht = sqrt (1 - ctht*ctht);173 break;174 179 case PROJ_ARC: 175 180 // R = 90 - theta (degrees) … … 177 182 stht = cos (RAD_DEG * R); 178 183 break; 179 180 case PROJ_ZPN:181 // R = 90 - theta (degrees)182 // this is wrong because we are ignoring the distortion183 // XXX For now, just solve for terms up to n = 3184 185 // Ro = (pi/180)(90 - theta)186 // R = (180/pi)sum (P_i R^i)187 188 if (UKIRT_ONLY) {189 double Ro = RAD_DEG * R;190 double P1 = coords[0].polyterms[0][1];191 double P3 = coords[0].polyterms[0][3];192 193 // find the roots of f(gamma) = P1 gamma + P3 gamma^3 - Ro194 // starting guess for gamma is Ro / P1195 double gamma = Ro / P1;196 197 int i;198 for (i = 0; i < 5; i++) {199 double F = P1*gamma + P3*gamma*gamma*gamma - Ro;200 double dFdgamma = P1 + 3.0*P3*gamma*gamma;201 202 double gamma_new = gamma - F / dFdgamma;203 gamma = gamma_new;204 }205 206 double theta = 90.0 - gamma * DEG_RAD ;207 ctht = cos (RAD_DEG * theta);208 stht = sin (RAD_DEG * theta);209 break;210 }211 184 212 185 case PROJ_ZEA: … … 220 193 ctht = sqrt (1 - stht*stht); 221 194 break; 195 196 case PROJ_ZPN: 197 198 // the forward projection is: 199 // theta = atan2(stht, ctht) 200 // gamma = (pi/2 - theta) : theta in radians 201 // Ro = sum (P_i gamma^i) 202 // R = (180/pi) Ro 203 204 // given R, we need to find theta: 205 // Ro = R * (pi / 180) = sum (P_i gamma^i) 206 // solve sum (P_i gamma^i) - Ro = 0 using Newton-Raphson 207 208 // use Ro to get a guess for gamma and iterate 209 210 { 211 double Ro = RAD_DEG * R; 212 213 // find the roots of f(gamma) - Ro = 0 214 // starting guess for gamma is (Ro - P0) / P1 215 double gamma = (Ro - coords[0].polyterms[0][0]) / coords[0].polyterms[1][0]; 216 217 int iter; 218 for (iter = 0; iter < 5; iter++) { 219 220 double Rc = 0.0; // this will hold the ander 221 double dR = 0.0; 222 for (int i = coords[0].Npolyterms - 1; i > 1; i--) { 223 double Pi = (i < 7) ? coords[0].polyterms[i][0] : coords[0].polyterms[i-7][1]; 224 Rc = (Rc + Pi)*gamma; 225 dR = (dR + i*Pi)*gamma; 226 } 227 double P0 = coords[0].polyterms[0][0]; 228 double P1 = coords[0].polyterms[1][0]; 229 Rc = (Rc + P1)*gamma + P0; 230 dR = (dR + P1); 231 232 double gamma_new = gamma - (Rc - Ro) / dR; 233 gamma = gamma_new; 234 } 235 236 double theta = 90.0 - gamma * DEG_RAD ; 237 ctht = cos (RAD_DEG * theta); 238 stht = sin (RAD_DEG * theta); 239 break; 240 } 241 222 242 default: 223 243 return (FALSE); … … 354 374 355 375 case PROJ_ZPN: 376 // the forward projection is: 377 // theta = atan2(stht, ctht) 378 // gamma = (pi/2 - theta) : theta in radians 379 // Ro = sum (P_i gamma^i) 380 // R = (180/pi) Ro 381 356 382 // Ro = (pi/180)(90 - theta) 357 383 // R = (180/pi)sum (P_i R^i) 384 385 // is ZPN defined for Npolyterms = 0 or 1? 386 358 387 ctht = hypot(sphi, cphi); 359 388 theta = atan2 (stht, ctht); 360 389 361 double Rc; 362 if (UKIRT_ONLY) { 363 double P1 = coords[0].polyterms[0][1]; 364 double P3 = coords[0].polyterms[0][3]; 365 double gamma = RAD_DEG * (90 - DEG_RAD * theta); 366 Rc = P1*gamma + P3*gamma*gamma*gamma; 367 } else { 368 double Ro = RAD_DEG * (90 - DEG_RAD * theta); 369 370 // i = 0 .. Npolyterms - 1 (1 <= Npolyterms <= 21) 371 i = coords[0].Npolyterms - 1; 372 Rc = 0.0; 373 while (i > 0) { 374 if (i < 7) { 375 Rc = (Rc + coords[0].polyterms[0][i])*Ro; 376 } else { 377 Rc = (Rc + coords[0].polyterms[1][i-7])*Ro; 378 } 379 i --; 380 } 381 Rc += coords[0].polyterms[0][i]; 390 double Ro; 391 double gamma = M_PI_2 - theta; 392 393 // i = 0 .. Npolyterms - 1 (1 <= Npolyterms <= 21) 394 Ro = 0.0; 395 for (i = coords[0].Npolyterms - 1; i > 0; i --) { 396 double Pi = (i < 7) ? coords[0].polyterms[i][0] : coords[0].polyterms[i-7][1]; 397 Ro = (Ro + Pi)*gamma; 382 398 } 383 Rc = DEG_RAD * Rc; 399 Ro += coords[0].polyterms[0][0]; 400 401 Rc = DEG_RAD * Ro; 384 402 385 403 *L = (ctht == 0.0) ? 0.0 : +Rc * sphi / ctht ; … … 609 627 enum {COORD_TYPE_NONE, COORD_TYPE_PC, COORD_TYPE_ROT, COORD_TYPE_CD, COORD_TYPE_LIN}; 610 628 629 int GetRadialZPN (Coords *coords, Header *header); 630 611 631 int GetCoords (Coords *coords, Header *header) { 612 632 613 int i,status, status1, status2, itmp, Polynomial, Polyterm;633 int status, status1, status2, itmp, Polynomial, Polyterm; 614 634 double Lambda, rotate, rotate1, rotate2, scale; 615 635 double equinox; … … 666 686 status &= gfits_scan (header, "PC002002", "%f", 1, &coords[0].pc2_2); 667 687 688 ctype = &coords[0].ctype[4]; 689 690 // read the ZPN coeffients PV2_i (i = 0 < 14) 691 // ZPN is inconsistent with the other Polynomial types 692 if (!strcmp (ctype, "-ZPN")) { 693 GetRadialZPN (coords, header); 694 break; 695 } 696 668 697 /* set NPLYTERM based on header. if NPLYTERM is missing, it should have a 669 698 value of 0, unless the projection type is one of PLY, DIS, WRP, in which 670 699 case it should be set to 3 */ 671 ctype = &coords[0].ctype[4];672 700 Polynomial = !strcmp (ctype, "-PLY") || !strcmp (ctype, "-DIS") || !strcmp (ctype, "-WRP"); 673 701 Polyterm = gfits_scan (header, "NPLYTERM", "%d", 1, &itmp); … … 723 751 coords[0].pc2_1 = sin(rotate*RAD_DEG) / Lambda; 724 752 coords[0].pc2_2 = cos(rotate*RAD_DEG); 753 754 // read the ZPN coeffients PV2_i (i = 0 < 14) 755 if (!strcmp (&coords[0].ctype[4], "-ZPN")) GetRadialZPN (coords, header); 725 756 break; 726 757 … … 744 775 coords[0].pc2_2 /= scale; 745 776 746 if (!strcmp (&coords[0].ctype[4], "-ZPN")) { 747 int found; 748 for (i = 0; i < 14; i++) { 749 char name[64]; 750 snprintf (name, 64, "PV2_%d", i); 751 if (i < 7) { 752 found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[0][i]); 753 } else { 754 found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[1][i-7]); 755 } 756 if ((i == 0) && !found) { 757 coords[0].polyterms[0][0] = 0.0; 758 continue; 759 } 760 if ((i == 1) && !found) { 761 coords[0].polyterms[0][1] = 1.0; 762 continue; 763 } 764 if (!found) { 765 coords[0].Npolyterms = i; 766 break; 767 } 768 } 769 } 777 // read the ZPN coeffients PV2_i (i = 0 < 14) 778 if (!strcmp (&coords[0].ctype[4], "-ZPN")) GetRadialZPN (coords, header); 770 779 break; 771 780 … … 819 828 } 820 829 return (status); 830 } 831 832 int GetRadialZPN (Coords *coords, Header *header) { 833 834 // RA---ZPN can have up to 14 radial polynomial terms. these are stored in 835 // polyterms[0][0] - [6][0] for the first 7 and [0][1] - [6][1] for the rest 836 // these terms are coeffients of a polynomial of the radial distances 837 838 // read the ZPN coeffients PV2_i (i = 0 < 14) 839 int found; 840 int Nmax = 0; 841 for (int i = 0; i < 14; i++) { 842 char name[64]; 843 snprintf (name, 64, "PV2_%d", i); 844 if (i < 7) { 845 coords[0].polyterms[i][0] = 0.0; 846 found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[i][0]); 847 } else { 848 coords[0].polyterms[i-7][1] = 0.0; 849 found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[i-7][1]); 850 } 851 // PV2_1 is implicit if not present 852 if ((i == 1) && !found) { 853 coords[0].polyterms[1][0] = 1.0; 854 continue; 855 } 856 // set Npolyterms based on the largest coefficient found 857 if (found) { 858 Nmax = i; 859 } 860 } 861 coords[0].Npolyterms = Nmax + 1; 862 return TRUE; 821 863 } 822 864
Note:
See TracChangeset
for help on using the changeset viewer.
