/* ╔═══════════════════════════════════════════════════════════════╗
║ ║
║ ║
║ lorenz = PROGRAM TO PLOT LORENZ ATTRACTOR ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
*/
#include <dos.h>
#include <stdio.h>
#include <math.h>
#include "tools.h"
float radians_to_degrees(float degrees);;
const int maxcol = 639;
const int maxrow = 349;
int LINEWIDTH = 3, OPERATOR = 0;
int color = 15;
unsigned long int PATTERN = 0xFFFFFFFF;
unsigned char PALETTE[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
float rad_per_degree=0.0174533,x_angle=45,y_angle=0,z_angle=90;
union LIMIT XMax,YMax,XMin,YMin,Pval,Qval;
char file_name[13] = {"lorenz00.pcx"};
main()
{
double x,y,z,d0_x,d0_y,d0_z,d1_x,d1_y,d1_z,d2_x,d2_y,d2_z,
d3_x,d3_y,d3_z,xt,yt,zt,dt,dt2,third=0.333333333,
sx,sy,sz,cx,cy,cz,temp_x,temp_y,old_y;
int i, j, row, col, old_row, old_col;
x_angle = radians_to_degrees(x_angle);
sx = sin(x_angle);
cx = cos(x_angle);
y_angle = radians_to_degrees(y_angle);
sy = sin(y_angle);
cy = cos(y_angle);
z_angle = radians_to_degrees(z_angle);
sz = sin(z_angle);
cz = cos(z_angle);
for (j=0; j<3; j++)
{
color = 4;
LINEWIDTH = 3;
x = 0;
y = 1;
z = 0;
setMode(16);
if (j == 0)
{
old_col = y*9;
old_row = 9*z - 240;
drawLine(-320,-238,319,-238,15);
drawLine(0,-238,0,239,15);
gotoxy(79,24);
printf("Y");
gotoxy(42,1);
printf("Z");
}
if (j == 1)
{
old_col = y*10;
old_row = 10*x;
drawLine(-320,0,319,0,15);
drawLine(0,-238,0,238,15);
gotoxy(79,12);
printf("Y");
gotoxy(42,1);
printf("X");
}
if (j == 2)
{
old_col = y*9;
old_row = 9*z - 240;
drawLine(-320,-238,319,-238,15);
drawLine(0,-238,0,239,15);
drawLine(0,-238,319,82,15);
gotoxy(79,24);
printf("Y");
gotoxy(42,1);
printf("Z");
gotoxy(79,8);
printf("X");
}
LINEWIDTH = 1;
dt = 0.01;
dt2 = dt/2;
for (i=0; i<8000; i++)
{
d0_x = 10*(y-x)*dt2;
d0_y = (-x*z + 28*x - y)*dt2;
d0_z = (x*y - 8*z/3)*dt2;
xt = x + d0_x;
yt = y + d0_y;
zt = z + d0_z;
d1_x = (10*(yt-xt))*dt2;
d1_y = (-xt*zt + 28*xt - yt)*dt2;
d1_z =(xt*yt - 8*zt/3)*dt2;
xt = x + d1_x;
yt = y + d1_y;
zt = z + d1_z;
d2_x = (10*(yt-xt))*dt;
d2_y = (-xt*zt + 28*xt - yt)*dt;
d2_z =(xt*yt - 8*zt/3)*dt;
xt = x + d2_x;
yt = y + d2_y;
zt = z + d2_z;
d3_x = (10*(yt - xt))*dt2;
d3_y = (-xt*zt + 28*xt - yt)*dt2;
d3_z = (xt*yt - 8*zt/3)*dt2;
old_y = y;
x += (d0_x + d1_x + d1_x + d2_x + d3_x) * third;
y += (d0_y + d1_y + d1_y + d2_y + d3_y) * third;
z += (d0_z + d1_z + d1_z + d2_z + d3_z) * third;
if (j == 0)
{
col = y*9;
row = 9*z - 240;
if (((col<0) && (old_col >= 0)) || ((col > 0)
&& (old_col <= 0)))
color++;
}
if (j == 1)
{
col = y*10;
row = 10*x;
if (((col<0) && (old_col >= 0)) || ((col > 0)
&& (old_col <= 0)))
color++;
}
if (j == 2)
{
if (((y<0) && (old_y >=0)) || ((y > 0)
&& (old_y <=0)))
color++;
temp_x = x*cx + y*cy + z*cz;
temp_y = x*sx + y*sy + z*sz;
col = temp_x*8;
row = temp_y*7-240;
}
drawLine(old_col,old_row,col,row,color);
old_row = row;
old_col = col;
}
save_screen(0,0,639,349,file_name);
getch();
}
}
float radians_to_degrees(float degrees)
{
float angle;
while (degrees >= 360)
degrees -= 360;
while (degrees < 0)
degrees += 360;
angle = rad_per_degree*degrees;
return angle;
}
/*┌───────────────────────────────────────────────────────┐
│ │
│ save_screen() = save screen to disk file │
│ │
└───────────────────────────────────────────────────────┘*/
void save_screen(int x1, int y1, int x2, int y2, char file_name[])
{
extern union LIMIT XMax,XMin,YMax,YMin,Pval,Qval;
extern unsigned char PALETTE[16];
int i,j,k,add1,add2,number,num_out, line_length, end,
start_line, end_line;
unsigned char ch,ch1,old_ch,red,green,blue;
FILE *fsave;
sound (256);
while (file_name[6] < 0x3A)
{
if (fsave = fopen (file_name,"rb") != NULL)
{
file_name[7]++;
if (file_name[7] >= 0x3A)
{
file_name[7] = 0x30;
file_name[6]++;
}
}
else
{
fsave = fopen(file_name,"wb");
fputc(0x0A,fsave);
fputc(0x05,fsave);
fputc(0x01,fsave);
fputc(0x04,fsave);
putw(x1,fsave);
putw(y1,fsave);
putw(x2,fsave);
putw(y2,fsave);
putw(640,fsave);
putw(350,fsave);
ch = 0x00;
for (i=0; i<16; i++)
{
red = (((PALETTE[i] & 0x20) >> 5) |
((PALETTE[i] & 0x04) >> 1)) * 85;
green = (((PALETTE[i] & 0x10) >> 4) |
(PALETTE[i] & 0x02)) * 85;
blue = (((PALETTE[i] & 0x08) >> 3) |
((PALETTE[i] & 0x01) << 1)) * 85;
fputc(red,fsave);
fputc(green,fsave);
fputc(blue,fsave);
}
fputc(0x00,fsave);
fputc(0x04,fsave);
start_line = x1/8;
end_line = x2/8 + 1;
line_length = end_line - start_line;
end = start_line + line_length * 4 + 1;
putw(line_length,fsave);
for (i=0; i<4; i++)
fputc(XMax.c[i],fsave);
for (i=0; i<4; i++)
fputc(XMin.c[i],fsave);
for (i=0; i<4; i++)
fputc(YMax.c[i],fsave);
for (i=0; i<4; i++)
fputc(YMin.c[i],fsave);
for (i=0; i<4; i++)
fputc(Pval.c[i],fsave);
for (i=0; i<4; i++)
fputc(Qval.c[i],fsave);
for (i=92; i<128; i++)
fputc(' ',fsave);
for (k=y1; k<y2; k++)
{
add1 = 80*k;
number = 1;
j = 0;
add2 = (start_line);
old_ch = read_screen(add1 + add2++,0);
for (i=add2; i<end; i++)
{
if (i == end - 1)
ch = old_ch - 1;
else
{
if ((add2) == end_line)
{
j++;
add2 = (start_line);
}
ch = read_screen(add1 + add2,
j);
}
if ((ch == old_ch) && number < 63)
number++;
else
{
num_out = ((unsigned char)
number | 0xC0);
if ((number != 1) ||
((old_ch & 0xC0) ==
0xC0))
fputc(num_out,fsave);
fputc(old_ch,fsave);
old_ch = ch;
number = 1;
}
add2++;
}
}
fclose(fsave);
break;
}
}
nosound();
}