/* Lorenz Mask in GLUT, Mariya Lazebnik, 2 May 2001 */ 
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <math.h>
#define EPS .01

float bifur=28;
float kk = 2.67 ; /* 8/3 */ 
float pand = 10; 

int showgraf=1;

float t = 1.5;  /* for the spin function */
float offX = 1; /* x-offset */
float offZ = 1; /* z-offset */

float tmp;
int hasnumber, number, decimal, sign ; 
int firsttime=1;

int i; /* for loop */

/* variables for 2-D array*/
#define MANY 5000
float dots[MANY+1][3]; /* MANY dots */

/***********************************************************/
/* assuming the window has an 800 x 400 pixels */
float xo = 400 , yo = 200 ,             /* screen origin */
      ux = 8 , uy =-8 ,             /*  screenunits */
      xx = 5, yy = -1 , zz = 0.,    /* world particle */ 
      ee = .05,            /* epsilon eye shear */ 
      ns = 200,             /* nose displacement */
      dd = .01;            /* delta stepsize  */

/***********************************************************/
/*"f" + "c" -- original position */

void firstdot(void){
  dots[0][0]=5;
  dots[0][1]=-1;
  dots[0][2]=0;
}

/***********************************************************/

void plotAdot(float xx, float yy, float red, float green, float blue){

     glColor3f(red,green,blue);
     glBegin(GL_POINTS); glVertex2f(xx,yy); 
     glEnd();
}      

/***********************************************************/
/* Manual Rotating Function */

void spin(void) {
int i;
float pi=3.14159;
float a, b; /* temporary variables */

  float t=1.5;
  for(i = 0; i<MANY; i++)
  {
/* spins around a shifted y-axis ?*/
    a = offX + dots[i][0]*cos(pi/180)-(dots[i][2] - offX)*sin(pi/180);
    b = offZ + dots[i][2]*cos(pi/180)+(dots[i][0] - offZ)*sin(pi/180);
    dots[i][0]=a; dots[i][2]=b; 
  } 
}

/***********************************************************/
calc(void){
   int ind; float xx,yy,zz, xn, yn, zn ;
   for(ind=1; ind<MANY; ind++)
   {
      xx=dots[ind-1][0];
      yy=dots[ind-1][1];
      zz=dots[ind-1][2];
      xn = xx + (pand*yy - pand*xx)*dd;
      yn = yy + (bifur*xx - xx*zz - yy)*dd;
      zn = zz + (xx*yy - zz*kk)*dd;

      dots[ind][0]=xn;
      dots[ind][1]=yn;
      dots[ind][2]=zn;
    }
      dots[0][0]=dots[MANY-1][0];
      dots[0][1]=dots[MANY-1][1];
      dots[0][2]=dots[MANY-1][2];
}
/***********************************************************/
void display(){ 

   int ind;
   float xleft = xo - ns, xriht = xo + ns; /* stereo */  
   
  {static first=1; if(first)        /* first time clear the slate */ 
   glClear(GL_COLOR_BUFFER_BIT);
   glClearColor(0.,0.,0.,0.);       /* to black */
   first =0;}
   glClear(GL_COLOR_BUFFER_BIT); /* clear screen for each set of dots */
 
   /* loop to draw all the dots */
   for (i = 0; i < MANY; i++)
   {
      plotAdot(xleft + (dots[i][0] - ee*dots[i][2])*ux, yo -
       dots[i][1]*uy, 1., 0., 1. ); 
      plotAdot(xriht + (dots[i][0] + ee*dots[i][2])*ux, yo -
       dots[i][1]*uy, 0., 1., 1. );
   }

   if(firsttime) {calc(); firsttime=0; }
      spin(); 

   /* call initial graffiti display */
   if(showgraf)  initGraffiti();

   glutSwapBuffers(); /* double buffer */

  /*  usleep(NAP);  */   
}
/****************************************************************/
float getnumber(float dflt){      /* return new or default number  */
  if(!hasnumber)return dflt;
  tmp = sign ? -number : number;
  return decimal>0 ? tmp/(float)decimal : tmp ;
}
/****************************************************************/
void offsetX(void) {
  offX=getnumber(offX);
}

void offsetZ(void) {
  offZ=getnumber(offZ);
}

void bifurc(void) {
  bifur=getnumber(bifur);
}

void prandtl(void) {
  pand=getnumber(pand);
}

void otherNum(void) {
  kk=getnumber(kk);
}

void reset(void) {
  bifur = 28;
  pand = 10;
  kk = 2.67;
  xx=5;
  yy=-1;
  offX=1;
  offZ=1;
}
/******************************************************************/
/* also takes in the (x1, y1) and (x2, y2) coordinates of the
   rectangle where the graffiti will be printed out */

void graffiti(int x1, int y1, int x2, int y2, char strng[128], float par)
{
  char buf[128], *p;
  glColor3f(0.0,0.0,0.0);  /* erase old graffiti */
  glRecti(x1, y1, x2, y2); /* black rectangle */
  glColor3f(1.0,0.0,0.0); /* create and draw new graffiti in red */
  sprintf(buf, strng, par); /* printing function */
  glRasterPos2i(10,(y1+y2)/2); /* position of first graffiti pixel */
  for(p=buf; *p; p++)glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *p);

 /*glutSwapBuffers();*/
}
/******************************************************************/
/* initial graffiti display */

initGraffiti(void) {
    char buf[128], *p;
    char strng[128]="(ESC)ape Re(C)alculate (F)irstDot (R)eset (T)oggle graffiti";
    sprintf(buf, strng, 0);
    glColor3f(1.0,0.0,0.0); /* create and draw new graffiti in red */
    glRasterPos2i(5,375); /* position of first graffiti pixel */
    for(p=buf; *p; p++)glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *p);

    graffiti(5,345,15,365, "%0.5f=(B)ifurcation", bifur);
    graffiti(5,325,15,345, "%0.5f=(P)randtl", pand);
    graffiti(5,305,15,325, "%0.5f=(K)", kk);
    graffiti(5,285,15,305, "%0.5f=(x)", offX);
    graffiti(5,265,15,285, "%0.5f=(z)", offZ); 
}
/***********************************************************/
void keyboard(unsigned char key, int x, int y){
  switch(key){ 
     case  27: fprintf(stderr," Thanks for using GLUT ! \n"); exit(0); break;

     case 'x': {offX = offX * (1+EPS); offsetX(); break;}
     case 'X': {offX = offX * (1-EPS); offsetX(); break;}     

     case 'z': {offZ = offZ * (1+EPS); offsetZ(); break;}
     case 'Z': {offZ = offZ * (1-EPS); offsetZ(); break;}

     case 't': {showgraf=!showgraf; break;} 

     case 'b': {bifur = bifur * (1+EPS); bifurc(); break;}
     case 'B': {bifur = bifur * (1-EPS); bifurc(); break;}

     case 'r': {reset(); break;} 

     case 'k': {kk = kk * (1+EPS); otherNum(); break;}
     case 'K': {kk = kk * (1-EPS); otherNum(); break;}

     case 'p': {pand = pand * (1+EPS); prandtl(); break;}
     case 'P': {pand = pand * (1-EPS); prandtl(); break;}
 
     case 'c': calc(); break;
     case 'f': firstdot(); break;
   }

   glFlush();
   /* Stuart Levy's gadget parser from avn.c 1998 */
   if(key >= '0' && key <= '9'){ hasnumber = 1;
         number = 10*number + (key - '0'); decimal *= 10;}
   else if(key == '.'){ decimal = 1;}
   else if(key == '-'){ sign = -1;}
   else {hasnumber = number = decimal = sign = 0;}
}
/***********************************************************/
void idle(void){ glutPostRedisplay(); } 
/***********************************************************/
int main(int argc, char **argv){ 
  glutInitWindowSize(800, 400);        

  dots[0][0]=5;
  dots[0][1]=-1;
  dots[0][2]=0;

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); /* double buffer */ 
  glutCreateWindow("<< Rotating Lorenz, Mariya Lazebnik >>");
  glutDisplayFunc(display);
  glutKeyboardFunc(keyboard);
  glutIdleFunc(idle); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,800,0,400,-10.0,10.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

Home