/* 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