1 #include <stdio.h> 2 #include <math.h> 3 4 /* 5 * take the x-ayis along the line between A and B with origin halfway 6 * between but z = 0 is the height of the launch platform. 7 * (xa, ya, za) = (-dist/2, 0, ha) is the location of theodolite A 8 * (xb, yb, zb) = (+dist/2, 0, hb) is the location of theodolite B 9 * the sight line from A is 10 * x = -(dist/2) + cos(alpha)*cos(gamma)*ta = xa + dxa*ta 11 * y = cos(alpha)*sin(gamma)*ta = ya + dya*ta 12 * z = ha + sin(alpha)*ta = za + dza*ta 13 * the sight line form b is 14 * x = (dist/2) + cos(beta)*cos(delta)*tb = xb + dxb*tb 15 * y = cos(beta)*sin(delta)*tb = yb + dyb*tb 16 * z = hb + sin(beta)*tb = zb + dzb*tb 17 * 18 * the vertical plane containing sightline A is 19 * x = xa + dxa*ta, y = ya + dya*ta, z = anything OR (x - xa)/dxa = (y - ya)/dya 20 * or x*dya - y*dxa = xa*dya - ya*dxa = R 21 * similarly the vertical plane containing sightline B is 22 * x*dyb - y*dxb = xa*dyb - ya*dxb = S 23 * solving (cramer's rule): 24 * x = (S*dxa - R*dxb)/(dyb*dxa - dya*dxb) 25 * y = (S*dya - R*dyb)/(dyb*dxa - dya*dxb) 26 * z = anything is the vertical line 27 * plug this into the sight line equations 28 * if (fabs(dxa) > fabs(dya)) ta = (x - xa)/dxa else ta = (y - ya)/dya 29 * if (fabs(dxb) > fabs(dyb)) tb = (x - xb)/dxb else tb = (y - yb)/dyb 30 * rza = za + ta*dza 31 * rzb = zb + tb*dzb 32 * if(fabs(rza - rzb) > errdist) error 33 * else z_res = (rza + rzb)/2.0 34 */ 35 #define EPS .01 36 37 char inbuf[512]; 38 39 int main() 40 { 41 int nProbs, probNum, z_out; 42 double alpha, beta, gamma, delta, deg2rad; 43 double xa, xb, ya, yb, za, zb, dxa, dxb, dya, dyb, dza, dzb; 44 double R, S, x, y, rza, rzb, ta, tb, z_res, dist, denom, offset, errdist; 45 46 if (fgets(&(inbuf[0]), 511, stdin) == NULL) 47 { 48 fprintf(stderr, "Read failed on problem count\n"); 49 return -1; 50 } 51 if (sscanf(&(inbuf[0]), "%d", &nProbs) != 1) 52 { 53 fprintf(stderr, "Scan failed on problem count\n"); 54 return -2; 55 } 56 if ((nProbs < 1) || (nProbs > 1000)) 57 { 58 fprintf(stderr, "problem count %d not in range 1 to 1000\n", nProbs); 59 return -3; 60 } 61 // get global parameters 62 if (fgets(&(inbuf[0]), 255, stdin) == NULL) 63 { 64 fprintf(stderr, "read failed on global parameters\n"); 65 return -4; 66 } 67 if (sscanf(&(inbuf[0]), "%lf %lf %lf %lf %lf", &dist, &offset, &za, &zb, &errdist) != 5) 68 { 69 fprintf(stderr, "scan failed on global parameters\n"); 70 return -5; 71 } 72 deg2rad = atan2(1.0,1.0)/45.0; 73 xb = dist * 0.5; 74 xa = -xb; 75 yb = ya = 0.0; 76 77 for (probNum = 1; probNum <= nProbs ; probNum++) 78 { 79 if (fgets(&(inbuf[0]), 511, stdin) == NULL) 80 { 81 fprintf(stderr, "Read failed on problem dims problem %d\n", probNum); 82 return -6; 83 } 84 if (sscanf(&(inbuf[0]), "%lf %lf %lf %lf", &alpha, &beta, &gamma, &delta) != 4) 85 { 86 fprintf(stderr, "scan failed on problem %d\n", probNum); 87 return -7; 88 } 89 if ((alpha <= 0.0) || (alpha >= 90.0) || 90 (beta <= 0.0) || (beta >= 90.0) || 91 (gamma <= 0.0) || (gamma >= 90.0) || 92 (delta <= 90.0) || (delta >= 180.0)) 93 { 94 printf("%d DISQUALIFIED\n", probNum); 95 continue; 96 } 97 dxa = cos(deg2rad*alpha)*cos(deg2rad*gamma); 98 dya = cos(deg2rad*alpha)*sin(deg2rad*gamma); 99 dza = sin(deg2rad*alpha); 100 dxb = cos(deg2rad*beta)*cos(deg2rad*delta); 101 dyb = cos(deg2rad*beta)*sin(deg2rad*delta); 102 dzb = sin(deg2rad*beta); 103 104 R = xa*dya - ya*dxa; 105 S = xb*dyb - yb*dxb; 106 denom = dyb*dxa - dya*dxb; 107 if (fabs(denom) < EPS) 108 { 109 printf("%d DIV BY ZERO\n", probNum); 110 continue; 111 } 112 x = (S*dxa - R*dxb)/denom; 113 y = (S*dya - R*dyb)/denom; 114 if (fabs(dxa) >= fabs(dya)) 115 { 116 ta = (x - xa)/dxa; 117 } 118 else 119 { 120 ta = (y - ya)/dya; 121 } 122 if (fabs(dxb) >= fabs(dyb)) 123 { 124 tb = (x - xb)/dxb; 125 } 126 else 127 { 128 tb = (y - yb)/dyb; 129 } 130 rza = za + ta*dza; 131 rzb = zb + tb*dzb; 132 if (fabs(rza - rzb) > errdist) 133 { 134 printf("%d ERROR\n", probNum); 135 } 136 else 137 { 138 z_res = (rza + rzb)/2.0; 139 z_out = (int)(z_res + 0.5); 140 printf("%d %d\n", probNum, z_out); 141 } 142 } 143 return 0; 144 } 145