home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / chaos.zip / CHAOS.C next >
Text File  |  1990-06-04  |  13KB  |  489 lines

  1. /******
  2. *
  3. *   module:      chaos.c
  4. *   descripton:  program that draws:
  5. *
  6. *                o  the Lorenz Attractor, a chaotic function  as seen
  7. *                   on the television show NOVA "THE STRANGE NEW
  8. *                   SCIENCE OF CHAOS"
  9. *
  10. *                o  the Pickover Attractor
  11. *
  12. *                this program is adapated from a similar program by
  13. *                Marty Belles 9-2-89
  14. *
  15. *  programmer:   Bryan A. Woodruff (Woodruff Software Systems) 6/2/90
  16. *                Copyright (c) 1990
  17. *
  18. ******/
  19.  
  20. #include <windows.h>
  21. #include <math.h>
  22. #include "chaos.h"
  23.  
  24. long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
  25. void DrawLorenz(HWND);
  26. void DrawPickover(HWND);
  27.  
  28. int     iPrevX, iPrevY, iPrevDef;
  29. short   xClient, yClient;
  30. short   nRed, nGreen, nBlue;
  31.  
  32. /***
  33. * Lorenz Attractor Globals
  34. ***/
  35.  
  36. double  dLorX, dLorY, dLorZ, dThetaX, dThetaY, dThetaZ, dCosX, dCosY, dCosZ,
  37.         dSinX, dSinY, dSinZ;
  38.  
  39. /***
  40. * Pickover Attractor Globals
  41. ***/
  42.  
  43. double  dMinX, dMinY, dMaxX, dMaxY, dPickX, dPickY, dPickZ,
  44.         dPickA, dPickB, dPickC, dPickD, dPickE;
  45.  
  46. /***
  47. * Defaults
  48. ***/
  49.  
  50. WORD    wColor = IDD_RANDOM,
  51.         wPlane = IDD_XYPLANE,
  52.         wFunc  = IDD_PICKOVER;
  53.  
  54.  
  55. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  56. HANDLE  hInstance, hPrevInstance;
  57. LPSTR   lpszCmdLine;
  58. int     nCmdShow;
  59. {
  60.    HWND         hWnd;
  61.    MSG          msg;
  62.    WNDCLASS     wndclass;
  63.    static char  szAppName[] = "chaos";
  64.    static char  szVersion[] = "Chaos Generator v1.2";
  65.  
  66.    if (hPrevInstance)
  67.       return (FALSE);
  68.  
  69.    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  70.    wndclass.lpfnWndProc   = WndProc;
  71.    wndclass.cbClsExtra    = 0;
  72.    wndclass.cbWndExtra    = 0;
  73.    wndclass.hInstance     = hInstance;
  74.    wndclass.hIcon         = NULL;
  75.    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  76.    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  77.    wndclass.lpszMenuName  = szAppName;
  78.    wndclass.lpszClassName = szAppName;
  79.  
  80.    if (!RegisterClass(&wndclass))
  81.       return FALSE;
  82.  
  83.    hWnd = CreateWindow(szAppName, szVersion, WS_OVERLAPPEDWINDOW,
  84.                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
  85.                         hInstance, NULL);
  86.  
  87.    ShowWindow(hWnd, nCmdShow);
  88.    UpdateWindow(hWnd);
  89.  
  90.    while (TRUE) {
  91.       if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  92.          if (msg.message == WM_QUIT)
  93.             break;
  94.          TranslateMessage(&msg);
  95.          DispatchMessage(&msg);
  96.       }
  97.       else {
  98.          switch (wFunc) {
  99.             case IDD_LORENZ:
  100.                DrawLorenz(hWnd);
  101.                break;
  102.  
  103.             case IDD_PICKOVER:
  104.                DrawPickover(hWnd);
  105.                break;
  106.          }
  107.       }
  108.    }
  109.    return msg.wParam;
  110.  
  111. } /* end of WinMain */
  112.  
  113. /******
  114. *
  115. *     function: DrawLorenz
  116. *  description: calculates and draws Lorenz Attractor
  117. *
  118. *               *** adapted from FRACTAL PROGRAMMING IN C, pp. 87 - 90 ***
  119. *
  120. ******/
  121.  
  122. #define ONETHIRD (1.0 / 3.0)
  123.  
  124. void DrawLorenz(hWnd)
  125. HWND hWnd;
  126. {
  127.    HPEN    hPen;
  128.    HDC     hDC;
  129.  
  130.    int     iX, iY;
  131.    double  dt = 0.01, dt2 = dt / 2.0;
  132.    double  d0_x, d0_y, d0_z, d1_x, d1_y, d1_z, d2_x, d2_y, d2_z,
  133.            d3_x, d3_y, d3_z, xt, yt, zt;
  134.  
  135.    int     rand();
  136.  
  137.  
  138.    d0_x = 10.0 * (dLorY - dLorX) * dt2;
  139.    d0_y = (-dLorX * dLorZ + 28.0 * dLorX - dLorY) * dt2;
  140.    d0_z = (dLorX * dLorY - 8.0 * dLorZ / 3.0) * dt2;
  141.    xt = dLorX + d0_x;
  142.    yt = dLorY + d0_y;
  143.    zt = dLorZ + d0_z;
  144.    d1_x = 10.0 * (yt - xt) * dt2;
  145.    d1_y = (-xt * zt + 28.0 * xt - yt) * dt2;
  146.    d1_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
  147.    xt = dLorX + d1_x;
  148.    yt = dLorY + d1_y;
  149.    zt = dLorZ + d1_z;
  150.    d2_x = 10.0 * (yt - xt) * dt;
  151.    d2_y = (-xt * zt + 28.0 * xt - yt) * dt;
  152.    d2_z = (xt * yt - 8.0 * zt / 3.0) * dt;
  153.    xt = dLorX + d2_x;
  154.    yt = dLorY + d2_y;
  155.    zt = dLorZ + d2_z;
  156.    d3_x = 10.0 * (yt - xt) * dt2;
  157.    d3_y = (-xt * zt + 28.0 * xt - yt) * dt2;
  158.    d3_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
  159.    xt = dLorX + d3_x;
  160.    yt = dLorY + d3_y;
  161.    zt = dLorZ + d3_z;
  162.  
  163.    dLorX += (d0_x + d1_x + d1_x + d2_x + d3_x) * ONETHIRD;
  164.    dLorY += (d0_y + d1_y + d1_y + d2_y + d3_y) * ONETHIRD;
  165.    dLorZ += (d0_z + d1_z + d1_z + d2_z + d3_z) * ONETHIRD;
  166.  
  167.    switch (wColor) {
  168.       case IDD_BLACKONWHITE :
  169.          nRed   = 0;
  170.          nGreen = 0;
  171.          nBlue  = 0;
  172.          break;
  173.       case IDD_WHITEONBLACK :
  174.          nRed   = 255;
  175.          nGreen = 255;
  176.          nBlue  = 255;
  177.          break;
  178.       case IDD_RANDOM:
  179.          if (((iY < 0) && (iPrevY >= 0)) ||
  180.              ((iY > 0) && (iPrevY <= 0))) {
  181.             nRed   = (short) (rand () % 255);
  182.             nGreen = (short) (rand () % 255);
  183.             nBlue  = (short) (rand () % 255);
  184.          }
  185.    }
  186.  
  187.    hDC = GetDC(hWnd);
  188.    hPen = CreatePen(PS_SOLID, 1, RGB(nRed, nGreen, nBlue));
  189.    SelectObject(hDC, hPen);
  190.    SetMapMode(hDC, MM_ISOTROPIC);
  191.    SetWindowExt(hDC, 500, 500);
  192.    SetViewportExt(hDC, xClient / 2, -yClient / 2);
  193.    SetViewportOrg(hDC, xClient / 2, yClient / 2);
  194.    MoveTo(hDC, iPrevX, iPrevY);
  195.    switch (wPlane) {
  196.       case IDD_XYPLANE:
  197.          iX = (int)(10.0 * dLorX - 250.0);
  198.          iY = (int)(10.0 * dLorY);
  199.          break;
  200.       case IDD_YZPLANE:
  201.          iX = (int)(10.0 * dLorZ - 250.0);
  202.          iY = (int)(10.0 * dLorY);
  203.          break;
  204.       case IDD_XYZPLANE:
  205.          iX = (int)((dLorX * dSinX + dLorY * dSinY + dLorZ * dSinZ) * 10.0
  206.                      - 250.0);
  207.          iY = (int)((dLorX * dCosX + dLorY * dCosY + dLorZ * dCosZ) * 10.0);
  208.    }
  209.    if (!iPrevDef)
  210.       MoveTo(hDC, iX, iY);
  211.    LineTo(hDC, iX, iY);
  212.    iPrevX = iX;
  213.    iPrevY = iY;
  214.    iPrevDef = TRUE;
  215.    ReleaseDC(hWnd, hDC);
  216.    DeleteObject(hPen);
  217.  
  218. } /* end of DrawLorenz */
  219.  
  220. /******
  221. *
  222. *     function: DrawPickover
  223. *  description: calculates and draws Pickover Attractor
  224. *
  225. *               *** adapted from FRACTAL PROGRAMMING IN C, pp. 91 - 93 ***
  226. *
  227. ******/
  228.  
  229. void DrawPickover(hWnd)
  230. HWND hWnd;
  231. {
  232.    int     iX, iY;
  233.    double  dTempX, dTempY, dDeltaX, dDeltaY;
  234.    HDC     hDC;
  235.  
  236.    int     rand();
  237.  
  238.    dDeltaX = 500.0 / (dMaxX - dMinX);
  239.    dDeltaY = 500.0 / (dMaxY - dMinY);
  240.    dTempX = sin(dPickA * dPickY) - dPickZ * cos(dPickB * dPickX);
  241.    dTempY = dPickZ * sin(dPickC * dPickX) - cos(dPickD * dPickY);
  242.    dPickZ = dPickE * sin(dPickC * dPickX);
  243.    dPickX = dTempX;
  244.    dPickY = dTempY;
  245.    switch (wPlane) {
  246.       case IDD_XYPLANE:
  247.          iX = (int)((dPickX - dMinX) * dDeltaX);
  248.          iY = (int)((dPickY - dMinY) * dDeltaY);
  249.          break;
  250.  
  251.       case IDD_YZPLANE:
  252.          iX = (int)((dPickY - dMinX) * dDeltaX);
  253.          iY = (int)((dPickZ - dMinY) * dDeltaY);
  254.          break;
  255.    }
  256.    switch (wColor) {
  257.       case IDD_BLACKONWHITE :
  258.          nRed   = 0;
  259.          nGreen = 0;
  260.          nBlue  = 0;
  261.          break;
  262.       case IDD_WHITEONBLACK :
  263.          nRed   = 255;
  264.          nGreen = 255;
  265.          nBlue  = 255;
  266.          break;
  267.       case IDD_RANDOM:
  268.          nRed   = (short) (rand () % 255);
  269.          nGreen = (short) (rand () % 255);
  270.          nBlue  = (short) (rand () % 255);
  271.          break;
  272.    }
  273.    if ((iX >= 0) && (iX < 500) && (iY >= 0) && (iY < 500)) {
  274.       hDC = GetDC(hWnd);
  275.       SetMapMode(hDC, MM_ISOTROPIC);
  276.       SetWindowExt(hDC, 500, 500);
  277.       if (yClient > xClient)
  278.          SetViewportOrg(hDC, 0, yClient - ((yClient - xClient) / 2));
  279.       else if (xClient > yClient)
  280.          SetViewportOrg(hDC, (xClient - yClient) / 2, yClient);
  281.       else
  282.          SetViewportOrg(hDC, 0, yClient);
  283.       SetViewportExt(hDC, xClient, -yClient);
  284.       SetPixel(hDC, iX, iY, RGB(nRed, nGreen, nBlue));
  285.       ReleaseDC(hWnd, hDC);
  286.    }
  287.  
  288. } /* end of DrawPickover */
  289.  
  290. void InitializeFunction()
  291. {
  292.    switch (wFunc) {
  293.       case IDD_PICKOVER:
  294.          /* Pickover initialization */
  295.          dMaxX = 2.8;
  296.          dMinX = -2.8;
  297.          dMaxY = 2.0;
  298.          dMinY = -2.0;
  299.          dPickX = 0.0;
  300.          dPickY = 0.0;
  301.          dPickZ = 0.0;
  302.          dPickA = 2.24;
  303.          dPickB = .43;
  304.          dPickC = -.65;
  305.          dPickD = -2.43;
  306.          dPickE = 1.0;
  307.          break;
  308.  
  309.        case IDD_LORENZ:
  310.          dThetaX = 0.7853981633974;
  311.          dThetaY = 0.0;
  312.          dThetaZ = 1.570796326795;
  313.          dCosX = cos(dThetaX);
  314.          dCosY = cos(dThetaY);
  315.          dCosZ = cos(dThetaZ);
  316.          dSinX = sin(dThetaX);
  317.          dSinY = sin(dThetaY);
  318.          dSinZ = sin(dThetaZ);
  319.          dLorX = 0.0;
  320.          dLorY = 1.0;
  321.          dLorZ = 0.0;
  322.          iPrevDef = FALSE;
  323.    }
  324.  
  325. } /* end of InitializeFunction */
  326.  
  327. BOOL FAR PASCAL AboutDlgProc(hDlg, iMessage, wParam, lParam)
  328. HWND      hDlg;
  329. unsigned  iMessage;
  330. WORD      wParam;
  331. LONG      lParam;
  332. {
  333.    switch (iMessage) {
  334.       case WM_INITDIALOG:
  335.          break;
  336.  
  337.       case WM_COMMAND:
  338.          switch (wParam) {
  339.             case IDOK:
  340.                EndDialog (hDlg, 0);
  341.                break;
  342.  
  343.             default:
  344.                return FALSE;
  345.          }
  346.          break;
  347.  
  348.       default:
  349.          return FALSE;
  350.  
  351.    }
  352.    return TRUE;
  353.  
  354. } /* end of AboutDlgProc */
  355.  
  356. BOOL FAR PASCAL SettingsProc(hDlg, iMessage, wParam, lParam)
  357. HWND      hDlg;
  358. unsigned  iMessage;
  359. WORD      wParam;
  360. LONG      lParam;
  361. {
  362.    int    i;
  363.    HMENU  hMenu;
  364.  
  365.    static WORD   wOldColor, wOldPlane, wOldFunc;
  366.  
  367.    switch (iMessage) {
  368.       case WM_INITDIALOG:
  369.          wOldColor = wColor;
  370.          wOldPlane = wPlane;
  371.          wOldFunc = wFunc;
  372.          CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wColor);
  373.          CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
  374.          CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wFunc);
  375.          EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
  376.          break;
  377.  
  378.       case WM_COMMAND:
  379.          switch (wParam) {
  380.             case IDD_WHITEONBLACK:
  381.             case IDD_BLACKONWHITE:
  382.             case IDD_RANDOM:
  383.                wColor  = wParam;
  384.                CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wParam);
  385.                break;
  386.  
  387.             case IDD_XYPLANE:
  388.             case IDD_XYZPLANE:
  389.             case IDD_YZPLANE:
  390.                wPlane = wParam;
  391.                CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wParam);
  392.                iPrevDef = FALSE;
  393.                break;
  394.  
  395.             case IDD_LORENZ:
  396.             case IDD_PICKOVER:
  397.                wFunc = wParam;
  398.                CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wParam);
  399.                EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
  400.                if ((wFunc == IDD_PICKOVER) && (wPlane == IDD_XYZPLANE)) {
  401.                   wPlane = IDD_XYPLANE;
  402.                   CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
  403.                }
  404.                iPrevDef = FALSE;
  405.                break;
  406.  
  407.             case IDOK:
  408.                EndDialog(hDlg, TRUE);
  409.                break;
  410.  
  411.             case IDCANCEL:
  412.                wColor = wOldColor;
  413.                wPlane = wOldPlane;
  414.                wFunc = wOldFunc;
  415.                EndDialog(hDlg, TRUE);
  416.                break;
  417.  
  418.             default:
  419.                return FALSE;
  420.          }
  421.          break;
  422.  
  423.       default:
  424.          return FALSE;
  425.  
  426.    }
  427.    return TRUE;
  428.  
  429. } /* end of SettingsProc */
  430.  
  431. long FAR PASCAL WndProc(hWnd, iMessage, wParam, lParam)
  432. HWND      hWnd;
  433. unsigned  iMessage;
  434. WORD      wParam;
  435. LONG      lParam;
  436. {
  437.    int    iRow;
  438.    static FARPROC  lpfnAboutDlgProc, lpfnSettingsProc;
  439.    static HWND     hInstance;
  440.    HDC    hDC;
  441.  
  442.    void   InitializeFunction();
  443.  
  444.    switch (iMessage) {
  445.       case WM_CREATE:
  446.          hInstance = ((LPCREATESTRUCT) lParam) -> hInstance;
  447.          lpfnAboutDlgProc = MakeProcInstance(AboutDlgProc, hInstance);
  448.          lpfnSettingsProc = MakeProcInstance(SettingsProc, hInstance);
  449.          break;
  450.  
  451.       case WM_SIZE:
  452.          xClient = LOWORD(lParam);
  453.          yClient = HIWORD(lParam);
  454.          InitializeFunction();
  455.          SetClassWord (hWnd, GCW_HBRBACKGROUND,
  456.                        GetStockObject ((wColor == IDD_BLACKONWHITE) ?
  457.                                         WHITE_BRUSH : BLACK_BRUSH));
  458.          InvalidateRect (hWnd, NULL, TRUE);
  459.          break;
  460.  
  461.       case WM_COMMAND:
  462.          switch (wParam) {
  463.             case IDM_ABOUT:
  464.                DialogBox(hInstance, "ChaosAbout", hWnd, lpfnAboutDlgProc);
  465.                break;
  466.  
  467.             case IDM_SETTINGS:
  468.                DialogBox(hInstance, "SettingsDlg", hWnd, lpfnSettingsProc);
  469.                SetClassWord (hWnd, GCW_HBRBACKGROUND,
  470.                              GetStockObject ((wColor == IDD_BLACKONWHITE) ?
  471.                                               WHITE_BRUSH : BLACK_BRUSH));
  472.                InitializeFunction();
  473.                InvalidateRect(hWnd, NULL, TRUE);
  474.                break;
  475.          }
  476.          break;
  477.  
  478.       case WM_DESTROY:
  479.          PostQuitMessage(0);
  480.          break;
  481.  
  482.       default:
  483.          return DefWindowProc (hWnd, iMessage, wParam, lParam);
  484.    }
  485.  
  486.    return 0L;
  487.  
  488. } /* end of WndProc */
  489.