www.pudn.com > MicroWindows-Source-200606.zip > cube.cpp
//
// Micro Windows Implementation
// cube.cpp
//
// $Revision: 1.3 $
// $Source: D:/DENG/PRG/MWINDOWS/APP/rcs/cube.cpp $
// $Date: 1993/11/14 05:43:42 $
//
#include "cube.h"
#include "shape.h"
#define ANGLE 5
CubeDemo::CubeDemo (View *parent, Rect *cubeRect)
{
erase = TRUE;
delay = 6000;
delayCounter = delay;
rho = 10;
theta = 0;
phi = 0;
ox = oy = oz = - 0.5;
cx = cy = xr = yr = 0;
Rect r;
if (cubeRect == NULL) parent->getRandomAttachRect (&r); else r = *cubeRect;
cubeWindow = new Window ("3D Cube", &r, parent, this, TRUE, TRUE);
speedUp = new Button ("Faster", &Rect(5, 5, 60, 25), cubeWindow, this);
speedDown = new Button ("Slower", &Rect(5, 26, 60, 46), cubeWindow, this);
idler->apply (cubeWindow);
}
BOOL CubeDemo::close (View *from)
{
idler->remove (cubeWindow);
return (TRUE);
}
void CubeDemo::draw (View *from, Port *port, Rect *area)
{
Rect r;
from->getClientRect (&r);
r.move (- r.x1, - r.y1);
port->setPenColor (PPC_Black);
port->draw (&FilledRectangle (&r));
erase = TRUE;
drawcube (port);
}
void CubeDemo::fromView (View *from)
{
erase = TRUE;
drawcube (from->getClientPort());
if (from == speedUp)
{
if (delay > 5) delay-=5;
}
else if (from == speedDown)
{
delay += 5;
}
from->draw ();
}
void CubeDemo::fromController (View *from, Controller *ctrl)
{
double pi = 3.14159;
double adegree = ANGLE * pi / 180;
if (erase == TRUE)
{
drawcube (from->getClientPort());
erase = FALSE;
delayCounter = delay;
}
else
{
if (delayCounter >= delay)
{
theta += adegree;
phi += adegree;
if (theta > 2 * pi)
{
theta = - 2 * pi;
phi = - 2 * pi;
}
drawcube (from->getClientPort());
}
delayCounter --;
if (!delayCounter) erase = TRUE;
}
}
void CubeDemo::calc3d (double x, double y, double z)
{
x += ox;
y += oy;
z += oz;
double xe = -x * s1 + y * c1;
double ye = -x * c1 * c2 - y*s1*c2 + z * s2;
double ze = -x * s2 * c1 - y*s2*s1 - z * c2 + rho;
xr = (int) (d * xe / ze) + cx;
yr = cy - (int)(d * ye / ze);
}
void CubeDemo::moveto3d (double x, double y, double z)
{
calc3d (x, y, z);
orig = Point (xr, yr);
}
void CubeDemo::lineto3d (Port *p, double x, double y, double z)
{
calc3d (x, y, z);
Point dest (xr, yr);
p->draw (&Line (&orig, &dest));
orig = dest;
}
void CubeDemo::drawcube (Port *p)
{
Rect r;
p->getPortRect (&r);
if (erase) p->setPenColor (PPC_Black); else p->setPenColor (PPC_White);
cx = r.width() / 2;
cy = r.height () / 2;
d = cx * 6;
s1 = sin(theta);
c1 = cos(theta);
s2 = sin(phi);
c2 = cos(phi);
moveto3d (0, 0, 0);
lineto3d (p, 1, 0, 0);
lineto3d (p, 1, 1, 0);
lineto3d (p, 0, 1, 0);
lineto3d (p, 0, 0, 0);
moveto3d (0, 0, 1);
lineto3d (p, 1, 0, 1);
lineto3d (p, 1, 1, 1);
lineto3d (p, 0, 1, 1);
lineto3d (p, 0, 0, 1);
moveto3d (1, 0, 0);
lineto3d (p, 1, 0, 1);
moveto3d (1, 1, 0);
lineto3d (p, 1, 1, 1);
moveto3d (0, 1, 0);
lineto3d (p, 0, 1, 1);
moveto3d (0, 0, 0);
lineto3d (p, 0, 0, 1);
// draw a word "X" on the cube face
moveto3d (0.3, 0.3, 0);
lineto3d (p, 0.7, 0.7, 0);
moveto3d (0.7, 0.3, 0);
lineto3d (p, 0.3, 0.7, 0);
}