home *** CD-ROM | disk | FTP | other *** search
- #include <owl\owlpch.h>
- #include <owl\applicat.h>
- #include <owl\framewin.h>
- #include <owl\dc.h>
- #include <string.h>
- #include <math.h>
- #include <stdlib.h>
- #include "plot3d.h"
-
- #ifndef TRUE
- #define TRUE -1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- static int external_to_plot(double,double);
- static double f(double,double);
- static int red(double,double);
-
- class SpikeWindow : public TFrameWindow
- {
- public:
- SpikeWindow(TWindow* parent, const char far* title);
- void CleanupWindow();
- BOOL IdleAction(long IdleCount);
- // So that the program remains responsive, the plotting is done here.
- void Paint(TDC &dc,BOOL erase,TRect &dirty);
- protected:
- void EvHScroll(UINT code,UINT pos,HWND wnd);
- // Processes a change in the horizontal scroll bar -- a request for
- // a new angle of rotation.
- void EvSize(UINT sizeType,TSize &size);
- // Processes resizing of the window -- a request for a different size
- // plot.
- void EvVScroll(UINT code,UINT pos,HWND wnd);
- // Processes a change in the vertical scroll bar -- a request for a
- // new angle of tilt.
- private:
- double light_x;
- double light_y;
- double light_z;
- // Vector to the major source of light.
- plot3d *plot3d_ptr;
- // Pointer to an instance of the 3D plotting class.
- TRect region_to_paint;
- int rotation;
- // The number of degrees the plot is rotated about a line
- // through its center running parallel to the z-axis.
- char state;
- // State of the plotting; one of the following:
- // 'B' -- beginning
- // 'S' -- preparing plot
- // 'P' -- plotting
- // 'F' -- failure
- // 'D' -- done
- int tilt;
- // The number of degrees the plot is tilted towards the viewer.
-
- DECLARE_RESPONSE_TABLE(SpikeWindow);
- // Associates user commands with methods in this program.
- };
-
- DEFINE_RESPONSE_TABLE1(SpikeWindow,TFrameWindow)
- EV_WM_HSCROLL,
- EV_WM_VSCROLL,
- EV_WM_SIZE,
- END_RESPONSE_TABLE;
-
- SpikeWindow::SpikeWindow(
- TWindow *parent,
- const char far *title) : TFrameWindow(parent,title)
- {
- Attr.Style |= WS_VSCROLL | WS_HSCROLL;
- // Scroll bars are used to specify tilt and rotation.
- AssignMenu("SPIKE_MENU");
- state='B'; // beginning plot
- rotation=0; // (degrees)
- tilt=30; // (degrees)
- light_x=(double) 1.0; // vector to light source
- light_y=(double) -1.0;
- light_z=(double) 1.0;
- plot3d_ptr=new plot3d((TFrameWindow *) this);
- }
-
- void SpikeWindow::CleanupWindow()
- {
- delete plot3d_ptr; // destroy 3D plotter
- TFrameWindow::CleanupWindow();
- }
-
- BOOL SpikeWindow::IdleAction(long IdleCount)
- // So that the program remains responsive, the plotting is done here.
- {
- switch (state)
- // State of the plotting; one of the following:
- // 'B' -- beginning
- // 'S' -- preparing plot
- // 'P' -- plotting
- // 'F' -- failure
- // 'D' -- done
- {
- case 'B': // begin
- GetClientRect(region_to_paint);
- // The whole plot is being done.
- SetScrollRange(SB_VERT,0,90);
- // The plot may be tilted between 0 and 90 degrees.
- SetScrollRange(SB_HORZ,0,360);
- // The plot may be rotated between 0 and 360 degrees.
- SetScrollPos(SB_VERT,90-tilt);
- // Display the current tilt on the vertical scroll bar.
- SetScrollPos(SB_HORZ,rotation);
- // Display the current rotation on the horizontal scroll bar.
- if (IsIconic())
- state='F';
- else
- state='S';
- break;
- case 'S': // prepare plot
- switch (plot3d_ptr->prepare_plot(
- f, // function f(x,y) to be plotted
- -1.0, // minimum x
- 1.0, // maximum x
- -1.0, // minimum y
- 1.0, // maximum y
- external_to_plot, // don't plot -- always FALSE
- red, // highlight -- always FALSE
- 120, // number of x divisions
- 120, // number of y divisions
- double(rotation), // rotation in degrees
- double(tilt), // tilt in degrees
- light_x,light_y,light_z)) // vector to light source
- {
- case 'S': // success; plot prepared
- state='P'; // proceed to plot
- break;
- case 'F': // failure (already announced in pop up)
- state='F';
- break;
- default: // continue
- break;
- }
- break;
- case 'P': // plotting
- switch (plot3d_ptr->plot(
- region_to_paint,
- FALSE, // highlight flagged areas
- FALSE, // only plot flagged areas
- 1.0)) // contrast adjustment
- {
- case 'S': // success; plot complete
- state='D'; // proceed to wait for user input
- break;
- case 'F': // failure (already announced in pop up)
- {
- state='F';
- TClientDC *dc=new TClientDC(*this);
- delete dc;
- }
- break;
- default: // continue
- break;
- }
- break;
- case 'F': // failed; wait for user input
- break;
- default: // done; wait for user input
- break;
- }
- TFrameWindow::IdleAction(IdleCount);
- return TRUE;
- }
-
- void SpikeWindow::Paint(TDC &dc,BOOL erase,TRect &dirty)
- // This method is invoked when part of the display has been made "dirty"
- // (for example, when another window has been moved from atop the display).
- {
- switch (state)
- {
- case 'B': // beginning
- // Nothing is displayed yet; nothing need be restored.
- break;
- case 'S': // preparing plot
- dc.PatBlt(this->GetClientRect(),WHITENESS);
- dc.TextOut(0,0,"Preparing plot...");
- // The internal state of the 3D plotter is not available here,
- // so display this message.
- break;
- case 'P': // still plotting
- state='P';
- GetClientRect(region_to_paint);
- plot3d_ptr->restart_plot();
- // Proceed to restore the entire display. Because the painter's
- // algorithm is used, areas outside the "dirty" region may still
- // need plotting.
- break;
- case 'F': // failed
- // Nothing is being displayed; nothing need be restored.
- break;
- default: // done
- state='P';
- region_to_paint=dirty;
- plot3d_ptr->restart_plot();
- // Redo the "dirty" region.
- break;
- }
- }
-
- void SpikeWindow::EvHScroll(UINT code,UINT pos,HWND wnd)
- // Processes a change in the horizontal scroll bar -- a request for a new angle
- // of rotation.
- {
- TFrameWindow::EvHScroll(code,pos,wnd);
- int change=FALSE;
- switch (code)
- {
- case SB_LINEUP:
- rotation--;
- change=TRUE;
- break;
- case SB_LINEDOWN:
- rotation++;
- change=TRUE;
- break;
- case SB_PAGEUP:
- rotation-=10;
- change=TRUE;
- break;
- case SB_PAGEDOWN:
- rotation+=10;
- change=TRUE;
- break;
- case SB_THUMBPOSITION:
- rotation=pos;
- change=TRUE;
- break;
- case SB_THUMBTRACK:
- break;
- default:
- break;
- }
- if (change)
- {
- delete plot3d_ptr;
- state='B'; // proceed to completely redo plot
- plot3d_ptr=new plot3d((TFrameWindow *) this);
- }
- return;
- }
-
- void SpikeWindow::EvSize(UINT sizeType,TSize &size)
- // Processes resizing of the window -- a request for a different size plot.
- {
- delete plot3d_ptr; // get rid of old 3D plotter
- state='B'; // proceed to completely redo plot
- plot3d_ptr=new plot3d((TFrameWindow *) this);
- return;
- }
-
- void SpikeWindow::EvVScroll(UINT code,UINT pos,HWND wnd)
- // Processes a change in the vertical scroll bar -- a request for a new angle of
- // tilt.
- {
- TFrameWindow::EvVScroll(code,pos,wnd);
- int change=FALSE;
- switch (code)
- {
- case SB_LINEUP:
- tilt++;
- if (tilt > 90)
- tilt=90;
- change=TRUE;
- break;
- case SB_LINEDOWN:
- tilt--;
- if (tilt < 0)
- tilt=0;
- change=TRUE;
- break;
- case SB_PAGEUP:
- tilt+=5;
- if (tilt > 90)
- tilt=90;
- change=TRUE;
- break;
- case SB_PAGEDOWN:
- tilt-=5;
- if (tilt < 0)
- tilt=0;
- change=TRUE;
- break;
- case SB_THUMBPOSITION:
- tilt=90-pos;
- change=TRUE;
- break;
- case SB_THUMBTRACK:
- break;
- default:
- break;
- }
- if (change)
- {
- delete plot3d_ptr;
- state='B'; // proceed to completely redo plot
- plot3d_ptr=new plot3d((TFrameWindow *) this);
- }
- return;
- }
-
- static int external_to_plot(
- double x,
- double y)
- // Returns TRUE if and only if a point (x,y) is external to the plot.
- {
- return FALSE;
- }
-
- static int red(
- double x,
- double y)
- // Returns TRUE if and only if a point (x,y) is flagged to be highlighted.
- {
- return FALSE;
- }
-
- static double f(
- double x,
- double y)
- // The function to be plotted.
- {
- double t1=x*x+y*y;
- double t2=cos(7.0*sqrt(t1));
- return 2.0*t2*t2/(1.0+30.0*t1);
- }
-
- class SpikeApp : public TApplication
- {
- public:
- SpikeApp() : TApplication("Spike") {}
- void InitMainWindow();
- };
-
- void SpikeApp::InitMainWindow()
- {
- MainWindow=new SpikeWindow(0,"Spike");
- MainWindow->SetIcon(this,"SPIKE_ICON");
- }
-
- int OwlMain(int /*argc*/, char* /*argv*/ [])
- // Execution of this program starts here.
- {
- return SpikeApp().Run(); // Process windows messages until user is done.
- }
-