/*                  bonsai7.c                  */
/* translated to Amiga C by Terry W. Gintz     */
/* from Atari Basic version by R. I. Macdonald */


double r5[8][2],h[8][2],ln1[129][10],x[129][10],y[129][10],z[129][10];
double diam,dl,dr,ff,hhh,h4,qx,qy,qz,r1,r2,rd1,rd2,t,udx,udy,udz,w,wid;
short int c,div,divflg,jp,h1,h2,h3,l,ls,ln[129][2][10],mm,oldiv,ps,q;
void controllers(),diverge();
char name[31],filename1[31],filename2[31];
FILE *fp;
double con = .0174532;
extern int SPSin(),SPCos(),SPPow(),SPTieee(),SPFieee();

bonsai(j1)
short int j1;
{
   autogo();
   gen(j1);
}

autogo()
{
   short int i;

   l = 7;
   wid = 6.0+(double)RangeRand(3);
   diam = .6+.2*drand48();
   h1 = RangeRand(60);
   h2 = RangeRand(65);
   dl = 2.0*drand48();
   dr = 2.0*drand48();
   r1 = .6+.1*drand48();
   r2 = .7+.2*drand48();
   rd1 = 0;
   rd2 = 0;
   if (h1<5 || h2<5){
      i=RangeRand(4);
      switch(i) {
         case 0:
            div=180;
            break;
         case 1:
            div=120;
            break;
         case 2:
            div=140;
            break;
         case 3:
            div=135;
            break;
      }
   }
   else
      div=0;
   udx =-.1+drand48()*.2;
   udy =-.1+drand48()*.2;
   udz =-.1+drand48()*.2;
   mm = RangeRand(2);
   if (mm==1){
      ff = .05+.02*drand48();
      qx = (double)(RangeRand(2));
      qy = (double)(RangeRand(2));
      qz = (double)(RangeRand(2));
   }
   else {
      ff=0;
      qx=0;
      qy=0;
      qz=0;
   }
}

gen(j1)
short int j1;
{
   short int p;
   register short int gp,j,j2,j3,j5,j6,jg;
   double con1,cos1,f,q1,s,sin1,u,v;

   divflg=0;
   h3=0;
   f=2.0;
   h2=-h2;
   for (j=1;j<=l;j++) {
      j2=j-1;
      h[j][0]=h1+j2*dl;
      h[j][1]=h2-j2*dr;
      r5[j][0]=r1+j2*rd1;
      r5[j][1]=r2+j2*rd2;
   }
   ps=128;
   x[1][j1]=0;
   x[2][j1]=0;
   y[1][j1]=0;
   y[2][j1]=0;
   z[1][j1]=0;
   z[2][j1]=1;
   ls=127;
   j=2;
   controllers(j,j1);
   w=1.0;
   t=1.0;
   q=2;
   h4=1.0;
   jp=2;
   jg=1;
   c=0;
   j=3;
   vertical(j,0,j1);
   c=1;
   j=4;
   divflg=1;
   vertical(j,0,j1);
   ln[0][0][j1]=0;
   ln[0][1][j1]=0;
   ln[1][0][j1]=0;
   ln[1][1][j1]=0;
   ln[2][0][j1]=1;
   ln[2][1][j1]=2;
   vertical(j,0,j1);
   ln1[0][j1]=wid;
   ln1[1][j1]=wid;
   ln1[2][j1]=wid;
   wid=wid*diam;
   ln1[3][j1]=wid;
   ln1[4][j1]=wid;
   oldiv=0;
   for (q=3;q<=l;q++){
      if (q==4||q==6)
         h4=1.0;
      else
         h4=-1.0;
      wid=wid*diam;
      if (div>0)
         divflg=1;
      q1=(double)q;
      h3=0;
      j3=(short int)(pow(f,q1-3.0)+1.001);
      j2=(short int)(pow(f,q1-2.0)+.001);
      j5=(short int)(pow(f,q1-1.0)+1.001);
      j6=(short int)(pow(f,q1-2.0)+1.001);
      for (jg=j3;jg<=j2;jg++){
         gp=jg-j3;
         for (p=0;p<=1;p++){
            for (c=0;c<=1;c++){
               j=j5+c+2*p+4*gp;
               jp=j6+p+2*gp;
               ln[j][0][j1]=jp;
               ln[j][1][j1]=j;
               ln1[j][j1]=wid;
               u=x[jp][j1]-x[jg][j1];
               v=y[jp][j1]-y[jg][j1];
               w=z[jp][j1]-z[jg][j1];
               k1.num1=u*u+v*v;
               k2.num2=k1.num1+w*w;
               k3.num3=0.5;
               k1.i1=SPFieee(k1.i1);
               k2.i2=SPFieee(k2.i2);
               k3.i3=SPFieee(k3.i3);
               k4.i4=SPPow(k3.i3,k2.i2);
               k5.i5=SPPow(k3.i3,k1.i1);
               k4.i4=SPTieee(k4.i4);
               k5.i5=SPTieee(k5.i5);
               t=k4.num4;
               s=k5.num5;
               if (s==0){
                  vertical(j,1,j1);
               }
               else {
                  s=1/s;
                  hhh=h[q][c];
                  if ((c==1)&&(div!=0)){
                     hhh=hhh*h4;
                     if (h3==0)
                        hhh=abs(hhh);
                  }
                  con1=con*hhh;
                  k1.num1=con1;
                  k1.i1=SPFieee(k1.i1);
                  k2.i2=SPSin(k1.i1);
                  k3.i3=SPCos(k1.i1);
                  k2.i2=SPTieee(k2.i2);
                  k3.i3=SPTieee(k3.i3);
                  sin1=s*t*k2.num2;
                  cos1=k3.num3;
                  x[j][j1]=udx+x[jp][j1]+r5[q][c]*(u*cos1-v*sin1);
                  y[j][j1]=udy+y[jp][j1]+r5[q][c]*(v*cos1+u*sin1);
                  z[j][j1]=udz+z[jp][j1]+r5[q][c]*w*cos1;
                  diverge(j,j1);
               }
            }
         h3=1;
         }
      }
   }
}

void controllers(j,j1)
short int j,j1;
{
   double fx,lk;

   if (mm==0)
      return;
   qx=qx-x[j][j1];
   qy=qy-y[j][j1];
   qz=qz-z[j][j1];
   fx=ff;
   lk=pow(qx*qx+qy*qy+qz*qz,0.5);
   x[j][j1]=fx*(qx/lk)+x[j][j1];
   y[j][j1]=fx*(qy/lk)+y[j][j1];
   z[j][j1]=fx*(qz/lk)+z[j][j1];
}

vertical(j,sw,j1)
short int j,j1,sw;
{
   double con1;

   if (sw==0){
      ln[j][0][j1]=jp;
      ln[j][1][j1]=j;
      ln1[j][j1]=wid;
   }
   hhh=h[q][c];
   if ((c==1)&&(div!=0)){
      hhh=hhh*h4;
      if (h3==0)
         hhh=abs(hhh);
   }
   con1=con*hhh;
   y[j][j1]=udy+y[jp][j1]+r5[q][c]*t*sin(con1);
   x[j][j1]=udx+x[jp][j1];
   z[j][j1]=udz+z[jp][j1]+r5[q][c]*w*cos(con1);
   diverge(j,j1);
}

void diverge(j,j1)
short int j,j1;
{
   double con1,ph,phi,dx,dy,rd;

   if ((divflg==0) || (c==0)){
      controllers(j,j1);
      return;
   }
   oldiv=oldiv+div;
   ph = 180.0;
   dx=x[j][j1]-x[jp][j1];
   dy=y[j][j1]-y[jp][j1];
   rd=pow(dx*dx+dy*dy,0.5);
   if (dx==0){
      phi=ph/2.0;
      if (dy<=0)
         phi=phi+ph;
   }
   else {
      phi=atan(con*(dy/dx));
      phi=phi*180/PI;
      if (dx>0){
         if (dy<0)
            phi=phi+2*ph;
      }
      else
         phi=ph+phi;
   }
   con1=con*(double)(oldiv+phi);
   x[j][j1]=x[jp][j1]+rd*cos(con1);
   y[j][j1]=y[jp][j1]+rd*sin(con1);
   divflg=0;
   controllers(j,j1);
}

exchange()
{
   double tt;
   short int tx;

   tx=h2;
   h2=h1;
   h1=tx;
   tt=dl;
   dl=dr;
   dr=tt;
}

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

   strcpy(filename1,name);
   strcat(filename1,".pnt");
   strcpy(filename2,name);
   strcat(filename2,".lin");
   fp=fopen(filename1,"w");
   for (i=1;i<=ps;i++) {
      fprintf (fp,"%lf\t%lf\t%lf\n",x[i][j1],y[i][j1],z[i][j1]);
   }
   fclose(fp);
   fp=fopen(filename2,"w");
   for (i=1;i<=ls;i++) {
      fprintf (fp,"%d\t%d\t%lf\n",ln[i][0][j1],ln[i][1][j1],ln1[i][j1]);
   }
   fclose(fp);
}
