[comp.sys.sgi] Render a 3D Chaotic attractor on your IRIS.

paul@manray.asd.sgi.com (Paul Haeberli) (11/07/90)

Here's a fun little program. . . .  Give it a try.

paul haeberli
paul@sgi.com
415-962-3665


/*
 *	smoke -
 *		create an image of a 3-D chaotic attractor. 
 *	From a paper by Clifford Pickover called "A Note on
 *	Rendering 3-D Strange Attractors" from Computers
 *	and Graphics Vol 12, No 2. pp. 263-267, 1988.
 *
 *	To Compile:
 *		cc smoke.c -o smoke -lgl_s -lm
 *
 *			Paul Haeberli - 1990
 *
 */
#include "math.h"
#include "gl.h"
#include "device.h"

#define SIZE	512
unsigned char *buf;

main()
{
    unsigned char *cptr;
    float xxmin, xxmax;
    float yymin, yymax;
    float xinc, yinc;
    float xx, yy, zz;
    int xxx, yyy;
    int iter;
    float a, b, c, d, e;
    float x, y, z;
    int i, j, ic;
    short val;

    iter = 10*SIZE*SIZE;
    buf = (unsigned char *)malloc(SIZE*SIZE*sizeof(unsigned char));
    bzero(buf,SIZE*SIZE*sizeof(unsigned char));
    prefsize(SIZE,SIZE);
    winopen("smoke");
    RGBmode();
    gconfig();
    cpack(0x000000);
    clear();
    xxmax = 2.0;
    xxmin = -2.0;
    yymax = 2.0;
    yymin = -2.0;
    xinc = SIZE/(xxmax-xxmin);
    yinc = SIZE/(yymax-yymin);
    a = 2.24;
    b = 0.43;
    c = -0.65;
    d = -2.43;
    e = 1.00;
    x = y = z = 0.0;
    for(i=1; i<=iter; i++) {
	xx = sin(a*y)-z*cos(b*x);
	yy = z*sin(c*x)-cos(d*y);
	zz = e*sin(x);
	x = xx; 
	y = yy; 
	z = zz;
	xxx = (xx-xxmin)*xinc;
	yyy = (yy-yymin)*yinc;
	if(xxx>=0 && xxx<SIZE && yyy>=0 && yyy<SIZE) {
	    cptr = buf+((yyy*SIZE)+xxx);
	    if(*cptr<255) {
		(*cptr)++;
		setcolor(*cptr);
		pnt2i(xxx,yyy);
	    }
	}
	if(i%1000 == 0) {
	    while(qtest()) {
		if(qread(&val) == REDRAW)
		    drawit();
	    }
	}
    }    
    ringbell();
    printf("done!!!\n");
    while(1) {
	if(qread(&val) == REDRAW) {
	    drawit();
	}
    }
}

setcolor(c)
int c;
{
    c = c*4;
    if(c>255)
       c = 255;
    cpack(0x010101*c);
}

drawit()
{
    int x, y;
    unsigned char *cptr;

    reshapeviewport();
    ortho2(-0.5,SIZE-0.5,-0.5,SIZE-0.5);
    cptr = buf;
    for(y=0; y<SIZE; y++) {
	for(x=0; x<SIZE; x++) {
	    setcolor(*cptr++);
	    pnt2i(x,y);
	}
    }
}