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