Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vppoint4d.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 // ChangeLog
00006 // Apr 29, 2005 - Bruno de Oliveira Schneider
00007 // - Changed "AngleTo" - it was still returning "NaN".
00008 // Apr 14, 2005 - Bruno de Oliveira Schneider
00009 // - Changed "AngleTo" - it was returning "NaN" because of floating point errors.
00010 //   This used to make the scene disappear from the viewer when rotating the camera.
00011 // Nov 24, 2004 - Bruno de Oliveira Schneider
00012 // - Added configurable order comparison methods: operator<, XThenZLess and
00013 //   LexicographicalLess.
00014 // Sep 28, 2004 - Bruno de Oliveira Schneider
00015 // - File was created from the translation to english of an old class of mine.
00016 // - Added cast constructors and some implementations of "operator=" to easily
00017 //   blend into VPAT.
00018 
00019 // FixMe: Some comments still need to be translated to english.
00020 
00021 #include "vppoint4d.h"
00022 
00023 using namespace std;
00024 
00025 // Default "less then" comparison uses "LexicographicalLess".
00026 VPPoint4D::tCompareOper VPPoint4D::operatorLess = &VPPoint4D::LexicographicalLess;
00027 
00028 VPPoint4D::VPPoint4D()
00029 {
00030     vetCoord[0]=vetCoord[1]=vetCoord[2]=0;
00031     vetCoord[3]=1;
00032 }
00033 
00034 VPPoint4D::VPPoint4D(const VPPoint4D &point)
00035 {
00036     vetCoord[0] = point.vetCoord[0];
00037     vetCoord[1] = point.vetCoord[1];
00038     vetCoord[2] = point.vetCoord[2];
00039     vetCoord[3] = point.vetCoord[3];
00040 }
00041 
00042 VPPoint4D::VPPoint4D(const VPVertex3D& v)
00043 {
00044     vetCoord[0] = v.vpGetX();
00045     vetCoord[1] = v.vpGetY();
00046     vetCoord[2] = v.vpGetZ();
00047     vetCoord[3] = 1;
00048 }
00049 
00050 VPPoint4D::VPPoint4D(const VPPoint3D& p)
00051 {
00052     vetCoord[0] = p.vpGetX();
00053     vetCoord[1] = p.vpGetY();
00054     vetCoord[2] = p.vpGetZ();
00055     vetCoord[3] = 1;
00056 }
00057 
00058 VPPoint4D::VPPoint4D(const VPVector3D& v)
00059 {
00060     vetCoord[0] = v.vpGetX();
00061     vetCoord[1] = v.vpGetY();
00062     vetCoord[2] = v.vpGetZ();
00063     vetCoord[3] = 0;
00064 }
00065 
00066 VPPoint4D::VPPoint4D(double x, double y, double z, double w)
00067 // w = 1 (point) by default (see constructor signature)
00068 {
00069     SetXYZW(x, y, z, w);
00070 }
00071 
00072 const VPPoint4D& VPPoint4D::X()
00073 {
00074     static const VPPoint4D x(1.0,0.0,0.0,0.0);
00075     return x;
00076 }
00077 
00078 const VPPoint4D& VPPoint4D::Y()
00079 {
00080     static const VPPoint4D y(0.0,1.0,0.0,0.0);
00081     return y;
00082 }
00083 
00084 const VPPoint4D& VPPoint4D::Z()
00085 {
00086     static const VPPoint4D z(0.0,0.0,1.0,0.0);
00087     return z;
00088 }
00089 
00090 const VPPoint4D& VPPoint4D::DOWN()
00091 {
00092     static const VPPoint4D down(0.0,-1.0,0.0,0.0);
00093     return down;
00094 }
00095 
00096 const VPPoint4D& VPPoint4D::ORIGIN()
00097 {
00098     static const VPPoint4D origin(0.0,0.0,0.0,1.0);
00099     return origin;
00100 }
00101 
00102 void VPPoint4D::SetXYZW(double x, double y, double z, double w)
00103 {
00104     vetCoord[0] = x;
00105     vetCoord[1] = y;
00106     vetCoord[2] = z;
00107     vetCoord[3] = w;
00108 }
00109 
00110 void VPPoint4D::Normalize()
00111 // requires that x,y,z and w are not all zeros
00112 {
00113     if (vetCoord[3] == 0)
00114     {
00115         // vector normalization
00116         double norma = Length();
00117 
00118         vetCoord[0] /= norma;
00119         vetCoord[1] /= norma;
00120         vetCoord[2] /= norma;
00121         vetCoord[3] = 0; // this seems to avoid some round off erros
00122     }
00123     else
00124     {
00125         // point normalization
00126         vetCoord[0] /= vetCoord[3];
00127         vetCoord[1] /= vetCoord[3];
00128         vetCoord[2] /= vetCoord[3];
00129         vetCoord[3] = 1;
00130     }
00131 }
00132 
00133 double VPPoint4D::Length() const
00134 {
00135     return sqrt(vetCoord[0]*vetCoord[0] + vetCoord[1]*vetCoord[1] + vetCoord[2]*vetCoord[2]);
00136 }
00137 
00138 double VPPoint4D::DotProduct(const VPPoint4D& p) const
00139 {
00140     return vetCoord[0]*p.vetCoord[0]+vetCoord[1]*p.vetCoord[1]+vetCoord[2]*p.vetCoord[2];
00141 }
00142 
00143 VPPoint4D VPPoint4D::CrossProduct(const VPPoint4D& p) const
00144 {
00145     return VPPoint4D(GetY()*p.GetZ()-GetZ()*p.GetY(), GetZ()*p.GetX()-GetX()*p.GetZ(), GetX()*p.GetY()-GetY()*p.GetX(), 0);
00146 }
00147 
00148 double VPPoint4D::AngleTo(const VPPoint4D& p) const
00149 // Note: This method requires both vectors to be normalized!
00150 {
00151     double dp = DotProduct(p);
00152     // Sometimes, the Dot Product is greater then 1 due to floating point errors.
00153     if (dp > 1.0)
00154         return 0;
00155     else
00156     {
00157         if (dp < -1.0)
00158             return 3.1415926535897932384626433832795;
00159         return acos(dp);
00160     }
00161 }
00162 
00163 VPPoint4D VPPoint4D::operator-() const
00164 {
00165     // To keep the nature of the point it seems to me that the w coordinate should
00166     // not be touched.
00167     return VPPoint4D(-vetCoord[0], -vetCoord[1], -vetCoord[2], vetCoord[3]);
00168 }
00169 
00170 VPPoint4D VPPoint4D::operator-(const VPPoint4D& point) const
00171 {
00172     return VPPoint4D(vetCoord[0]-point.vetCoord[0],
00173                      vetCoord[1]-point.vetCoord[1],
00174                      vetCoord[2]-point.vetCoord[2],
00175                      vetCoord[3]-point.vetCoord[3]);
00176 }
00177 
00178 VPPoint4D VPPoint4D::operator+(const VPPoint4D& vector) const
00179 // A principio este operador nao deveria somar ponto com ponto. Entretanto, a soma
00180 // de vetor - criado pela diferenca de pontos nao normalizados - com um ponto nao
00181 // e' detectavel pela coordenada W e pode ser usado no algoritmo de recorte.
00182 {
00183     return VPPoint4D(vetCoord[0]+vector.vetCoord[0],
00184                      vetCoord[1]+vector.vetCoord[1],
00185                      vetCoord[2]+vector.vetCoord[2],
00186                      vetCoord[3]+vector.vetCoord[3]);
00187 }
00188 
00189 void VPPoint4D::operator+=(const VPPoint4D& vector)
00190 // requer normalizacao do ponto sendo alterado
00191 {
00192     vetCoord[0] += vector.vetCoord[0];
00193     vetCoord[1] += vector.vetCoord[1];
00194     vetCoord[2] += vector.vetCoord[2];
00195 }
00196 
00197 VPPoint4D VPPoint4D::operator*(double escalar) const
00198 {
00199     return VPPoint4D(vetCoord[0]*escalar,
00200                      vetCoord[1]*escalar,
00201                      vetCoord[2]*escalar,
00202                      vetCoord[3]*escalar);
00203 }
00204 
00205 void VPPoint4D::operator*=(double escalar)
00206 {
00207     vetCoord[0]*=escalar;
00208     vetCoord[1]*=escalar;
00209     vetCoord[2]*=escalar;
00210     vetCoord[3]*=escalar;
00211 }
00212 
00213 bool VPPoint4D::operator==(const VPPoint4D& point) const
00214 {
00215     return (vetCoord[0] == point.vetCoord[0]) &&
00216            (vetCoord[1] == point.vetCoord[1]) &&
00217            (vetCoord[2] == point.vetCoord[2]) &&
00218            (vetCoord[3] == point.vetCoord[3]);
00219 }
00220 
00221 bool VPPoint4D::operator<(const VPPoint4D& p) const
00222 {
00223     return (this->*operatorLess)(p);
00224 }
00225 
00226 bool VPPoint4D::operator!=(const VPPoint4D& point) const
00227 {
00228     return (vetCoord[0] != point.vetCoord[0]) ||
00229            (vetCoord[1] != point.vetCoord[1]) ||
00230            (vetCoord[2] != point.vetCoord[2]) ||
00231            (vetCoord[3] != point.vetCoord[3]);
00232 }
00233 
00234 void VPPoint4D::operator=(const VPPoint4D& point)
00235 {
00236     vetCoord[0] = point.vetCoord[0];
00237     vetCoord[1] = point.vetCoord[1];
00238     vetCoord[2] = point.vetCoord[2];
00239     vetCoord[3] = point.vetCoord[3];
00240 }
00241 
00242 void VPPoint4D::operator=(const VPPoint3D& p)
00243 {
00244     vetCoord[0] = p.vpGetX();
00245     vetCoord[1] = p.vpGetY();
00246     vetCoord[2] = p.vpGetZ();
00247     vetCoord[3] = 1;
00248 }
00249 
00250 void VPPoint4D::operator=(const VPVertex3D& v)
00251 {
00252     vetCoord[0] = v.vpGetX();
00253     vetCoord[1] = v.vpGetY();
00254     vetCoord[2] = v.vpGetZ();
00255     vetCoord[3] = 1;
00256 }
00257 
00258 void VPPoint4D::operator=(const VPVector3D& v)
00259 {
00260     vetCoord[0] = v.vpGetX();
00261     vetCoord[1] = v.vpGetY();
00262     vetCoord[2] = v.vpGetZ();
00263     vetCoord[3] = 0;
00264 }
00265 
00266 bool VPPoint4D::LexicographicalLess(const VPPoint4D& p) const
00267 {
00268     if (vetCoord[0] == p.vetCoord[0])
00269     {
00270         if (vetCoord[1] == p.vetCoord[1])
00271         {
00272             if (vetCoord[2] == p.vetCoord[2])
00273                 return vetCoord[3] < p.vetCoord[3];
00274             else
00275                 return vetCoord[2] < p.vetCoord[2];
00276         }
00277         else
00278             return vetCoord[1] < p.vetCoord[1];
00279     }
00280     else
00281         return vetCoord[0] < p.vetCoord[0];
00282 }
00283 
00284 bool VPPoint4D::XThenZLess(const VPPoint4D& p) const
00285 {
00286     if (vetCoord[0] == p.vetCoord[0])
00287         return vetCoord[2] < p.vetCoord[2];
00288     else
00289         return vetCoord[0] < p.vetCoord[0];
00290 }
00291 
00292 ostream& operator<<(ostream& output, const VPPoint4D& p)
00293 {
00294     output.setf(ios::fixed);
00295     output.precision(5);
00296     output << "(" << p.GetX() << "," << p.GetY() << "," << p.GetZ() << ","
00297            << p.GetW() << ")";
00298     output.unsetf(ios::fixed);
00299     return output;
00300 }

Generated on Tue Sep 6 10:00:05 2005 for VPAT by  doxygen 1.4.4