Metropoli BBS
VIEWER: lorenz.c MODE: TEXT (CP437)
/*          ╔═══════════════════════════════════════════════════════════════╗
            ║                                                               ║
            ║                                                               ║
	    ║           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();
}
[ RETURN TO DIRECTORY ]