/* Lorenz Mask in GLUT, Mariya Lazebnik, 2 May 2001 */ 

#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <math.h>
#include <unistd.h>
#define EPS .01

float bifur = 28;  /* the bifurcation parameter */ 
float kk = 2.67;   /* the third parameter */
float pand = 10;   /* the prandtl number */

float initialbifur= 28;
float finalbifur= 28;

float initialpand= 10;
float finalpand= 10;

float initialkk= 2.67;
float finalkk= 2.67;

int showgraf=1;  /* flag for displaying graffiti */ 
int moviestat=0; /* flag for movie function */

float tmp;

int hasnumber, number, decimal, sign; /* for getnumber function */ 

int i; /* for loop */

/* variables for 2-D array*/
#define MANY 500
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  */

/***********************************************************/
void plotAdot(float xx, float yy, float red, float green, float blue){
     glColor3f(red,green,blue);
     glBegin(GL_POINTS); glVertex2f(xx,yy); 
     glEnd();
}      

/**************************************************************/
/* 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();*/
}

/************************************************************/
void display(void){ 

   float xleft = xo - ns, xriht = xo + ns; /* stereo */  
   float xn, yn, zn; /* new x, y, z */ 
  
   {static first=1; if(first) {     
   glClear(GL_COLOR_BUFFER_BIT);
   glClearColor(0.,0.,0.,0.);   }  
    first =0;}
   
   glClear(GL_COLOR_BUFFER_BIT); 

   /* loop to draw all the dots */
   for (i = 0; i < 5000; i++)
   {
      /* Update dots */
      xn = xx + (pand*yy - pand*xx)*dd; 
      yn = yy + (bifur*xx - xx*zz - yy)*dd;
      zn = zz + (xx*yy - zz*kk)*dd;

      xx = xn;  yy = yn;  zz = zn;

      plotAdot(xleft + (xn - ee*zn)*ux, yo - yn*uy, 1., 0., 1. ); 
      plotAdot(xriht + (xn + ee*zn)*ux, yo - yn*uy, 0., 1., 1. );
   }

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

   glutSwapBuffers(); /* double buffer */
}

/******************************************************************/
void graffitiText(char strng[128]) {
   char buf[128], *p;
   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);
}

/******************************************************************/
/* initial graffiti display */

initGraffiti(void) {
 
if (moviestat==0) {
    graffitiText("(ESC)ape (S)pin (R)eset (T)oggle graffiti (M)ovie");
    graffiti(5,345,50,365, "%0.5f=(B)ifurcation", bifur);
    graffiti(5,325,50,345, "%0.5f=(P)randtl", pand);
    graffiti(5,305,50,325, "%0.5f=(K)", kk);
}

if (moviestat==1) {
    graffitiText("Type Initial Values for B, P, and K; Press 'm' to continue");
    graffiti(5,345,50,365, "%0.5f=(B)ifurcation", initialbifur);
    graffiti(5,325,50,345, "%0.5f=(P)randtl", initialpand);
    graffiti(5,305,50,325, "%0.5f=(K)", initialkk);
}

if (moviestat==2) {
    graffitiText("Type Final Values for B, P, and K; Press 'm' to play movie");
    graffiti(5,345,50,365, "%0.5f=(B)ifurcation", finalbifur);
    graffiti(5,325,50,345, "%0.5f=(P)randtl", finalpand);
    graffiti(5,305,50,325, "%0.5f=(K)", finalkk);
}

if (moviestat==3) {
    graffitiText("Playing Movie...");
    graffiti(5,345,50,365, "%0.5f=(B)ifurcation", bifur);
    graffiti(5,325,50,345, "%0.5f=(P)randtl", pand);
    graffiti(5,305,50,325, "%0.5f=(K)", kk);
}

}

/****************************************************************/
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 bifurc(void) {
  if (moviestat==0) {bifur=getnumber(bifur);}
  if (moviestat==1) {initialbifur=getnumber(bifur);}
  if (moviestat==2) {finalbifur=getnumber(bifur);}
}

void prandtl(void) {
  if (moviestat==0) {pand=getnumber(pand);}
  if (moviestat==1) {initialpand=getnumber(pand);}
  if (moviestat==2) {finalpand=getnumber(pand);}

}

void otherNum(void) {
  if (moviestat==0) {kk=getnumber(kk);}
  if (moviestat==1) {initialkk=getnumber(kk);}
  if (moviestat==2) {finalkk=getnumber(kk);}
}

void reset(void) {
  bifur = 28; 
  pand = 10; 
  kk = 2.67; 
  xx=5; 
  yy=-1; 
}

/**************************************************************/
void movie(void) {

  for (bifur=initialbifur; bifurinitialbifur; (bifur=bifur*(1-EPS)))
   {
      display();
      sginap(10);
   }
  sginap(250);
  reset();

  for (pand=initialpand; pandinitialpand; (pand=pand*(1-EPS)))
   {
      display();
      sginap(10);
   }
  sginap(250);
  reset();

  for (kk=initialkk; kkinitialkk; (kk=kk*(1-EPS)))
   {
      display();
      sginap(10);
   }
  sginap(250);
  reset();
  moviestat=0;
}

/*************************************************************/
void keyboard(unsigned char key, int x, int y){
  switch(key){ 
     case  27: fprintf(stderr," Thanks for using GLUT ! \n"); exit(0); break;
     case 't': {showgraf=!showgraf; break;} 

     case 's': {glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.,0.,0.,0.); glFlush(); glutSwapBuffers();  system("/afs/ncsa.uiuc.edu/projects/MATH198/lazebnik/final/lorrot"); 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 'm': {moviestat++; if (moviestat==3) movie(); 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);        
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); /* double buffer */ 
  glutCreateWindow("<< Lorenz in GLUT, 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