home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc.
- * ALL RIGHTS RESERVED
- * Permission to use, copy, modify, and distribute this software for
- * any purpose and without fee is hereby granted, provided that the above
- * copyright notice appear in all copies and that both the copyright notice
- * and this permission notice appear in supporting documentation, and that
- * the name of Silicon Graphics, Inc. not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission.
- *
- * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
- * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
- * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
- * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
- * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
- * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
- * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * US Government Users Restricted Rights
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
- * (c)(1)(ii) of the Rights in Technical Data and Computer Software
- * clause at DFARS 252.227-7013 and/or in similar or successor
- * clauses in the FAR or the DOD or NASA FAR Supplement.
- * Unpublished-- rights reserved under the copyright laws of the
- * United States. Contractor/manufacturer is Silicon Graphics,
- * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
- *
- * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
- */
- #ifndef POINT_H
- #define POINT_H
-
- #ifndef POINT_EXTERN
- #define POINT_EXTERN extern
- #endif
-
- const float point_fudge = .000001;
-
- class Point_b {
- public:
- inline Point_b operator=(Point_b a);
- inline Point_b operator=(GLfloat *a);
- inline Point_b operator+(Point_b a);
- inline Point_b operator+=(Point_b a);
- inline Point_b operator-(Point_b a);
- // This takes a cross-product
- inline Point_b operator*(Point_b b);
- inline Point_b operator*(GLfloat b);
- inline Point_b operator/(GLfloat b);
- inline Point_b operator/=(GLfloat b);
- inline GLfloat& operator[](int index);
-
- inline GLfloat dist(Point_b b);
- inline GLfloat dot(Point_b b);
- inline GLfloat mag();
- inline GLfloat magsquared();
- inline Point_b unit();
- inline void unitize();
-
- // Angle is in RADIANS
- inline Point_b rotate(Point_b axis, GLfloat angle);
- inline Point_b rotate(Point_b axis, GLfloat c, GLfloat s);
- inline void rotate_self(Point_b axis, GLfloat c, GLfloat s);
- Point_b rotate_abouty(GLfloat c, GLfloat s);
-
- // Returns point projected through proj_pt into XY plane
- // Does nothing if proj_pt - *this is parallel to XY plane
- inline Point_b project(Point_b proj_pt);
- inline void project_self(Point_b proj_pt);
- inline void /*Point_b::*/project_self(GLfloat px, GLfloat py, GLfloat pz);
- inline Point_b project_direction(Point_b direction);
- inline Point_b /*Point_b::*/project_direction(GLfloat x, GLfloat y, GLfloat z);
- // This projects (px, py, pz) into this in direction (dx, dy, dz)
- inline void /*Point_b::*/compute_projected(GLfloat px, GLfloat py, GLfloat pz,
- GLfloat x, GLfloat y, GLfloat z);
-
- // Returns point projected through light and refracted into XY
- // plane.
- // N is normal at point (ie normal at *this)
- // I is the index of refraction
- inline Point_b refract(Point_b light, Point_b N, GLfloat I);
- void refract_self(Point_b light, Point_b N, GLfloat I);
- Point_b refract_direction(Point_b light, Point_b N, GLfloat I);
-
- inline void glvertex();
- inline void glnormal();
-
- void print();
- void print(const char *format);
-
- GLfloat pt[4];
- private:
- };
-
- POINT_EXTERN Point_b val;
-
- #define DOT(a, b) (a.pt[0]*b.pt[0] + a.pt[1]*b.pt[1] + a.pt[2]*b.pt[2])
- #define THIS_DOT(b) (pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2])
-
- inline Point_b Point_b::operator=(Point_b a)
- {
- pt[0] = a.pt[0];
- pt[1] = a.pt[1];
- pt[2] = a.pt[2];
- pt[3] = a.pt[3];
- return *this;
- }
-
- inline Point_b Point_b::operator=(GLfloat *a)
- {
- pt[0] = a[0];
- pt[1] = a[1];
- pt[2] = a[2];
- pt[3] = 1;
- return *this;
- }
-
- inline Point_b Point_b::operator+(Point_b a)
- {
- val.pt[0] = pt[0] + a.pt[0];
- val.pt[1] = pt[1] + a.pt[1];
- val.pt[2] = pt[2] + a.pt[2];
- return val;
- }
-
- inline Point_b Point_b::operator+=(Point_b a)
- {
- pt[0] += a.pt[0];
- pt[1] += a.pt[1];
- pt[2] += a.pt[2];
- return *this;
- }
-
- inline Point_b Point_b::operator-(Point_b a)
- {
- val.pt[0] = pt[0] - a.pt[0];
- val.pt[1] = pt[1] - a.pt[1];
- val.pt[2] = pt[2] - a.pt[2];
- return val;
- }
-
- inline Point_b Point_b::operator*(Point_b b)
- {
- val.pt[0] = pt[1]*b.pt[2] - b.pt[1]*pt[2];
- val.pt[1] = pt[2]*b.pt[0] - b.pt[2]*pt[0];
- val.pt[2] = pt[0]*b.pt[1] - pt[1]*b.pt[0];
- return val;
- }
-
- inline Point_b Point_b::operator*(GLfloat b)
- {
- val.pt[0] = pt[0] * b;
- val.pt[1] = pt[1] * b;
- val.pt[2] = pt[2] * b;
- return val;
- }
-
- inline Point_b Point_b::operator/(GLfloat b)
- {
- val.pt[0] = pt[0] / b;
- val.pt[1] = pt[1] / b;
- val.pt[2] = pt[2] / b;
- return val;
- }
-
- inline Point_b Point_b::operator/=(GLfloat b)
- {
- pt[0] /= b;
- pt[1] /= b;
- pt[2] /= b;
- return *this;
- }
-
- inline GLfloat& Point_b::operator[](int index)
- {
- return pt[index];
- }
-
- inline GLfloat Point_b::dist(Point_b b)
- {
- return (*this - b).mag();
- }
-
- inline GLfloat Point_b::dot(Point_b b)
- {
- return pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2];
- }
-
- inline GLfloat Point_b::mag()
- {
- return sqrt(pt[0]*pt[0] + pt[1]*pt[1] +
- pt[2]*pt[2]);
- }
-
- inline GLfloat Point_b::magsquared()
- {
- return pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2];
- }
-
- inline Point_b Point_b::unit()
- {
- GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
- val.pt[0] = pt[0] / m;
- val.pt[1] = pt[1] / m;
- val.pt[2] = pt[2] / m;
- return val;
- }
-
- inline void Point_b::unitize()
- {
- GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
- pt[0] /= m;
- pt[1] /= m;
- pt[2] /= m;
- }
-
- inline Point_b Point_b::rotate(Point_b axis, GLfloat angle)
- {
- return rotate(axis, cos(angle), sin(angle));
- }
-
- inline Point_b Point_b::rotate(Point_b axis, GLfloat c, GLfloat s)
- {
- float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
- float tx, ty;
-
- tx = t*x;
- /* Taking advantage of inside info that this is a common case */
- if (y == 0.0) {
- val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(-s*z) + pt[2]*(tx*z);
- val.pt[1] = pt[0]*(s*z) + pt[1]*c + pt[2]*(-s*x);
- val.pt[2] = pt[0]*(tx*z) + pt[1]*s*x + pt[2]*(t*z*z + c);
- } else {
- ty = t*y;
- val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(tx*y - s*z) +
- pt[2]*(tx*z + s*y);
- val.pt[1] = pt[0]*(tx*y + s*z) + pt[1]*(ty*y + c) +
- pt[2]*(ty*z - s*x);
- val.pt[2] = pt[0]*(tx*z - s*y) + pt[1]*(ty*z + s*x) +
- pt[2]*(t*z*z + c);
- }
- return val;
- }
-
- inline void Point_b::rotate_self(Point_b axis, GLfloat c, GLfloat s)
- {
- float Px, Py, Pz;
- float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
- float tx, ty;
-
- tx = t*x;
- Px = pt[0];
- Py = pt[1];
- Pz = pt[2];
- /* Taking advantage of inside info that this is a common case */
- if (!y) {
- pt[0] = Px*(tx*x + c) + Py*(-s*z) + Pz*(tx*z);
- pt[1] = Px*(s*z) + Py*c + Pz*(-s*x);
- pt[2] = Px*(tx*z) + Py*s*x + Pz*(t*z*z + c);
- } else {
- ty = t*y;
- pt[0] = Px*(tx*x + c) + Py*(tx*y - s*z) +
- Pz*(tx*z + s*y);
- pt[1] = Px*(tx*y + s*z) + Py*(ty*y + c) +
- Pz*(ty*z - s*x);
- pt[2] = Px*(tx*z - s*y) + Py*(ty*z + s*x) +
- Pz*(t*z*z + c);
- }
- }
-
- inline void Point_b::glvertex()
- {
- glVertex3fv(pt);
- }
-
- inline void Point_b::glnormal()
- {
- glNormal3fv(pt);
- }
-
- inline Point_b Point_b::project(Point_b proj_pt)
- {
- GLfloat dirx = pt[0] - proj_pt.pt[0],
- diry = pt[1] - proj_pt.pt[1],
- dirz = pt[2] - proj_pt.pt[2];
- GLfloat t;
-
- if (fabs(dirz) < point_fudge) val = *this;
- else {
- t = -proj_pt.pt[2] / dirz;
- val.pt[0] = proj_pt.pt[0] + dirx*t;
- val.pt[1] = proj_pt.pt[1] + diry*t;
- val.pt[2] = 0.0;
- }
- return val;
- }
-
- // This naively assumes that proj_pt[z] != this->pt[z]
- inline void Point_b::project_self(Point_b proj_pt)
- {
- GLfloat dirx = pt[0] - proj_pt.pt[0],
- diry = pt[1] - proj_pt.pt[1],
- dirz = pt[2] - proj_pt.pt[2];
- GLfloat t;
-
- t = -proj_pt.pt[2] / dirz;
- pt[0] = proj_pt.pt[0] + dirx*t;
- pt[1] = proj_pt.pt[1] + diry*t;
- pt[2] = 0.0;
- }
-
- inline void Point_b::project_self(GLfloat px, GLfloat py, GLfloat pz)
- {
- GLfloat dirx = pt[0] - px,
- diry = pt[1] - py,
- dirz = pt[2] - pz, t;
-
- t = -pz / dirz;
- pt[0] = px + dirx*t;
- pt[1] = py + diry*t;
- pt[2] = 0.0;
- }
-
- inline Point_b Point_b::project_direction(Point_b direction) {
- GLfloat t;
-
- t = -pt[2] / direction.pt[2];
- val.pt[0] = pt[0] + direction.pt[0]*t;
- val.pt[1] = pt[1] + direction.pt[1]*t;
- val.pt[2] = 0;
- return val;
- }
-
- inline Point_b Point_b::project_direction(GLfloat x, GLfloat y, GLfloat z)
- {
- GLfloat t;
-
- t = -pt[2] / z;
- val.pt[0] = pt[0] + x*t;
- val.pt[1] = pt[1] + y*t;
- val.pt[2] = 0;
- return val;
- }
-
- inline void Point_b::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
- GLfloat dx, GLfloat dy, GLfloat dz)
- {
- GLfloat t = -pz / dz;
- pt[0] = px + dx*t;
- pt[1] = py + dy*t;
- pt[2] = 0;
- }
-
-
- #undef POINT_EXTERN
-
- #endif
-