#include <stdio.h>

/*
   Syntax: $0
   Author: Chris Alfeld
   Created: 12/10/94
   Purpose: Output a povray #declare statement for a pyramid based on the 
sierpinski triangle. 
*/

/*** Types ***/
struct Pt_S {
  float x,y,z;
};
typedef struct Pt_S Pt;

/*** Functions ***/
/*
   t - top
   f - bottom-front
   r - bottom-right
   l - bottom-left
*/
void DrawTri(Pt t,Pt f,Pt r,Pt l,int d);

/*** Prefs ***/
#define DEPTH 3
#define RADIUS 0.01

/*** Code ***/
main()
{
  Pt t,f,r,l;
  
  /* Initial points */
  t.z=0;
  t.x=0;
  t.y=1;
  
  f.z=1;
  f.x=0;
  f.y=0;
  
  r.z=-1;
  r.x=1;
  r.y=0;
  
  l.z=-1;
  l.x=-1;
  l.y=0;

  /* Header */
  printf("// Generate by SierPyr - Chris Alfeld\n");
  printf("#declare SierPyr = union {\n");

  /* Body */
  DrawTri(t,f,r,l,DEPTH);

  /* tail */
  printf("}\n");
}

/***/
void DrawTri(Pt t,Pt f,Pt r,Pt l,int d)
{
  Pt T,F,R,L; /* new points */

  if (d>0) {
  /** Output current triangle **/

    if (d == 1) {
  /* t->f */
  printf("// T:%f,%f,%f F:%f,%f,%f R:%f,%f,%f L:%f,%f,%f D:%f\n",t.x,t.y,t.z,f.x,f.y,f.z,r.x,r.y,r.z,l.x,l.y,l.z,d);
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",t.x,t.y,t.z,f.x,f.y,f.z,RADIUS);
  /* t->r */
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",t.x,t.y,t.z,r.x,r.y,r.z,RADIUS);
  /* t->l */
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",t.x,t.y,t.z,l.x,l.y,l.z,RADIUS);
  /* r->l */
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",r.x,r.y,r.z,l.x,l.y,l.z,RADIUS);
  /* r->f */
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",r.x,r.y,r.z,f.x,f.y,f.z,RADIUS); 
  /* l->f */
  printf("\tcylinder { <%f,%f,%f>,<%f,%f,%f>,%f }\n",l.x,l.y,l.z,f.x,f.y,f.z,RADIUS);
}

  /** New tri 1 - T **/
  T.z=t.z;
  T.x=t.x;
  T.y=t.y;
  
  F.z=(f.z+t.z)/2;
  F.x=(f.x+t.x)/2;
  F.y=(f.y+t.y)/2;
  
  R.z=(r.z+t.z)/2;
  R.x=(r.x+t.x)/2;
  R.y=(r.y+t.y)/2;
  
  L.z=(l.z+t.z)/2;
  L.x=(l.x+t.x)/2;
  L.y=(l.y+t.y)/2;

  DrawTri(T,F,R,L,d-1);
  
  /** New tri 2 - F **/
  F.z=f.z;
  F.x=f.x;
  F.y=f.y;
  
  T.x=(t.x+f.x)/2;
  T.y=(t.y+f.y)/2;
  T.z=(t.z+f.z)/2;

  R.x=(r.x+f.x)/2;
  R.y=(r.y+f.y)/2;
  R.z=(r.z+f.z)/2;
  
  L.x=(l.x+f.x)/2;
  L.y=(l.y+f.y)/2;
  L.z=(l.z+f.z)/2;

  DrawTri(T,F,R,L,d-1);

  /** New tri 3 - R **/
  R.z=r.z;
  R.x=r.x;
  R.y=r.y;

  T.x=(t.x+r.x)/2;
  T.y=(t.y+r.y)/2;
  T.z=(t.z+r.z)/2;

  L.x=(l.x+r.x)/2;
  L.y=(l.y+r.y)/2;
  L.z=(l.z+r.z)/2;

  F.x=(f.x+r.x)/2;
  F.y=(f.y+r.y)/2;
  F.z=(f.z+r.z)/2;

  DrawTri(T,F,R,L,d-1);

  /** New tri 4 - L **/
  L.z=l.z;
  L.x=l.x;
  L.y=l.y;

  T.x=(t.x+l.x)/2;
  T.y=(t.y+l.y)/2;
  T.z=(t.z+l.z)/2;

  R.x=(r.x+l.x)/2;
  R.y=(r.y+l.y)/2;
  R.z=(r.z+l.z)/2;

  F.x=(f.x+l.x)/2;
  F.y=(f.y+l.y)/2;
  F.z=(f.z+l.z)/2;

  DrawTri(T,F,R,L,d-1);
  }
}



