home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
windows
/
chaos.zip
/
CHAOS.C
next >
Wrap
Text File
|
1990-06-04
|
13KB
|
489 lines
/******
*
* module: chaos.c
* descripton: program that draws:
*
* o the Lorenz Attractor, a chaotic function as seen
* on the television show NOVA "THE STRANGE NEW
* SCIENCE OF CHAOS"
*
* o the Pickover Attractor
*
* this program is adapated from a similar program by
* Marty Belles 9-2-89
*
* programmer: Bryan A. Woodruff (Woodruff Software Systems) 6/2/90
* Copyright (c) 1990
*
******/
#include <windows.h>
#include <math.h>
#include "chaos.h"
long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
void DrawLorenz(HWND);
void DrawPickover(HWND);
int iPrevX, iPrevY, iPrevDef;
short xClient, yClient;
short nRed, nGreen, nBlue;
/***
* Lorenz Attractor Globals
***/
double dLorX, dLorY, dLorZ, dThetaX, dThetaY, dThetaZ, dCosX, dCosY, dCosZ,
dSinX, dSinY, dSinZ;
/***
* Pickover Attractor Globals
***/
double dMinX, dMinY, dMaxX, dMaxY, dPickX, dPickY, dPickZ,
dPickA, dPickB, dPickC, dPickD, dPickE;
/***
* Defaults
***/
WORD wColor = IDD_RANDOM,
wPlane = IDD_XYPLANE,
wFunc = IDD_PICKOVER;
int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int nCmdShow;
{
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
static char szAppName[] = "chaos";
static char szVersion[] = "Chaos Generator v1.2";
if (hPrevInstance)
return (FALSE);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
return FALSE;
hWnd = CreateWindow(szAppName, szVersion, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (TRUE) {
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
switch (wFunc) {
case IDD_LORENZ:
DrawLorenz(hWnd);
break;
case IDD_PICKOVER:
DrawPickover(hWnd);
break;
}
}
}
return msg.wParam;
} /* end of WinMain */
/******
*
* function: DrawLorenz
* description: calculates and draws Lorenz Attractor
*
* *** adapted from FRACTAL PROGRAMMING IN C, pp. 87 - 90 ***
*
******/
#define ONETHIRD (1.0 / 3.0)
void DrawLorenz(hWnd)
HWND hWnd;
{
HPEN hPen;
HDC hDC;
int iX, iY;
double dt = 0.01, dt2 = dt / 2.0;
double 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;
int rand();
d0_x = 10.0 * (dLorY - dLorX) * dt2;
d0_y = (-dLorX * dLorZ + 28.0 * dLorX - dLorY) * dt2;
d0_z = (dLorX * dLorY - 8.0 * dLorZ / 3.0) * dt2;
xt = dLorX + d0_x;
yt = dLorY + d0_y;
zt = dLorZ + d0_z;
d1_x = 10.0 * (yt - xt) * dt2;
d1_y = (-xt * zt + 28.0 * xt - yt) * dt2;
d1_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
xt = dLorX + d1_x;
yt = dLorY + d1_y;
zt = dLorZ + d1_z;
d2_x = 10.0 * (yt - xt) * dt;
d2_y = (-xt * zt + 28.0 * xt - yt) * dt;
d2_z = (xt * yt - 8.0 * zt / 3.0) * dt;
xt = dLorX + d2_x;
yt = dLorY + d2_y;
zt = dLorZ + d2_z;
d3_x = 10.0 * (yt - xt) * dt2;
d3_y = (-xt * zt + 28.0 * xt - yt) * dt2;
d3_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
xt = dLorX + d3_x;
yt = dLorY + d3_y;
zt = dLorZ + d3_z;
dLorX += (d0_x + d1_x + d1_x + d2_x + d3_x) * ONETHIRD;
dLorY += (d0_y + d1_y + d1_y + d2_y + d3_y) * ONETHIRD;
dLorZ += (d0_z + d1_z + d1_z + d2_z + d3_z) * ONETHIRD;
switch (wColor) {
case IDD_BLACKONWHITE :
nRed = 0;
nGreen = 0;
nBlue = 0;
break;
case IDD_WHITEONBLACK :
nRed = 255;
nGreen = 255;
nBlue = 255;
break;
case IDD_RANDOM:
if (((iY < 0) && (iPrevY >= 0)) ||
((iY > 0) && (iPrevY <= 0))) {
nRed = (short) (rand () % 255);
nGreen = (short) (rand () % 255);
nBlue = (short) (rand () % 255);
}
}
hDC = GetDC(hWnd);
hPen = CreatePen(PS_SOLID, 1, RGB(nRed, nGreen, nBlue));
SelectObject(hDC, hPen);
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExt(hDC, 500, 500);
SetViewportExt(hDC, xClient / 2, -yClient / 2);
SetViewportOrg(hDC, xClient / 2, yClient / 2);
MoveTo(hDC, iPrevX, iPrevY);
switch (wPlane) {
case IDD_XYPLANE:
iX = (int)(10.0 * dLorX - 250.0);
iY = (int)(10.0 * dLorY);
break;
case IDD_YZPLANE:
iX = (int)(10.0 * dLorZ - 250.0);
iY = (int)(10.0 * dLorY);
break;
case IDD_XYZPLANE:
iX = (int)((dLorX * dSinX + dLorY * dSinY + dLorZ * dSinZ) * 10.0
- 250.0);
iY = (int)((dLorX * dCosX + dLorY * dCosY + dLorZ * dCosZ) * 10.0);
}
if (!iPrevDef)
MoveTo(hDC, iX, iY);
LineTo(hDC, iX, iY);
iPrevX = iX;
iPrevY = iY;
iPrevDef = TRUE;
ReleaseDC(hWnd, hDC);
DeleteObject(hPen);
} /* end of DrawLorenz */
/******
*
* function: DrawPickover
* description: calculates and draws Pickover Attractor
*
* *** adapted from FRACTAL PROGRAMMING IN C, pp. 91 - 93 ***
*
******/
void DrawPickover(hWnd)
HWND hWnd;
{
int iX, iY;
double dTempX, dTempY, dDeltaX, dDeltaY;
HDC hDC;
int rand();
dDeltaX = 500.0 / (dMaxX - dMinX);
dDeltaY = 500.0 / (dMaxY - dMinY);
dTempX = sin(dPickA * dPickY) - dPickZ * cos(dPickB * dPickX);
dTempY = dPickZ * sin(dPickC * dPickX) - cos(dPickD * dPickY);
dPickZ = dPickE * sin(dPickC * dPickX);
dPickX = dTempX;
dPickY = dTempY;
switch (wPlane) {
case IDD_XYPLANE:
iX = (int)((dPickX - dMinX) * dDeltaX);
iY = (int)((dPickY - dMinY) * dDeltaY);
break;
case IDD_YZPLANE:
iX = (int)((dPickY - dMinX) * dDeltaX);
iY = (int)((dPickZ - dMinY) * dDeltaY);
break;
}
switch (wColor) {
case IDD_BLACKONWHITE :
nRed = 0;
nGreen = 0;
nBlue = 0;
break;
case IDD_WHITEONBLACK :
nRed = 255;
nGreen = 255;
nBlue = 255;
break;
case IDD_RANDOM:
nRed = (short) (rand () % 255);
nGreen = (short) (rand () % 255);
nBlue = (short) (rand () % 255);
break;
}
if ((iX >= 0) && (iX < 500) && (iY >= 0) && (iY < 500)) {
hDC = GetDC(hWnd);
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExt(hDC, 500, 500);
if (yClient > xClient)
SetViewportOrg(hDC, 0, yClient - ((yClient - xClient) / 2));
else if (xClient > yClient)
SetViewportOrg(hDC, (xClient - yClient) / 2, yClient);
else
SetViewportOrg(hDC, 0, yClient);
SetViewportExt(hDC, xClient, -yClient);
SetPixel(hDC, iX, iY, RGB(nRed, nGreen, nBlue));
ReleaseDC(hWnd, hDC);
}
} /* end of DrawPickover */
void InitializeFunction()
{
switch (wFunc) {
case IDD_PICKOVER:
/* Pickover initialization */
dMaxX = 2.8;
dMinX = -2.8;
dMaxY = 2.0;
dMinY = -2.0;
dPickX = 0.0;
dPickY = 0.0;
dPickZ = 0.0;
dPickA = 2.24;
dPickB = .43;
dPickC = -.65;
dPickD = -2.43;
dPickE = 1.0;
break;
case IDD_LORENZ:
dThetaX = 0.7853981633974;
dThetaY = 0.0;
dThetaZ = 1.570796326795;
dCosX = cos(dThetaX);
dCosY = cos(dThetaY);
dCosZ = cos(dThetaZ);
dSinX = sin(dThetaX);
dSinY = sin(dThetaY);
dSinZ = sin(dThetaZ);
dLorX = 0.0;
dLorY = 1.0;
dLorZ = 0.0;
iPrevDef = FALSE;
}
} /* end of InitializeFunction */
BOOL FAR PASCAL AboutDlgProc(hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
switch (iMessage) {
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
EndDialog (hDlg, 0);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
} /* end of AboutDlgProc */
BOOL FAR PASCAL SettingsProc(hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
int i;
HMENU hMenu;
static WORD wOldColor, wOldPlane, wOldFunc;
switch (iMessage) {
case WM_INITDIALOG:
wOldColor = wColor;
wOldPlane = wPlane;
wOldFunc = wFunc;
CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wColor);
CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wFunc);
EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
break;
case WM_COMMAND:
switch (wParam) {
case IDD_WHITEONBLACK:
case IDD_BLACKONWHITE:
case IDD_RANDOM:
wColor = wParam;
CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wParam);
break;
case IDD_XYPLANE:
case IDD_XYZPLANE:
case IDD_YZPLANE:
wPlane = wParam;
CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wParam);
iPrevDef = FALSE;
break;
case IDD_LORENZ:
case IDD_PICKOVER:
wFunc = wParam;
CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wParam);
EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
if ((wFunc == IDD_PICKOVER) && (wPlane == IDD_XYZPLANE)) {
wPlane = IDD_XYPLANE;
CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
}
iPrevDef = FALSE;
break;
case IDOK:
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
wColor = wOldColor;
wPlane = wOldPlane;
wFunc = wOldFunc;
EndDialog(hDlg, TRUE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
} /* end of SettingsProc */
long FAR PASCAL WndProc(hWnd, iMessage, wParam, lParam)
HWND hWnd;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
int iRow;
static FARPROC lpfnAboutDlgProc, lpfnSettingsProc;
static HWND hInstance;
HDC hDC;
void InitializeFunction();
switch (iMessage) {
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam) -> hInstance;
lpfnAboutDlgProc = MakeProcInstance(AboutDlgProc, hInstance);
lpfnSettingsProc = MakeProcInstance(SettingsProc, hInstance);
break;
case WM_SIZE:
xClient = LOWORD(lParam);
yClient = HIWORD(lParam);
InitializeFunction();
SetClassWord (hWnd, GCW_HBRBACKGROUND,
GetStockObject ((wColor == IDD_BLACKONWHITE) ?
WHITE_BRUSH : BLACK_BRUSH));
InvalidateRect (hWnd, NULL, TRUE);
break;
case WM_COMMAND:
switch (wParam) {
case IDM_ABOUT:
DialogBox(hInstance, "ChaosAbout", hWnd, lpfnAboutDlgProc);
break;
case IDM_SETTINGS:
DialogBox(hInstance, "SettingsDlg", hWnd, lpfnSettingsProc);
SetClassWord (hWnd, GCW_HBRBACKGROUND,
GetStockObject ((wColor == IDD_BLACKONWHITE) ?
WHITE_BRUSH : BLACK_BRUSH));
InitializeFunction();
InvalidateRect(hWnd, NULL, TRUE);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hWnd, iMessage, wParam, lParam);
}
return 0L;
} /* end of WndProc */