// Geometry3D.h
// Header file for the 3D geometry classes.
// Copyright 1999 and 2000 by Rick Wagner,
// all rights reserved.
//
// Code use permission granted for educational purposes at USC only.
// No use without attribution.
//
// Version 1.14.
// Created September 10, 1999, last edited June 23, 2000.

#ifndef POINT3D_H
#define POINT3D_H

#include <math.h>

// Global constants:
const float gsfPi = (float) (atan(1.0) * 4.0);         // Compute pi.
const float gsfEpsilon = (float) 0.0000000001;         // Tiny number, nine balls one.

// Classes are listed below in referenced order.

// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Direction3D: a class to model a unit direction vector in 3D:
class Direction3D
{
public:

  Direction3D();                                       // Default constructor.
  Direction3D(float x, float y, float z);              // 3-vector constructor.
  Direction3D(float alpha, float beta);                // 2-angle constructor.
  Direction3D(const Direction3D& d);                   // Copy constructor.

  float getX() const;                                  // Vector accessors.
  float getY() const;
  float getZ() const;

  float getAzimuth() const;                            // Angle accessors.
  float getElevation() const;

  void setX(float x);                                  // 1-vector mutator.
  void setY(float y);                                  // 1-vector mutator.
  void setZ(float z);                                  // 1-vector mutator.
  void setXYZ(float x, float y, float z);              // 3-vector mutator.
  void setAzimuth(float alpha);                        // Azimuth mutator.
  void setElevation(float beta);                       // Elevation mutator.

  float dotProduct(const Direction3D& d);              // Return the dot product of two directions.
  float angleBetween(const Direction3D& d);            // Return the angle between two directions.
  Direction3D* crossProduct(const Direction3D& d);     // Return the cross product of two directions.

private:

  float _x;                                            // X component of the vector.
  float _y;                                            // Y component of the vector.
  float _z;                                            // Z component of the vector.

}; // End of Direction3D class declaration.

// Non-member functions for the Direction3D class:
bool operator ==(const Direction3D& d1, const Direction3D& d2);


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Point3D: a class to model a point in three dimensional Cartesian space:
class Point3D
{
public:

  Point3D(float x = 0, float y = 0, float z = 0,       // Constructor.
          char* l = "");
  Point3D(const Point3D& p);                           // Copy constructor.

  ~Point3D();                                          // Destructor.

  float getX() const;                                  // Accessors.
  float getY() const;
  float getZ() const;
  char* getLabel() const;

  void setX(float x);                                  // Mutators.
  void setY(float y);
  void setZ(float z);
  void setLabel(char* l);

  void operator =(const Point3D& source);              // Overloaded assignment operator.

  float distance(const Point3D& p);                    // Return the distance to another point.

  bool equals(const Point3D& p);                       // Test for equality with another point.

private:

  float _x;                                            // X coordinate of the point.
  float _y;                                            // Y coordinate of the point.
  float _z;                                            // Z coordinate of the point.

  char* _label;                                        // A text label for the point.

}; // End of Point3D class declaration.

// Nonmember functions for the Point3D class:

// Return the distance between two points:
float distance(const Point3D& p1, const Point3D& p2);

// Operator overloading:
bool operator ==(const Point3D& p1, const Point3D& p2);


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Edge3D: a class to model an edge (line segment) in three dimensional Cartesian space:
class Edge3D
{
public:

  Edge3D();                                            // Default constructor.
  Edge3D(const Point3D& p1, const Point3D& p2);        // Two point constructor.
  Edge3D(const Edge3D& e);                             // Copy constructor.
  void operator =(const Edge3D& source);               // Overloaded assignment operator.
  ~Edge3D();                                           // Destructor.

  Point3D* getP1() const;                              // Accessors.
  Point3D* getP2() const;

  void setP1(const Point3D& p);                        // Mutators.
  void setP2(const Point3D& p);

  bool equals(const Edge3D& e);                        // Test for equality with another edge.

private:

  Point3D *_p1;                                        // Point one of the edge.
  Point3D *_p2;                                        // Point two of the edge.

}; // End of Edge3D class declaration.


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// DirectedPoint3D: a class to model a point with direction in three dimensional Cartesian space.
// Can be used to model a plane, a line, or a unit wrench.
class DirectedPoint3D
{
public:

  DirectedPoint3D();                                        // Default constructor.
  DirectedPoint3D(const Direction3D& d, const Point3D& p);  // General constructor.
  DirectedPoint3D(const DirectedPoint3D& dp);               // Copy constructor.
  void operator =(const DirectedPoint3D& dp);               // Overloaded assignment operator.

  ~DirectedPoint3D();                                       // Destructor.

  // Accessors:
  Direction3D* getDirection() const;                        // Returns a pointer to a copy of the direction.
  Point3D* getPoint() const;                                // Returns a pointer to a copy of the point.

  // Mutators:
  void setDirection(const Direction3D& d);
  void setPoint(const Point3D& p);

private:

  Direction3D *_d;
  Point3D *_p;

}; // End of DirectedPoint3D class declaration.

// Non-member functions for the DirectedPoint3D class:

// Return the intersection point with a plane:
Point3D* LinePlaneIntersection(DirectedPoint3D line, DirectedPoint3D plane);

// Return the line of intersection of two planes:
DirectedPoint3D* GetPlaneIntersection(DirectedPoint3D plane1, DirectedPoint3D plane2);


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Vector3D: a class to model a vector in three dimensional Cartesian space:
class Vector3D
{
public:

  Vector3D();                                           // Default constructor.
  Vector3D(const Direction3D& d, float l = 1);          // General constructor.
  Vector3D(const Vector3D& v);                          // Copy constructor.

  ~Vector3D();                                          // Destructor.

  // Accessors:
  Direction3D* getDirection() const;                    // Returns a pointer to a copy of the direction.
  float getLength() const;                              // Returns the length of the vector.

  // Mutators:
  void setDirection(const Direction3D& d);
  void setLength(float l);

  void operator =(const Vector3D& source);              // Overloaded assignment operator.

  float dotProduct(const Vector3D& v);                  // Return the dot product of two directions.
  float angleBetween(const Vector3D& v);                // Return the angle between two directions.

private:

  Direction3D *_d;                                      // Vector direction.
  float _l;                                             // Vector length.
  
}; // End of Vector3D class declaration.


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Polygon3D: a class to model a polygon in three dimensional Cartesian space:
class Polygon3D
{
public:

  Polygon3D();                                           // Default constructor.
  Polygon3D(Edge3D **e, int n);                          // General constructor.
  Polygon3D(const Polygon3D& p);                         // Copy constructor.

  ~Polygon3D();                                          // Destructor.

  // Accessors:
  Edge3D* getEdge(int n) const;                          // Returns a pointer to a copy of the nth edge.

  // Mutators:
  void setEdge(const Edge3D& e, int n);                  // Change the nth edge.
  void addEdge(const Edge3D& e);                         // Add a new edge (to the end of the array).

  void operator =(const Polygon3D& source);              // Overloaded assignment operator.

private:

  int _n;                                                // Number of edges in the polygon.
  Edge3D **_e;                                           // Edge pointer array.
  
}; // End of Polygon3D class declaration.


// *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  
// Polyhedron3D: a class to model a polyhedron (BRep) in three dimensional Cartesian space:
class Polyhedron3D
{
public:

  Polyhedron3D();                                        // Default constructor.
  Polyhedron3D(Polygon3D **p, int n);                    // General constructor.
  Polyhedron3D(const Polyhedron3D& p);                   // Copy constructor.

  ~Polyhedron3D();                                       // Destructor.

  // Accessors:
  Polygon3D* getPolygon(int n) const;                    // Returns a pointer to a copy of the nth polygon.

  // Mutators:
  void setPolygon(const Polygon3D& p, int n);            // Change the nth polygon.
  void addPolygon(const Polygon3D& p);                   // Add a new polygon (to the end of the array).

  void operator =(const Polyhedron3D& source);           // Overloaded assignment operator.

private:

  int _n;                                                // Number of polygons in the polyhedron.
  Polygon3D **_p;                                        // polygon pointer array.
  
}; // End of Polyhedron3D class declaration.



#endif
