home *** CD-ROM | disk | FTP | other *** search
- //
-
- //+---------------------------------------------------------------------+
-
- //+ Program ATRACTOR.CPP 16/05/94 +
-
- //+ By Rafael GOMEZ {gomez@gosc.enst-bretagne.fr} (France) +
-
- //+ +
-
- //+ PLOTS A ROTATING Lorenz ATRACTOR IN 3D. +
-
- //+ +
-
- //+ Based on the program LORENZ.CPP +
-
- //+ By Ramiro Perez {RPEREZ@UTPVM1.BITNET}, (Panama) +
-
- //+ and Fausto A. A. Barbuto {BJ06@C53000.PETROBRAS.ANRJ.BR}, (Brazil). +
-
- //+ C++ 3.1 programme's creator: Fausto A. A. Barbuto, April 14, 1994. +
-
- //+ After a TURBO BASIC program by Ramiro Perez. +
-
- //+ +
-
- //+ You can rotate it with the numeric keyboard (NumLock = ON) +
-
- //+ Keys: (NumLock = ON) +
-
- //+ 4 and 6 rotate the atractor around the Y axis (azimuth). +
-
- //+ 2 and 8 change the elevation of the looking point +
-
- //+ (Rotation around the screen's X axis) +
-
- //+ 5 returns the azimuth and elevation to 0.0 +
-
- //+ - and + decrease or increase the step angle of the rotations. +
-
- //+ / and * decrease or increase the number of iterations. +
-
- //+ A or a turns on/of the reference axis +
-
- //+ SPACE turns on/off the repetition of the last command +
-
- //+ (with this you can have continuous rotation) +
-
- //+ < and > decrease or increase the integration interval dt +
-
- //+ Q or q Quit +
-
- //+ +
-
- //+ VGA 16 colours, 640x480 points version. +
-
- //+---------------------------------------------------------------------+
-
- //
-
-
-
- #include <graphics.h>
-
- #include <conio.h>
-
- #include <stdio.h>
-
- #include <dos.h>
-
- #include <math.h>
-
-
-
- #define centx 320
-
- #define centy 240
-
- #define axesx 35
-
- #define axesy 440
-
- #define longaxe 30
-
- #define pi 3.141592654
-
- #define twopi 6.283185307
-
- #define halfpi 1.570796327
-
-
-
- int get_cmd (int *);
-
- double bound (double);
-
- void update_param (int, double *, int *, int *, int *);
-
- void axe_x ();
-
- void axe_y ();
-
- void axe_z ();
-
- void draw_axes ();
-
- void print_info (int, int, double);
-
-
-
- static double azim, elev, fxx, fxz, fyx, fyy, fyz;
-
-
-
- void main()
-
- {
-
- int c, b, a, l, n, kb, cl, step, iter, axis = 1, rep = 0;
-
- double dt, xa[2], ya[2], za[2], x, y, z, x1, y1, z1, xd, yd;
-
- int graphdriver = VGA, graphmode = VGAHI;
-
-
-
- initgraph (&graphdriver,&graphmode,"");
-
- settextstyle (SMALL_FONT, HORIZ_DIR, 4);
-
-
-
- azim = 0.0;
-
- elev = 0.0;
-
- step = 9;
-
- iter = 1000;
-
- dt = 0.03;
-
- a = 5;
-
- b = 15;
-
- c = 1;
-
-
-
- do {
-
- cleardevice ();
-
- //
-
- // Start-up values for xa, ya and za.
-
- //
-
- xa[0] = 3.051522;
-
- ya[0] = 1.592542;
-
- za[0] = 15.62388;
-
- xa[1] = 3.051522;
-
- ya[1] = 1.582542;
-
- za[1] = 15.62388;
-
-
-
- fxx = cos(azim);
-
- fxz = -sin(azim);
-
- fyx = sin(elev)*fxz;
-
- fyy = cos(elev);
-
- fyz = -sin(elev)*fxx;
-
- for (n=1; n<=iter; n++) {
-
- for (l=0;l<=1;l++) {
-
- x = xa[l];
-
- y = ya[l];
-
- z = za[l];
-
- x1 = x - a*x*dt + a*y*dt;
-
- y1 = y + b*x*dt - y*dt - z*x*dt;
-
- z1 = z - c*z*dt + x*y*dt;
-
- xa[l] = x1;
-
- ya[l] = y1;
-
- za[l] = z1;
-
- z1 -= 16.0;
-
- xd = 19.3*(x1*fxx + z1*fxz) + centx;
-
- yd = -11.0*(x1*fyx + y1*fyy + z1*fyz) + centy;
-
- putpixel((int)xd, (int)yd, (l==0) ? LIGHTBLUE :
-
- LIGHTGREEN);
-
- }
-
- }
-
- if (axis) draw_axes ();
-
- if (!rep) print_info (step, iter, dt);
-
- kb = get_cmd (&rep);
-
- update_param (kb, &dt, &step, &iter, &axis);
-
- } while (kb!='q' && kb!='Q');
-
- closegraph ();
-
- }
-
-
-
-
-
- int get_cmd (int *rep)
-
- {
-
- static int lkb;
-
- int kb;
-
-
-
- if (*rep) {
-
- if (kbhit ()) kb = getch ();
-
- if (kb==' ') *rep = 0;
-
- else kb = lkb;
-
- }
-
- else {
-
- for ( ; !kbhit (); );
-
- kb = getch ();
-
- if (kb==' ') {
-
- *rep = 1;
-
- kb = lkb;
-
- }
-
- else lkb = kb;
-
- }
-
- return (kb);
-
- }
-
-
-
-
-
- void axe_x ()
-
- {
-
- int br, xd, yd;
-
- br = azim>=0.0 && azim<=pi || elev==halfpi || elev==3*halfpi;
-
- if (elev>halfpi && elev<3*halfpi) br = !br;
-
- setcolor (br ? CYAN : BLUE);
-
- xd = longaxe*fxx + axesx;
-
- yd = -longaxe*fyx + axesy;
-
- line (axesx, axesy, xd, yd);
-
- outtextxy (xd, yd, "X");
-
- return;
-
- }
-
-
-
- void axe_y ()
-
- {
-
- int xd, yd;
-
- setcolor ((elev<=pi) ? YELLOW : GREEN);
-
- xd = axesx;
-
- yd = -longaxe*fyy + axesy;
-
- line (axesx, axesy, xd, yd);
-
- outtextxy (xd + 2, yd, "Y");
-
- return;
-
- }
-
-
-
- void axe_z ()
-
- {
-
- int br, xd, yd;
-
- br = azim>=(3*halfpi) || azim<=halfpi || elev==halfpi || elev==3*halfpi;
-
- if (elev>halfpi && elev<3*halfpi) br = !br;
-
- setcolor (br ? LIGHTRED : RED);
-
- xd = longaxe*fxz + axesx;
-
- yd = -longaxe*fyz + axesy;
-
- line (axesx, axesy, xd, yd);
-
- outtextxy (xd, yd, "Z");
-
- return;
-
- }
-
-
-
- void draw_axes ()
-
- {
-
- int dr = 1, ord;
-
-
-
- //These if's are for line-hiding in the reference axis.
-
- //If you want more speed you can delete them.
-
-
-
- if (elev>=pi && elev<=twopi) {
-
- axe_y ();
-
- dr = 0;
-
- }
-
- ord = azim>=3*halfpi && azim<=twopi;
-
- if (elev>halfpi) ord = !ord;
-
- if (ord) {
-
- axe_x ();
-
- axe_z ();
-
- }
-
- else {
-
- axe_z ();
-
- axe_x ();
-
- }
-
- if (dr) axe_y ();
-
- return;
-
- }
-
-
-
- void print_info (int step, int iter, double dt)
-
- {
-
- char mess[100];
-
- setcolor (WHITE);
-
- outtextxy (216, 5, "L O R E N Z A T R A C T O R");
-
- sprintf (mess, "Elev= %4.0f deg Azim= %4.0f deg Step= %i deg
-
- Iterations= %i dt= %4.3f", elev*180/pi, azim*180/pi,
-
- step, iter, dt);
-
- outtextxy (80, 460, mess);
-
- return;
-
- }
-
-
-
-
-
- double bound (double angle)
-
- {
-
- double angb;
-
-
-
- if (angle>=twopi) angb = angle - twopi;
-
- else if (angle<0.0) angb = angle + twopi;
-
- else angb = angle;
-
- return (angb);
-
- }
-
-
-
-
-
- void update_param (int kb, double *dt, int *step, int *iter, int *axis)
-
- {
-
- double delta;
-
-
-
- delta = (*step)*pi/180.0;
-
-
-
- switch (kb) {
-
- case('4'):
-
- azim += delta;
-
- break;
-
- case('6'):
-
- azim -= delta;
-
- break;
-
- case('2'):
-
- elev += delta;
-
- break;
-
- case('8'):
-
- elev -= delta;
-
- break;
-
- case('5'):
-
- azim = 0.0;
-
- elev = 0.0;
-
- break;
-
- case('*'):
-
- (*iter) += 500;
-
- break;
-
- case('/'):
-
- if (*iter>500) (*iter) -= 500;
-
- break;
-
- case('+'):
-
- if (*step<90.0) (*step)++;
-
- break;
-
- case('-'):
-
- if (*step>0.0) (*step)--;
-
- break;
-
- case('>'):
-
- if (*dt<0.05) (*dt) += 0.005;
-
- break;
-
- case('<'):
-
- if (*dt>0.0) (*dt) -= 0.005;
-
- break;
-
- case('a'):
-
- case('A'):
-
- *axis = !(*axis);
-
- break;
-
- default:
-
- break;
-
- }
-
- azim = bound (azim);
-
- elev = bound (elev);
-
- return;
-
- }
-
-