/* perspec4.c */


short int m1,m2,n1,n2,l1,l2,t1,t2;
short tv,yt;
double g[11],oy,p[129][3],zoom;
double ax,ay,az,k,kk,vcx,vcy,vcz,xad,xc,x1,x2,x9,yad,y9,yc,y1,y2;
double r,vz,scl,xs0,ys0;
double cy,cz,dy,dz,u1,s2,s3,scy,xw,yw,zw,xs,ys;
void calcplot(),clipit(),widen(),visible();
extern int pt,color;
extern SHORT mx,my;
int osx,osy,valid;

perspec(host)
int host;
{
   osx=mx;
   osy=199-my;
   scy=1.0;
   g[7]=0;
   g[6]=319;
   g[5]=199;
   yt=0;
   if (host==1){
      bonsai(0);
      xs=3.5;
      ys=0;
      vz=2.0;
      oy=10.0;
      zoom=1.0;
      SetAPen(rp,color);
      generate(0);
   }
   else {
      xs=3.5;
      ys=0;
      vz=2.0;
      oy=10.0;
      zoom=1.0;
      strcpy(filename1,name);
      strcat(filename1,".pnt");
      strcpy(filename2,name);
      strcat(filename2,".lin");
      valid=getfile(0);
      SetAPen(rp,color);
      if (valid==1)
         generate(0);
   }
}

getfile(j1)
short int j1;
{
   register short int i;

   fp=fopen(filename1,"r");
   if (fp==NULL){
      for (valid=0;valid<=200000;valid++)
      ;
      return(0);
   }
   ps=128;
   for (i=1;i<=ps;i++){
      fscanf (fp,"%lf%lf%lf",&x[i][j1],&y[i][j1],&z[i][j1]);
   }
   fclose(fp);
   fp=fopen(filename2,"r");
   if (fp==NULL){
      for (valid=0;valid<=200000;valid++)
      ;
      return(0);
   }
   ls=127;
   for (i=1;i<=ls;i++){
      fscanf (fp,"%h%h%lf",&ln[i][0][j1],&ln[i][1][j1],&ln1[i][j1]);
   }
   fclose(fp);
   return(1);
}

generate(j1)
short int j1;
{
   register short int i;

   x[0][j1]=0;
   y[0][j1]=0;
   z[0][j1]=vz;
   dy=-oy;
   dz=vz;
   u1=sqrt(dy*dy+dz*dz);
   cy=dy/u1;
   cz=dz/u1;
   s3=sqrt(1.0-cz*cz);
   s2=sqrt(1.0-cy*cy);
   qy=oy+cy;
   qz=cz;
   i=0;
      xw=x[0][j1];
      yw=y[0][j1];
      zw=z[0][j1];
      visible();
      calcplot(i);
   for (i=1;i<=ps;i++){
         xw=x[i][j1]*scl+xs;
         yw=y[i][j1]*scl+ys;
         zw=z[i][j1]*scl;
         visible();
         calcplot(i);
   }
   scale(j1);
}

void visible()
{
   vcx=xw;
   vcy=yw-oy;
   vcz=zw;
}

void calcplot(i)
short int i;
{
   k=1.0/(vcy*cy+vcz*cz);
   ax=k*vcx;
   ay=oy+k*vcy;
   az=k*vcz;
   if (s3!=0){
      p[i][1]=(ax*cy)/s3;
      p[i][2]=(az-qz)/s3;
      return;
   }
   p[i][1]=(-ax*cz)/s2;
   p[i][2]=(ay-qy)/s2;
}

scale(j1)
short int j1;
{
   register short int i;
   double t;

   t=450.0*zoom;
   for (i=0;i<=ps;i++){
      p[i][1]=p[i][1]*t;
      p[i][2]=p[i][2]*t;
   }
   xad=160.0-p[0][1];
   yad=96.0-p[0][2];
   for (i=1;i<=ps;i++){
      p[i][1]=p[i][1]+xad;
      p[i][2]=p[i][2]+yad;
   }
   drawit(j1);
}

drawit(j1)
short int j1;
{
   register short int i;

   for (i=1;i<=ls;i++){
         x1=p[(ln[i][0][j1])][1];
         y1=191-p[(ln[i][0][j1])][2];
         x2=p[(ln[i][1][j1])][1];
         y2=191-p[(ln[i][1][j1])][2];
         w=ln1[i][j1]/2.0;
         w*=zoom;
         xc=x1;
         yc=y1;
         x9=x2;
         y9=y2;
         widen();
   }
}

void widen()
{
   double j;

   if ((x9==xc)&&(y9==yc))
      return;
   if (w<.4) {
      clipit();
      return;
   }
   for (j=-w/2.0;j<=w/2.0;j+=.4){
      x1=x1+.5;
      y1=y1+.5;
      x2=x2+.5;
      y2=y2+.5;
      clipit();
   }
}

void clipit()
{
   m1=(short int)x1+osx;
   m2=(short int)x2+osx;
   n1=(short int)(scy*y1)-osy;
   n2=(short int)(scy*y2)-osy;
   Move(rp,m1,n1);
   Draw(rp,m2,n2);
}
