home *** CD-ROM | disk | FTP | other *** search
/ Desktop Works 1995 - 1996 / desktopworks1995-1996.iso / scrnsave / win_maze / spike.cpp < prev    next >
C/C++ Source or Header  |  1996-01-01  |  11KB  |  354 lines

  1. #include <owl\owlpch.h>
  2. #include <owl\applicat.h>
  3. #include <owl\framewin.h>
  4. #include <owl\dc.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <stdlib.h>
  8. #include "plot3d.h"
  9.  
  10. #ifndef TRUE
  11. #define TRUE -1
  12. #endif
  13. #ifndef FALSE
  14. #define FALSE 0
  15. #endif
  16.  
  17. static int    external_to_plot(double,double);
  18. static double f(double,double);
  19. static int    red(double,double);
  20.  
  21. class SpikeWindow : public TFrameWindow
  22.   {
  23.     public:
  24.       SpikeWindow(TWindow* parent, const char far* title);
  25.       void CleanupWindow();
  26.       BOOL IdleAction(long IdleCount);
  27.         // So that the program remains responsive, the plotting is done here.
  28.       void Paint(TDC &dc,BOOL erase,TRect &dirty);
  29.     protected:
  30.       void EvHScroll(UINT code,UINT pos,HWND wnd);
  31.         // Processes a change in the horizontal scroll bar -- a request for
  32.         // a new angle of rotation.
  33.       void EvSize(UINT sizeType,TSize &size);
  34.         // Processes resizing of the window -- a request for a different size
  35.         // plot.
  36.       void EvVScroll(UINT code,UINT pos,HWND wnd);
  37.         // Processes a change in the vertical scroll bar -- a request for a
  38.         // new angle of tilt.
  39.     private:
  40.       double light_x;
  41.       double light_y;
  42.       double light_z;
  43.         // Vector to the major source of light.
  44.       plot3d *plot3d_ptr;
  45.         // Pointer to an instance of the 3D plotting class.
  46.       TRect  region_to_paint;
  47.       int    rotation;
  48.         // The number of degrees the plot is rotated about a line
  49.         // through its center running parallel to the z-axis.
  50.       char   state;
  51.         // State of the plotting; one of the following:
  52.         //     'B' -- beginning
  53.         //     'S' -- preparing plot
  54.         //     'P' -- plotting
  55.         //     'F' -- failure
  56.         //     'D' -- done
  57.       int    tilt;
  58.         // The number of degrees the plot is tilted towards the viewer.
  59.   
  60.       DECLARE_RESPONSE_TABLE(SpikeWindow);
  61.        // Associates user commands with methods in this program.
  62.   };
  63.  
  64. DEFINE_RESPONSE_TABLE1(SpikeWindow,TFrameWindow)
  65.   EV_WM_HSCROLL,
  66.   EV_WM_VSCROLL,
  67.   EV_WM_SIZE,
  68. END_RESPONSE_TABLE;
  69.  
  70. SpikeWindow::SpikeWindow(
  71.   TWindow        *parent,
  72.   const char far *title) : TFrameWindow(parent,title)
  73.     {
  74.       Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  75.         // Scroll bars are used to specify tilt and rotation.
  76.       AssignMenu("SPIKE_MENU");
  77.       state='B';             // beginning plot
  78.       rotation=0;            // (degrees)
  79.       tilt=30;               // (degrees)
  80.       light_x=(double) 1.0;  // vector to light source
  81.       light_y=(double) -1.0;
  82.       light_z=(double) 1.0;
  83.       plot3d_ptr=new plot3d((TFrameWindow *) this);
  84.     }
  85.  
  86. void SpikeWindow::CleanupWindow()
  87.   {
  88.     delete plot3d_ptr; // destroy 3D plotter
  89.     TFrameWindow::CleanupWindow();
  90.   }
  91.  
  92. BOOL SpikeWindow::IdleAction(long IdleCount)
  93. // So that the program remains responsive, the plotting is done here.
  94.   {
  95.     switch (state)
  96.       // State of the plotting; one of the following:
  97.       //     'B' -- beginning
  98.       //     'S' -- preparing plot
  99.       //     'P' -- plotting
  100.       //     'F' -- failure
  101.       //     'D' -- done
  102.       {
  103.         case 'B': // begin
  104.           GetClientRect(region_to_paint);
  105.             // The whole plot is being done.
  106.           SetScrollRange(SB_VERT,0,90);   
  107.             // The plot may be tilted between 0 and 90 degrees.
  108.           SetScrollRange(SB_HORZ,0,360);
  109.             // The plot may be rotated between 0 and 360 degrees.
  110.           SetScrollPos(SB_VERT,90-tilt);
  111.             // Display the current tilt on the vertical scroll bar.
  112.           SetScrollPos(SB_HORZ,rotation);
  113.             // Display the current rotation on the horizontal scroll bar.
  114.           if (IsIconic())
  115.             state='F';
  116.           else
  117.             state='S';
  118.           break;
  119.         case 'S': // prepare plot
  120.           switch (plot3d_ptr->prepare_plot(
  121.            f,                        // function f(x,y) to be plotted
  122.            -1.0,                     // minimum x
  123.            1.0,                      // maximum x
  124.            -1.0,                     // minimum y
  125.            1.0,                      // maximum y
  126.            external_to_plot,         // don't plot -- always FALSE
  127.            red,                      // highlight -- always FALSE
  128.            120,                      // number of x divisions
  129.            120,                      // number of y divisions
  130.            double(rotation),         // rotation in degrees
  131.            double(tilt),             // tilt in degrees
  132.            light_x,light_y,light_z)) // vector to light source
  133.             {
  134.               case 'S': // success; plot prepared
  135.                 state='P'; // proceed to plot
  136.                 break;
  137.               case 'F': // failure (already announced in pop up)
  138.                 state='F';
  139.                 break;
  140.               default:  // continue
  141.                 break;
  142.             }
  143.           break;
  144.         case 'P': // plotting
  145.           switch (plot3d_ptr->plot(
  146.            region_to_paint,
  147.            FALSE,                     // highlight flagged areas
  148.            FALSE,                     // only plot flagged areas
  149.            1.0))                      // contrast adjustment
  150.             {
  151.               case 'S': // success; plot complete
  152.                 state='D'; // proceed to wait for user input
  153.                 break;
  154.               case 'F': // failure (already announced in pop up)
  155.                 {
  156.                   state='F';
  157.                   TClientDC *dc=new TClientDC(*this);
  158.                   delete dc;
  159.                 }
  160.                 break;
  161.               default:  // continue
  162.                 break;
  163.             }
  164.           break;
  165.         case 'F': // failed; wait for user input
  166.           break;
  167.         default:  // done; wait for user input
  168.           break;
  169.       }
  170.     TFrameWindow::IdleAction(IdleCount);
  171.     return TRUE;
  172.   }
  173.  
  174. void SpikeWindow::Paint(TDC &dc,BOOL erase,TRect &dirty)
  175. // This method is invoked when part of the display has been made "dirty"
  176. // (for example, when another window has been moved from atop the display).
  177.   {
  178.      switch (state)
  179.        {
  180.          case 'B': // beginning
  181.              // Nothing is displayed yet; nothing need be restored.
  182.            break;
  183.          case 'S': // preparing plot
  184.            dc.PatBlt(this->GetClientRect(),WHITENESS);
  185.            dc.TextOut(0,0,"Preparing plot...");
  186.              // The internal state of the 3D plotter is not available here,
  187.              // so display this message.
  188.            break;
  189.          case 'P': // still plotting
  190.            state='P';
  191.            GetClientRect(region_to_paint);
  192.            plot3d_ptr->restart_plot();
  193.              // Proceed to restore the entire display.  Because the painter's
  194.              // algorithm is used, areas outside the "dirty" region may still
  195.              // need plotting.
  196.            break;
  197.          case 'F': // failed
  198.              // Nothing is being displayed; nothing need be restored.
  199.            break;
  200.          default:  // done
  201.            state='P';
  202.            region_to_paint=dirty;
  203.            plot3d_ptr->restart_plot();
  204.              // Redo the "dirty" region.
  205.            break;
  206.        }
  207.   }
  208.  
  209. void SpikeWindow::EvHScroll(UINT code,UINT pos,HWND wnd)
  210. // Processes a change in the horizontal scroll bar -- a request for a new angle
  211. // of rotation.
  212.   {
  213.     TFrameWindow::EvHScroll(code,pos,wnd);
  214.     int change=FALSE;
  215.     switch (code) 
  216.       {
  217.         case SB_LINEUP:
  218.           rotation--;
  219.           change=TRUE;
  220.           break;
  221.         case SB_LINEDOWN:
  222.           rotation++;
  223.           change=TRUE;
  224.           break;
  225.         case SB_PAGEUP:
  226.           rotation-=10;
  227.           change=TRUE;
  228.           break;
  229.         case SB_PAGEDOWN:
  230.           rotation+=10;
  231.           change=TRUE;
  232.           break;
  233.         case SB_THUMBPOSITION:
  234.           rotation=pos;
  235.           change=TRUE;
  236.           break;
  237.         case SB_THUMBTRACK:
  238.           break;
  239.         default:
  240.           break;
  241.       }
  242.     if (chang