Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

. To begin, construct a three-dimensional model of a scene in wireframe. The sce

ID: 3835108 • Letter: #

Question

. To begin, construct a three-dimensional model of a scene in wireframe. The scene must have at least one moving part, which should be animated while you fly a camera through the scene, giving a variety of points of view.After you have this working, give the model a solid surface (draw the faces as polygons and provide surface normals), apply materials to the surfaces, and light the scene with at least two lights.

WALKTHRU.CPP

#include "vector.h"

#include <GL/glut.h>   /* define GLUT window and device routines */

#define WINDOW_WIDTH   740   /* window dimensions */

#define WINDOW_HEIGHT   740

#define FALSE       0

#define TRUE       1

#define FRUSTUM_FAR   1800

#define ARROW_SPACING   50

#define FRAME_RATE   10

static double WinWidth = WINDOW_WIDTH;

static double WinHeight = WINDOW_HEIGHT;

static int TimerRunning = FALSE;

static double CameraZ = 150;

static double CameraY = 50;

static double CameraRoll = 0;

/*

Draw the scene

*/

void draw_scene(){

Vector3d arrow(1, 0, 0);

Vector3d loc;

int distance;

int i;

distance = (int)ceil(CameraZ / ARROW_SPACING) * ARROW_SPACING;

for(i = 0; i < FRUSTUM_FAR / ARROW_SPACING; i++){

distance -= ARROW_SPACING;

loc.set(-40, -40, distance);

arrow.draw(80, loc);

}

}

/*

Camera Motion Routine

*/

void MoveCamera(int value){

  

value = value;   // avoid warning message

CameraZ -= 10;

CameraY -= 0.5;

CameraRoll += 1;

glutTimerFunc(1000.0 / FRAME_RATE, MoveCamera, 0);

glutPostRedisplay();

}

/*

Adjust mouse coordinates to match window coordinates

*/

void AdjustMouse(int& x, int& y){

/* reverse y, so zero at bottom, and max at top */

y = WinHeight - y;

/* rescale x, y to match current window size (may have been rescaled) */

y *= WINDOW_HEIGHT / WinHeight;

x *= WINDOW_WIDTH / WinWidth;

}

/*

Watch mouse button presses, start camera motion on left button,

quit on right button.

*/

void handleButton(int button, int state, int x, int y){

AdjustMouse(x, y);   /* adjust mouse coords to current window size */

if(!TimerRunning && button == GLUT_LEFT_BUTTON && state == GLUT_UP){

glutTimerFunc(1000.0 / FRAME_RATE, MoveCamera, 0);

TimerRunning = TRUE;

}

else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP)

exit(0);

}

/*

On Redraw request, erase the window and redraw thread and crossings

*/

void drawDisplay(){

/* clear window */

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

glTranslatef(0, CameraY, -CameraZ);   // Camera transform

glRotatef(CameraRoll, 0, 0, 1);

draw_scene();

glutSwapBuffers();

}

/*

On Reshape request, reshape viewing coordinates

*/

void doReshape(int w, int h){

glViewport(0, 0, w, h);

WinWidth = w;

WinHeight = h;

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glFrustum(-1, 1, -1, 1, 1, FRUSTUM_FAR);

glMatrixMode(GL_MODELVIEW);

}

/*

   Main program to set up display

*/

int main(int argc, char* argv[]){

glutInit(&argc, argv);

/* open window and establish coordinate system on it */

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);

glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);

glutCreateWindow("Fly Through Demo");

/* register display and mouse-button callback routines */

glutReshapeFunc(doReshape);

glutDisplayFunc(drawDisplay);

glutMouseFunc(handleButton);

/* Set the line width */

glLineWidth(2);

/* Set shading to flat shading */

glShadeModel(GL_FLAT);

glutMainLoop();

return 0;

}

VECTOR.H

#include <math.h>   // define math library routines

#include <stdlib.h>   // define standard C library routines

#include <iostream>   // define C++ stream I/O routines

#include <GL/gl.h> // define OpenGL graphics routines

#include <GL/glu.h> // define OpenGL utility routines

using namespace std;

#define HIT_RADIUS   5       // radius around point for hit test

#define PI       3.1415926536   // blueberry or pizza?

#define CIRC_INC   (2 * PI / 36)   // radians per circle drawing segment

#define sqr(x)   ((x) * (x))   // square of x

#define RadToDeg(x) ((x) * (180.0 / PI))

#define DegToRad(x) ((x) * (PI / 180.0))

class Vector2d{

protected:

double x, y;

public:

Vector2d();

Vector2d(double vx, double vy);

Vector2d(Vector2d &v);

void set(double vx, double vy);

double normsqr();

double norm();

double getx();

double gety();

void draw(double scale, Vector2d &where);

void print();

};

Vector2d operator+(Vector2d &p0, Vector2d &p1);

Vector2d operator-(Vector2d &p0, Vector2d &p1);

double operator*(Vector2d &p0, Vector2d &p1);

Vector2d operator*(double a, Vector2d &p0);

Vector2d operator*(Vector2d &p0, double a);

Vector2d operator/(Vector2d &p0, double a);

class Point2d:public Vector2d{

public:

Point2d();

Point2d(double px, double py);

Point2d(Vector2d &v);

Point2d(Point2d &p);

void translate(double dx, double dy);   // translate by (dx, dy)

int hit(Point2d cursor);       // return true if cursor nearby

void draw();               // draw the point

};

class Vector3d{

protected:

double x, y, z;

public:

Vector3d();

Vector3d(double vx, double vy, double vz);

Vector3d(Vector2d &v);

Vector3d(Vector3d &v);

void set(double vx, double vy, double vz);

double normsqr();

double norm();

double getx();

double gety();

double getz();

void draw(double scale, Vector3d &where);

void print();

};

Vector3d operator+(Vector3d &p0, Vector3d &p1);

Vector3d operator-(Vector3d &p0, Vector3d &p1);

double operator*(Vector3d &p0, Vector3d &p1);

Vector3d operator%(Vector3d &p0, Vector3d &p1);

Vector3d operator*(double a, Vector3d &p0);

Vector3d operator*(Vector3d &p0, double a);

Vector3d operator/(Vector3d &p0, double a);

class Point3d:public Vector3d{

public:

Point3d();

Point3d(double px, double py, double pz);

Point3d(Vector2d &v);

Point3d(Vector3d &v);

Point3d(Point2d &p);

Point3d(Point3d &p);

void translate(double dx, double dy, double dz); // xlate by (dx, dy, dz)

int hit(Point3d cursor);       // return true if cursor nearby

void draw();               // draw the point

};

void Disk(double x, double y, double r);   // draw outlined circle

VECTOR.CPP

#include "vector.h"

Vector2d::Vector2d(){

set(0.0, 0.0);

}

Vector2d::Vector2d(double vx, double vy){

set(vx, vy);

}

Vector2d::Vector2d(Vector2d &v){

set(v.getx(), v.gety());

}

void Vector2d::set(double vx, double vy){

x = vx;

y = vy;

}

double Vector2d::normsqr(){

return sqr(x) + sqr(y);

}

double Vector2d::norm(){

return sqrt(normsqr());

}

double Vector2d::getx(){

return x;

}

double Vector2d::gety(){

return y;

}

void Vector2d::draw(double scale, Vector2d &where){

double len = norm() * scale;

glPushMatrix();

glTranslatef(where.getx(), where.gety(), 0.0);

glScalef(len, len, 1);

glRotatef(RadToDeg(atan2(y, x)), 0, 0, 1);

glBegin(GL_LINES);

glVertex2f(0, 0);

glVertex2f(1, 0);

glVertex2f(1, 0);

glVertex2f(0.87009619, 0.075);   // 0.87... == (1 - 0.075 * sqrt(3))

glVertex2f(1, 0);

glVertex2f(0.87009619, -0.075);

glEnd();

glPopMatrix();

}

void Vector2d::print(){

cout << "(" << x << ", " << y << ")";

}

Vector2d operator+(Vector2d &p0, Vector2d &p1){

  

Vector2d pt(p0.getx() + p1.getx(), p0.gety() + p1.gety());

return pt;

}

Vector2d operator-(Vector2d &p0, Vector2d &p1){

  

Vector2d pt(p0.getx() - p1.getx(), p0.gety() - p1.gety());

return pt;

}

double operator*(Vector2d &p0, Vector2d &p1){

  

return p0.getx() * p1.getx() + p0.gety() * p1.gety();

}

Vector2d operator*(double a, Vector2d &p0){

Vector2d pt(a * p0.getx(), a * p0.gety());

  

return pt;

}

Vector2d operator*(Vector2d &p0, double a){

Vector2d pt(a * p0.getx(), a * p0.gety());

  

return pt;

}

Vector2d operator/(Vector2d &p0, double a){

Vector2d pt(p0.getx() / a, p0.gety() / a);

  

return pt;

}

Point2d::Point2d(){

set(0.0, 0.0);

}

Point2d::Point2d(double px, double py){

set(px, py);

}

Point2d::Point2d(Vector2d &v){

set(v.getx(), v.gety());

}

Point2d::Point2d(Point2d &p){

set(p.getx(), p.gety());

}

void Point2d::translate(double dx, double dy){

x += dx;

y += dy;

}

int Point2d::hit(Point2d cursor){

return(sqr(x - cursor.getx()) + sqr(y - cursor.gety()) < sqr(HIT_RADIUS));

}

void Point2d::draw(){

glColor3f(0.9, 0.1, 0.1);   // light red

Disk(x, y, HIT_RADIUS);

}

Vector3d::Vector3d(){

set(0.0, 0.0, 0.0);

}

Vector3d::Vector3d(double vx, double vy, double vz){

set(vx, vy, vz);

}

Vector3d::Vector3d(Vector2d &v){

set(v.getx(), v.gety(), 0.0);

}

Vector3d::Vector3d(Vector3d &v){

set(v.getx(), v.gety(), v.getz());

}

void Vector3d::set(double vx, double vy, double vz){

x = vx;

y = vy;

z = vz;

}

double Vector3d::normsqr(){

return sqr(x) + sqr(y) + sqr(z);

}

double Vector3d::norm(){

return sqrt(normsqr());

}

double Vector3d::getx(){

return x;

}

double Vector3d::gety(){

return y;

}

double Vector3d::getz(){

return z;

}

void Vector3d::draw(double scale, Vector3d &where){

double len = norm() * scale;

glPushMatrix();

glTranslatef(where.getx(), where.gety(), where.getz());

glScalef(len, len, 1);

glRotatef(RadToDeg(atan2(y, x)), 0, 0, 1);

glBegin(GL_LINES);

glVertex3f(0, 0, 0);

glVertex3f(1, 0, 0);

glVertex3f(1, 0, 0);

glVertex3f(0.87009619, 0.075, 0);   // 0.87... == (1 - 0.075 * sqrt(3))

glVertex3f(1, 0, 0);

glVertex3f(0.87009619, -0.075, 0);

glEnd();

glPopMatrix();

}

void Vector3d::print(){

cout << "(" << x << ", " << y << ", " << z << ")";

}

Vector3d operator+(Vector3d &p0, Vector3d &p1){

  

Vector3d

pt(p0.getx() + p1.getx(), p0.gety() + p1.gety(), p0.getz() + p1.getz());

return pt;

}

Vector3d operator-(Vector3d &p0, Vector3d &p1){

  

Vector3d

pt(p0.getx() - p1.getx(), p0.gety() - p1.gety(), p0.getz() - p1.getz());

return pt;

}

double operator*(Vector3d &p0, Vector3d &p1){

  

return

p0.getx() * p1.getx() + p0.gety() * p1.gety() + p0.getz() * p1.getz();

}

Vector3d operator%(Vector3d &p0, Vector3d &p1){

  

Vector3d vc(p0.gety() * p1.getz() - p0.getz() * p1.gety(),

      p0.getz() * p1.getx() - p0.getx() * p1.getz(),

      p0.getx() * p1.gety() - p0.gety() * p1.getx());

return vc;

}

Vector3d operator*(double a, Vector3d &p0){

Vector3d pt(a * p0.getx(), a * p0.gety(), a * p0.getz());

  

return pt;

}

Vector3d operator*(Vector3d &p0, double a){

Vector3d pt(a * p0.getx(), a * p0.gety(), a * p0.getz());

  

return pt;

}

Vector3d operator/(Vector3d &p0, double a){

Vector3d pt(p0.getx() / a, p0.gety() / a, p0.getz() / a);

  

return pt;

}

Point3d::Point3d(){

set(0.0, 0.0, 0.0);

}

Point3d::Point3d(double px, double py, double pz){

set(px, py, pz);

}

Point3d::Point3d(Vector2d &v){

set(v.getx(), v.gety(), 0.0);

}

Point3d::Point3d(Vector3d &v){

set(v.getx(), v.gety(), v.getz());

}

Point3d::Point3d(Point2d &p){

set(p.getx(), p.gety(), 0.0);

}

Point3d::Point3d(Point3d &p){

set(p.getx(), p.gety(), p.getz());

}

void Point3d::translate(double dx, double dy, double dz){

x += dx;

y += dy;

y += dz;

}

int Point3d::hit(Point3d cursor){

return(sqr(x - cursor.getx()) + sqr(y - cursor.gety()) < sqr(HIT_RADIUS));

}

void Point3d::draw(){

glColor3f(0.9, 0.1, 0.1);   // light red

Disk(x, y, HIT_RADIUS);

}

//

// Draw an outlined circle with center at position (x, y) and radius r

//

void Disk(double x, double y, double r)

{

double theta;

glBegin(GL_POLYGON);

for(theta = 0.0; theta < 2 * PI; theta += CIRC_INC)

glVertex2f(x + r * cos(theta), y + r * sin(theta));

glEnd();

}

Explanation / Answer

WALKTHRU.CPP

#include "vector.h"

#include <GL/glut.h>   /* define GLUT window and device routines */

#define WINDOW_WIDTH   740   /* window dimensions */

#define WINDOW_HEIGHT   740

#define FALSE       0

#define TRUE       1

#define FRUSTUM_FAR   1800

#define ARROW_SPACING   50

#define FRAME_RATE   10

static double WinWidth = WINDOW_WIDTH;

static double WinHeight = WINDOW_HEIGHT;

static int TimerRunning = FALSE;

static double CameraZ = 150;

static double CameraY = 50;

static double CameraRoll = 0;

/*

Draw the scene

*/

void draw_scene(){

Vector3d arrow(1, 0, 0);

Vector3d loc;

int distance;

int i;

distance = (int)ceil(CameraZ / ARROW_SPACING) * ARROW_SPACING;

for(i = 0; i < FRUSTUM_FAR / ARROW_SPACING; i++){

distance -= ARROW_SPACING;

loc.set(-40, -40, distance);

arrow.draw(80, loc);

}

}

/*

Camera Motion Routine

*/

void MoveCamera(int value){

  

value = value;   // avoid warning message

CameraZ -= 10;

CameraY -= 0.5;

CameraRoll += 1;

glutTimerFunc(1000.0 / FRAME_RATE, MoveCamera, 0);

glutPostRedisplay();

}

/*

Adjust mouse coordinates to match window coordinates

*/

void AdjustMouse(int& x, int& y){

/* reverse y, so zero at bottom, and max at top */

y = WinHeight - y;

/* rescale x, y to match current window size (may have been rescaled) */

y *= WINDOW_HEIGHT / WinHeight;

x *= WINDOW_WIDTH / WinWidth;

}

/*

Watch mouse button presses, start camera motion on left button,

quit on right button.

*/

void handleButton(int button, int state, int x, int y){

AdjustMouse(x, y);   /* adjust mouse coords to current window size */

if(!TimerRunning && button == GLUT_LEFT_BUTTON && state == GLUT_UP){

glutTimerFunc(1000.0 / FRAME_RATE, MoveCamera, 0);

TimerRunning = TRUE;

}

else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP)

exit(0);

}

/*

On Redraw request, erase the window and redraw thread and crossings

*/

void drawDisplay(){

/* clear window */

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

glTranslatef(0, CameraY, -CameraZ);   // Camera transform

glRotatef(CameraRoll, 0, 0, 1);

draw_scene();

glutSwapBuffers();

}

/*

On Reshape request, reshape viewing coordinates

*/

void doReshape(int w, int h){

glViewport(0, 0, w, h);

WinWidth = w;

WinHeight = h;

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glFrustum(-1, 1, -1, 1, 1, FRUSTUM_FAR);

glMatrixMode(GL_MODELVIEW);

}

/*

   Main program to set up display

*/

int main(int argc, char* argv[]){

glutInit(&argc, argv);

/* open window and establish coordinate system on it */

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);

glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);

glutCreateWindow("Fly Through Demo");

/* register display and mouse-button callback routines */

glutReshapeFunc(doReshape);

glutDisplayFunc(drawDisplay);

glutMouseFunc(handleButton);

/* Set the line width */

glLineWidth(2);

/* Set shading to flat shading */

glShadeModel(GL_FLAT);

glutMainLoop();

return 0;

}

VECTOR.H

#include <math.h>   // define math library routines

#include <stdlib.h>   // define standard C library routines

#include <iostream>   // define C++ stream I/O routines

#include <GL/gl.h> // define OpenGL graphics routines

#include <GL/glu.h> // define OpenGL utility routines

using namespace std;

#define HIT_RADIUS   5       // radius around point for hit test

#define PI       3.1415926536   // blueberry or pizza?

#define CIRC_INC   (2 * PI / 36)   // radians per circle drawing segment

#define sqr(x)   ((x) * (x))   // square of x

#define RadToDeg(x) ((x) * (180.0 / PI))

#define DegToRad(x) ((x) * (PI / 180.0))

class Vector2d{

protected:

double x, y;

public:

Vector2d();

Vector2d(double vx, double vy);

Vector2d(Vector2d &v);

void set(double vx, double vy);

double normsqr();

double norm();

double getx();

double gety();

void draw(double scale, Vector2d &where);

void print();

};

Vector2d operator+(Vector2d &p0, Vector2d &p1);

Vector2d operator-(Vector2d &p0, Vector2d &p1);

double operator*(Vector2d &p0, Vector2d &p1);

Vector2d operator*(double a, Vector2d &p0);

Vector2d operator*(Vector2d &p0, double a);

Vector2d operator/(Vector2d &p0, double a);

class Point2d:public Vector2d{

public:

Point2d();

Point2d(double px, double py);

Point2d(Vector2d &v);

Point2d(Point2d &p);

void translate(double dx, double dy);   // translate by (dx, dy)

int hit(Point2d cursor);       // return true if cursor nearby

void draw();               // draw the point

};

class Vector3d{

protected:

double x, y, z;

public:

Vector3d();

Vector3d(double vx, double vy, double vz);

Vector3d(Vector2d &v);

Vector3d(Vector3d &v);

void set(double vx, double vy, double vz);

double normsqr();

double norm();

double getx();

double gety();

double getz();

void draw(double scale, Vector3d &where);

void print();

};

Vector3d operator+(Vector3d &p0, Vector3d &p1);

Vector3d operator-(Vector3d &p0, Vector3d &p1);

double operator*(Vector3d &p0, Vector3d &p1);

Vector3d operator%(Vector3d &p0, Vector3d &p1);

Vector3d operator*(double a, Vector3d &p0);

Vector3d operator*(Vector3d &p0, double a);

Vector3d operator/(Vector3d &p0, double a);

class Point3d:public Vector3d{

public:

Point3d();

Point3d(double px, double py, double pz);

Point3d(Vector2d &v);

Point3d(Vector3d &v);

Point3d(Point2d &p);

Point3d(Point3d &p);

void translate(double dx, double dy, double dz); // xlate by (dx, dy, dz)

int hit(Point3d cursor);       // return true if cursor nearby

void draw();               // draw the point

};

void Disk(double x, double y, double r);   // draw outlined circle

VECTOR.CPP

#include "vector.h"

Vector2d::Vector2d(){

set(0.0, 0.0);

}

Vector2d::Vector2d(double vx, double vy){

set(vx, vy);

}

Vector2d::Vector2d(Vector2d &v){

set(v.getx(), v.gety());

}

void Vector2d::set(double vx, double vy){

x = vx;

y = vy;

}

double Vector2d::normsqr(){

return sqr(x) + sqr(y);

}

double Vector2d::norm(){

return sqrt(normsqr());

}

double Vector2d::getx(){

return x;

}

double Vector2d::gety(){

return y;

}

void Vector2d::draw(double scale, Vector2d &where){

double len = norm() * scale;

glPushMatrix();

glTranslatef(where.getx(), where.gety(), 0.0);

glScalef(len, len, 1);

glRotatef(RadToDeg(atan2(y, x)), 0, 0, 1);

glBegin(GL_LINES);

glVertex2f(0, 0);

glVertex2f(1, 0);

glVertex2f(1, 0);

glVertex2f(0.87009619, 0.075);   // 0.87... == (1 - 0.075 * sqrt(3))

glVertex2f(1, 0);

glVertex2f(0.87009619, -0.075);

glEnd();

glPopMatrix();

}

void Vector2d::print(){

cout << "(" << x << ", " << y << ")";

}

Vector2d operator+(Vector2d &p0, Vector2d &p1){

  

Vector2d pt(p0.getx() + p1.getx(), p0.gety() + p1.gety());

return pt;

}

Vector2d operator-(Vector2d &p0, Vector2d &p1){

  

Vector2d pt(p0.getx() - p1.getx(), p0.gety() - p1.gety());

return pt;

}

double operator*(Vector2d &p0, Vector2d &p1){

  

return p0.getx() * p1.getx() + p0.gety() * p1.gety();

}

Vector2d operator*(double a, Vector2d &p0){

Vector2d pt(a * p0.getx(), a * p0.gety());

  

return pt;

}

Vector2d operator*(Vector2d &p0, double a){

Vector2d pt(a * p0.getx(), a * p0.gety());

  

return pt;

}

Vector2d operator/(Vector2d &p0, double a){

Vector2d pt(p0.getx() / a, p0.gety() / a);

  

return pt;

}

Point2d::Point2d(){

set(0.0, 0.0);

}

Point2d::Point2d(double px, double py){

set(px, py);

}

Point2d::Point2d(Vector2d &v){

set(v.getx(), v.gety());

}

Point2d::Point2d(Point2d &p){

set(p.getx(), p.gety());

}

void Point2d::translate(double dx, double dy){

x += dx;

y += dy;

}

int Point2d::hit(Point2d cursor){

return(sqr(x - cursor.getx()) + sqr(y - cursor.gety()) < sqr(HIT_RADIUS));

}

void Point2d::draw(){

glColor3f(0.9, 0.1, 0.1);   // light red

Disk(x, y, HIT_RADIUS);

}

Vector3d::Vector3d(){

set(0.0, 0.0, 0.0);

}

Vector3d::Vector3d(double vx, double vy, double vz){

set(vx, vy, vz);

}

Vector3d::Vector3d(Vector2d &v){

set(v.getx(), v.gety(), 0.0);

}

Vector3d::Vector3d(Vector3d &v){

set(v.getx(), v.gety(), v.getz());

}

void Vector3d::set(double vx, double vy, double vz){

x = vx;

y = vy;

z = vz;

}

double Vector3d::normsqr(){

return sqr(x) + sqr(y) + sqr(z);

}

double Vector3d::norm(){

return sqrt(normsqr());

}

double Vector3d::getx(){

return x;

}

double Vector3d::gety(){

return y;

}

double Vector3d::getz(){

return z;

}

void Vector3d::draw(double scale, Vector3d &where){

double len = norm() * scale;

glPushMatrix();

glTranslatef(where.getx(), where.gety(), where.getz());

glScalef(len, len, 1);

glRotatef(RadToDeg(atan2(y, x)), 0, 0, 1);

glBegin(GL_LINES);

glVertex3f(0, 0, 0);

glVertex3f(1, 0, 0);

glVertex3f(1, 0, 0);

glVertex3f(0.87009619, 0.075, 0);   // 0.87... == (1 - 0.075 * sqrt(3))

glVertex3f(1, 0, 0);

glVertex3f(0.87009619, -0.075, 0);

glEnd();

glPopMatrix();

}

void Vector3d::print(){

cout << "(" << x << ", " << y << ", " << z << ")";

}

Vector3d operator+(Vector3d &p0, Vector3d &p1){

  

Vector3d

pt(p0.getx() + p1.getx(), p0.gety() + p1.gety(), p0.getz() + p1.getz());

return pt;

}

Vector3d operator-(Vector3d &p0, Vector3d &p1){

  

Vector3d

pt(p0.getx() - p1.getx(), p0.gety() - p1.gety(), p0.getz() - p1.getz());

return pt;

}

double operator*(Vector3d &p0, Vector3d &p1){

  

return

p0.getx() * p1.getx() + p0.gety() * p1.gety() + p0.getz() * p1.getz();

}

Vector3d operator%(Vector3d &p0, Vector3d &p1){

  

Vector3d vc(p0.gety() * p1.getz() - p0.getz() * p1.gety(),

      p0.getz() * p1.getx() - p0.getx() * p1.getz(),

      p0.getx() * p1.gety() - p0.gety() * p1.getx());

return vc;

}

Vector3d operator*(double a, Vector3d &p0){

Vector3d pt(a * p0.getx(), a * p0.gety(), a * p0.getz());

  

return pt;

}

Vector3d operator*(Vector3d &p0, double a){

Vector3d pt(a * p0.getx(), a * p0.gety(), a * p0.getz());

  

return pt;

}

Vector3d operator/(Vector3d &p0, double a){

Vector3d pt(p0.getx() / a, p0.gety() / a, p0.getz() / a);

  

return pt;

}

Point3d::Point3d(){

set(0.0, 0.0, 0.0);

}

Point3d::Point3d(double px, double py, double pz){

set(px, py, pz);

}

Point3d::Point3d(Vector2d &v){

set(v.getx(), v.gety(), 0.0);

}

Point3d::Point3d(Vector3d &v){

set(v.getx(), v.gety(), v.getz());

}

Point3d::Point3d(Point2d &p){

set(p.getx(), p.gety(), 0.0);

}

Point3d::Point3d(Point3d &p){

set(p.getx(), p.gety(), p.getz());

}

void Point3d::translate(double dx, double dy, double dz){

x += dx;

y += dy;

y += dz;

}

int Point3d::hit(Point3d cursor){

return(sqr(x - cursor.getx()) + sqr(y - cursor.gety()) < sqr(HIT_RADIUS));

}

void Point3d::draw(){

glColor3f(0.9, 0.1, 0.1);   // light red

Disk(x, y, HIT_RADIUS);

}

//

// Draw an outlined circle with center at position (x, y) and radius r

//

void Disk(double x, double y, double r)

{

double theta;

glBegin(GL_POLYGON);

for(theta = 0.0; theta < 2 * PI; theta += CIRC_INC)

glVertex2f(x + r * cos(theta), y + r * sin(theta));

glEnd();

}