/* * Sets up the polygons, runs the overlap computation, and returns the area of overlap. */ double computeOverlap(double *ilon, double *ilat, double *olon, double *olat, int energyMode, double refArea, double *areaRatio) { int i; double thisPixelArea; *areaRatio = 1.; if (energyMode) { nv = 0; for (i = 0; i < 4; ++i) SaveVertex(&P[i]); thisPixelArea = Girard(); *areaRatio = thisPixelArea / refArea; } nv = 0; if (DEBUG >= 4) { printf("Input (P):\n"); for (i = 0; i < 4; ++i) printf("%10.6f %10.6f\n", ilon[i], ilat[i]); printf("\nOutput (Q):\n"); for (i = 0; i < 4; ++i) printf("%10.6f %10.6f\n", olon[i], olat[i]); printf("\n"); fflush(stdout); } for (i = 0; i < 4; ++i) { P[i].x = cos(ilon[i]) * cos(ilat[i]); P[i].y = sin(ilon[i]) * cos(ilat[i]); P[i].z = sin(ilat[i]); } for (i = 0; i < 4; ++i) { Q[i].x = cos(olon[i]) * cos(olat[i]); Q[i].y = sin(olon[i]) * cos(olat[i]); Q[i].z = sin(olat[i]); } ComputeIntersection(P, Q); return (Girard()); }
double computeOverlap(double *ilon, double *ilat, double *olon, double *olat, int energyMode, double refArea, double *areaRatio) { int i; double thisPixelArea; pi = atan(1.0) * 4.; dtr = pi / 180.; *areaRatio = 1.; if(energyMode) { nv = 0; for(i=0; i<4; ++i) SaveVertex(&P[i]); thisPixelArea = Girard(); *areaRatio = thisPixelArea / refArea; } nv = 0; if(debug >= 4) { printf("\n-----------------------------------------------\n\nAdding pixel (%d,%d) to pixel (%d,%d)\n\n", inRow, inColumn, outRow, outColumn); printf("Input (P):\n"); for(i=0; i<4; ++i) printf("%10.6f %10.6f\n", ilon[i], ilat[i]); printf("\nOutput (Q):\n"); for(i=0; i<4; ++i) printf("%10.6f %10.6f\n", olon[i], olat[i]); printf("\n"); fflush(stdout); } for(i=0; i<4; ++i) { P[i].x = cos(ilon[i]*dtr) * cos(ilat[i]*dtr); P[i].y = sin(ilon[i]*dtr) * cos(ilat[i]*dtr); P[i].z = sin(ilat[i]*dtr); } for(i=0; i<4; ++i) { Q[i].x = cos(olon[i]*dtr) * cos(olat[i]*dtr); Q[i].y = sin(olon[i]*dtr) * cos(olat[i]*dtr); Q[i].z = sin(olat[i]*dtr); } ComputeIntersection(P, Q); return(Girard()); }
double Girard() { int i, j, ibad; double area; double lon, lat; Vec side[16]; double ang [16]; Vec tmp; double pi, dtr, sumang, cosAng, sinAng; pi = atan(1.0) * 4.; dtr = pi / 180.; sumang = 0.; if(nv < 3) return(0.); if(debug >= 4) { for(i=0; i<nv; ++i) { lon = atan2(V[i].y, V[i].x)/dtr; lat = asin(V[i].z)/dtr; printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", i, V[i].x, V[i].y, V[i].z, lon, lat); fflush(stdout); } } for(i=0; i<nv; ++i) { Cross (&V[i], &V[(i+1)%nv], &side[i]); (void) Normalize(&side[i]); } for(i=0; i<nv; ++i) { Cross (&side[i], &side[(i+1)%nv], &tmp); sinAng = Normalize(&tmp); cosAng = -Dot(&side[i], &side[(i+1)%nv]); /* Remove center point of colinear segments */ ang[i] = atan2(sinAng, cosAng); if(debug >= 4) { if(i==0) printf("\n"); printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n", i, ang[i], ang[i] - pi/2., sinAng, cosAng); fflush(stdout); } if(ang[i] > pi - 0.0175) /* Direction changes of less than */ { /* a degree can be tricky */ ibad = (i+1)%nv; if(debug >= 4) { printf("Girard(): ---------- Corner %d bad; Remove point %d -------------\n", i, ibad); fflush(stdout); } --nv; for(j=ibad; j<nv; ++j) { V[j].x = V[j+1].x; V[j].y = V[j+1].y; V[j].z = V[j+1].z; } return(Girard()); } sumang += ang[i]; } area = sumang - (nv-2.)*pi; if(mNaN(area) || area < 0.) area = 0.; if(debug >= 4) { printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv); fflush(stdout); } return(area); }
/* * Use Girard's theorem to compute the area of a sky polygon. */ double Girard() { int i, j, ibad; double area; double lon, lat; Vec side[16]; double ang[16]; Vec tmp; double sumang, cosAng, sinAng; sumang = 0; if (nv < 3) return 0; if (DEBUG >= 4) { for (i = 0; i < nv; ++i) { lon = atan2(V[i].y, V[i].x) / DEG_TO_RADIANS; lat = asin(V[i].z) / DEG_TO_RADIANS; printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", i, V[i].x, V[i].y, V[i].z, lon, lat); fflush(stdout); } } for (i = 0; i < nv; ++i) { Cross(&V[i], &V[(i + 1) % nv], &side[i]); Normalize(&side[i]); } for (i = 0; i < nv; ++i) { Cross(&side[i], &side[(i + 1) % nv], &tmp); sinAng = Normalize(&tmp); cosAng = -Dot(&side[i], &side[(i + 1) % nv]); // Remove center point of colinear segments ang[i] = atan2(sinAng, cosAng); if (DEBUG >= 4) { if (i == 0) printf("\n"); printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n", i, ang[i], ang[i] - M_PI / 2., sinAng, cosAng); fflush(stdout); } // Direction changes of less than a degree can be tricky if (ang[i] > M_PI - 0.0175) { ibad = (i + 1) % nv; if (DEBUG >= 4) { printf("Girard(): ---------- Corner %d bad; " "Remove point %d -------------\n", i, ibad); fflush(stdout); } --nv; for (j = ibad; j < nv; ++j) { V[j].x = V[j + 1].x; V[j].y = V[j + 1].y; V[j].z = V[j + 1].z; } return (Girard()); } sumang += ang[i]; } area = sumang - (nv - 2.) * M_PI; if (mNaN(area) || area < 0.) area = 0.; if (DEBUG >= 4) { printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv); fflush(stdout); } return area; }