00001 /*************************************************************************** 00002 * Copyright (C) 2004 by Jacques Gasselin * 00003 * jacquesgasselin@hotmail.com * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU Library General Public License as * 00007 * published by the Free Software Foundation; either version 2 of the * 00008 * License, or (at your option) any later version. * 00009 * * 00010 * This program is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00013 * GNU General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU Library General Public * 00016 * License along with this program; if not, write to the * 00017 * Free Software Foundation, Inc., * 00018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00019 ***************************************************************************/ 00020 00021 00022 #ifndef GLPLANE_H 00023 #define GLPLANE_H 00024 00025 00026 #include "GLVector.h" 00027 00028 00034 namespace mathglpp 00035 { 00036 00037 template <typename T> 00038 class GLPlane 00039 { 00040 public: 00042 typedef GLVector3<T> vector_type; 00043 00045 GLPlane() 00046 :normal(T(0)),D(T(0)) 00047 {} 00048 00050 GLPlane(const vector_type& n, const vector_type& op) 00051 :normal(n), D(-(n.dot(op))) {} 00052 00054 GLPlane(const vector_type& op1, const vector_type& op2, const vector_type& op3) 00055 { normal = (op3 - op2).getCross( (op1 - op2) ); normal.normalize(); D = -(normal.dot(op1)); } 00056 00058 GLPlane(const GLPlane& pl): normal(pl.normal), D(pl.D) {} 00059 00061 ~GLPlane(){} 00062 00064 inline void set(const vector_type& op1, const vector_type& op2, const vector_type& op3) 00065 { normal = (op3 - op2).getCross( (op1 - op2) ); normal.normalize(); D = -(normal.dot(op1)); } 00066 00068 inline const vector_type& getNormal(void) const 00069 { return normal; } 00070 00072 inline void setNormal(const vector_type& n) 00073 { normal = n; } 00074 00076 inline const T& getD(void) const 00077 { return D; } 00078 00080 inline void setD(const T& d) 00081 { D = d; } 00082 00084 inline T distanceToPoint(const vector_type& p) const 00085 { return (normal.dot(p) + D); } 00086 00089 inline T intersectionWithLine(const vector_type& dir, const vector_type& origin) const 00090 { return - (normal.dot(origin) + D) / normal.dot(dir); } 00091 00093 inline vector_type reflectedVector(const vector_type& in) const 00094 { return in - (normal*(distanceToPoint(in))*2); } 00095 00097 inline GLMatrix<T> reflectionMatrix() 00098 { 00099 GLMatrix<T> ret; 00100 00101 ret[0] = 1 - 2*(normal.x*normal.x); 00102 ret[4] = - 2*(normal.x*normal.y); 00103 ret[8] = - 2*(normal.x*normal.z); 00104 ret[12] = -2*normal.x*D; 00105 00106 ret[1] = - 2*(normal.y*normal.x); 00107 ret[5] = 1 - 2*(normal.y*normal.y); 00108 ret[9] = - 2*(normal.y*normal.z); 00109 ret[13] = -2*normal.y*D; 00110 00111 ret[2] = - 2*(normal.z*normal.x); 00112 ret[6] = - 2*(normal.z*normal.y); 00113 ret[10] = 1 - 2*(normal.z*normal.z); 00114 ret[14] = -2*normal.z*D; 00115 00116 ret[3] = 0; 00117 ret[7] = 0; 00118 ret[11] = 0; 00119 ret[15] = 1; 00120 00121 return ret; 00122 } 00123 00125 inline GLMatrix<T> directionalProjectionMatrix(const vector_type& dir) 00126 { 00127 GLMatrix<T> ret; 00128 00129 ret[0] = 1+1*(dir.x*normal.x); 00130 ret[4] = 1*(dir.x*normal.y); 00131 ret[8] = 1*(dir.x*normal.z); 00132 ret[12] = 1*dir.x*D; 00133 00134 ret[1] = 1*(dir.y*normal.x); 00135 ret[5] = 1+1*(dir.y*normal.y); 00136 ret[9] = 1*(dir.y*normal.z); 00137 ret[13] = 1*dir.y*D; 00138 00139 ret[2] = 1*(dir.z*normal.x); 00140 ret[6] = 1*(dir.z*normal.y); 00141 ret[10] =1+1*(dir.z*normal.z); 00142 ret[14] = 1*dir.z*D; 00143 00144 ret[3] = 0; 00145 ret[7] = 0; 00146 ret[11] = 0; 00147 ret[15] = 1; 00148 00149 return ret; 00150 } 00151 00153 inline GLMatrix<T> pointProjectionMatrix(const vector_type& l) 00154 { 00155 GLMatrix<T> ret; 00156 00157 T d = -l.dot(normal); 00158 T c = D - d; 00159 00160 ret[0] = -l.x*normal.x + c; 00161 ret[4] = -l.x*normal.y; 00162 ret[8] = -l.x*normal.z; 00163 ret[12]= -c*l.x - d*l.x; 00164 00165 ret[1] = -l.y*normal.x; 00166 ret[5] = -l.y*normal.y + c; 00167 ret[9] = -l.y*normal.z; 00168 ret[13]= -c*l.y - d*l.y; 00169 00170 ret[2] = -l.z*normal.x; 00171 ret[6] = -l.z*normal.y; 00172 ret[10] = -l.z*normal.z + c; 00173 ret[14]= -c*l.z - d*l.z; 00174 00175 ret[3] = -normal.x; 00176 ret[7] = -normal.y; 00177 ret[11] = -normal.z; 00178 ret[15]= -d; 00179 00180 return ret; 00181 } 00182 00183 private: 00184 00186 vector_type normal; 00188 T D; 00189 }; 00190 00191 00193 typedef GLPlane<GLbyte> GLPlaneb; 00195 typedef GLPlane<GLshort> GLPlanes; 00197 typedef GLPlane<GLint> GLPlanei; 00199 typedef GLPlane<GLfloat> GLPlanef; 00201 typedef GLPlane<GLdouble> GLPlaned; 00202 00203 00204 }; 00205 #endif