/* Copyright (C) 1997, 1998, 1999 by Alex Pfaffe (Digital Dawn Graphics Inc) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _ddgGeometry_Class_ #define _ddgGeometry_Class_ #ifdef DDG #include "math/ddgvec.h" #include "util/ddgerror.h" #else #include "sysdef.h" #include "csgeom/math2d.h" #include "csgeom/math3d.h" #include "csterr/util/ddg.h" #include "csterr/math/ddgvec.h" #endif #define ddgVertex ddgVector3 #define ddgPoint3 ddgVector3 class ddgPlane { ddgVector3 _normal; float _d; public: inline float a(void) { return _normal[0];}; inline float b(void) { return _normal[1];}; inline float c(void) { return _normal[2];}; inline float d(void) { return _d;}; inline ddgVector3 *normal(void) { return &_normal; } ddgPlane(void) {} ddgPlane( const ddgVector3 p0, const ddgVector3 p1, const ddgVector3 p2) { #ifdef DDG _normal.normal(&p0,&p1,&p2); // Solve for D. _d = -1 * (_normal.dot(&p0)); #else _normal = ddgVector3(p2 - p1) * ddgVector3(p0 - p1); // Solve for D. _d = -1 * (_normal * p0); #endif } ddgPlane( const ddgVector3 p0, const ddgVector3 n) { _normal = n; // Solve for D. #ifdef DDG _d = -1 * (_normal.dot(&p0)); #else _d = -1 * (_normal * p0); #endif } bool projectAlongX(ddgVector3 *p) { if (_normal[0] == 0.0) return ddgFailure; (*p)[0] = -1 * (_d + _normal[1] * (*p)[1] + _normal[2] * (*p)[2])/ _normal[0]; return ddgSuccess; } bool projectAlongY(ddgVector3 *p) { if (_normal[1] == 0.0) return ddgFailure; (*p)[1] = -1 * (_d + _normal[0] * (*p)[0] + _normal[2] * (*p)[2])/ _normal[1]; return ddgSuccess; } bool projectAlongZ(ddgVector3 *p) { if (_normal[2] == 0.0) return ddgFailure; (*p)[2] = -1 * (_d + _normal[1] * (*p)[1] + _normal[0] * (*p)[0])/ _normal[2]; return ddgSuccess; } void set( const ddgVector3 n, float d ) { _normal = n; _d = d; } void normalize( void ) { #ifdef DDG _d /= _normal.size(); _normal.normalize(); #else _d /= _normal.Norm(); _normal.Normalize(); #endif } ddgVector3 project(ddgVector3 *p0); bool intersectPlaneWithLine( const ddgVector3 l1, const ddgVector3 l2, ddgVector3 *pi); bool intersectPointPlane( const ddgVector3 pt); float distToPoint(const ddgVector3 p); float isPointAbovePlane(const ddgVector3 p); }; class ddgTriangle { ddgVertex _v1; ddgVertex _v2; ddgVertex _v3; public: ddgTriangle(ddgVector3 p1, ddgVector3 p2, ddgVector3 p3 ) : _v1(p1), _v2(p2), _v3(p3) {} bool intersectTriangleWithLine( const ddgVector3 l1, const ddgVector3 l2, ddgVector3 *pi); bool intersectPointTriangle( const ddgVector3 pt); }; class ddgPolygon { unsigned short _n; ddgVector3 *_p; public: unsigned int vertices(void) { return _n; } ddgVector3 *vertex(unsigned int n) { return &(_p[n]); } ddgPolygon *clip( ddgPlane *p, bool rotated); }; class ddgRect { public: ddgVector2 min; ddgVector2 max; ddgRect(void) {} ddgRect( ddgVector2 p1, ddgVector2 p2) { min = p1; max = p1; min.minimum(p2); max.maximum(p2); } bool intersect(ddgRect *r, ddgRect *i = NULL) { if (r->min[0] > max[0] || min[0] > r->max[0] || r->min[1] > max[1] || min[1] > r->max[1]) return false; if (i) { i->min = min; i->max = max; i->min.maximum(r->min); i->max.minimum(r->max); } return true; } }; class ddgLine2 { ddgVector2 _p; ddgVector2 _d; public: ddgLine2( ddgVector2 p1, ddgVector2 p2 ) { _p.set(p1); _d.set(p2-p1); _d.normalize(); } ddgVector2 p(void) { return _p; } ddgVector2 d(void) { return _d; } inline bool solve( ddgVector2 *v, int dim) { if (_d[dim] == 0.0) return ddgFailure; float t = (v->v[dim] - _p.v[dim])/_d[dim]; v = _p + (_d * t); return ddgSuccess; } bool intersect( ddgLine2 *l, ddgVector2 *p) { if (_d[1] == 0 ) { ddgAsserts(0,"Special case"); } if (_d[1] == l->d()[1] && _d[0] == l->d()[0]) { return ddgFailure; // Parallel lines. } float x = (_d[0]*_p[0] - l->d()[0]*l->p()[0]+_d[1]*+_p[1]- l->d()[1]*l->p()[1])*(l->d()[1]*_d[1]); x /= (_d[1]*_d[0] - l->d()[1]*l->d()[0]); float y = (_d[1]*_p[1]+_d[0]*_p[0]-_d[0]*x ) / _d[1]; p->set(x,y); return ddgSuccess; } }; class ddgLine3 { ddgVector3 _p; ddgVector3 _d; public: ddgLine3( ddgVector3 p1, ddgVector3 p2 ) { _p.set(p1); _d.set(p2-p1); _d.normalize(); } ddgVector3 p(void) { return _p; } ddgVector3 d(void) { return _d; } inline bool solve( ddgVector3 *v, int dim) { if (_d[dim] == 0.0) return ddgFailure; float n = (v->v[dim] - _p.v[dim])/_d[dim]; v = _p + (n * _d); return ddgSuccess; } ddgVector3 intersect( ddgLine3 *l) { ddgVector3 p; return p; } bool intersect( ddgLine3 *l, ddgVector3 *p) { // $TODO this function is simply wrong... if (_d[1] == 0 ) { ddgAsserts(0,"Special case"); } if (_d[1] == l->d()[1] && _d[0] == l->d()[0]) { return ddgFailure; // Parallel lines. } float x = (_d[0]*_p[0] - l->d()[0]*l->p()[0]+_d[1]*+_p[1]- l->d()[1]*l->p()[1])*(l->d()[1]*_d[1]); x /= (_d[1]*_d[0] - l->d()[1]*l->d()[0]); float y = (_d[1]*_p[1]+_d[0]*_p[0]-_d[0]*x ) / _d[1]; // Dirty hack. p->set(x,y,p->v[2]); return ddgSuccess; } }; #endif