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