Nori

include/nori/vector.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Nori, a simple educational ray tracer
00003 
00004     Copyright (c) 2012 by Wenzel Jakob and Steve Marschner.
00005 
00006     Nori is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License Version 3
00008     as published by the Free Software Foundation.
00009 
00010     Nori 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 General Public License
00016     along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #if !defined(__VECTOR_H)
00020 #define __VECTOR_H
00021 
00022 #include <nori/common.h>
00023 
00024 NORI_NAMESPACE_BEGIN
00025 
00026 /* ===================================================================
00027     This file contains a few templates and specializations that
00028     provide 2/3D points, vectors, and normals over different
00029     underlying data types. Points, vectors, and normals are distinct
00030     in Nori, because they transform differently under homogeneous
00031     coordinate transformations.
00032  * =================================================================== */
00033 
00034 /**
00035  * \brief Generic N-dimensional vector data structure based on Eigen::Matrix
00036  */
00037 template <typename _Scalar, int _Dimension> struct TVector : public Eigen::Matrix<_Scalar, _Dimension, 1> {
00038 public:
00039         enum {
00040                 Dimension = _Dimension
00041         };
00042 
00043         typedef _Scalar                             Scalar;
00044         typedef Eigen::Matrix<Scalar, Dimension, 1> Base;
00045         typedef TVector<Scalar, Dimension>          VectorType;
00046         typedef TPoint<Scalar, Dimension>           PointType;
00047 
00048         /// Create a new vector with constant component vlaues
00049         inline TVector(Scalar value = (Scalar) 0) { setConstant(value); }
00050 
00051         /// Create a new 2D vector (type error if \c Dimension != 2)
00052         inline TVector(Scalar x, Scalar y) : Base(x, y) { }
00053         
00054         /// Create a new 3D vector (type error if \c Dimension != 3)
00055         inline TVector(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { }
00056 
00057         /// Create a new 4D vector (type error if \c Dimension != 4)
00058         inline TVector(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { }
00059 
00060         /// Construct a vector from MatrixBase (needed to play nice with Eigen)
00061         template <typename Derived> inline TVector(const Eigen::MatrixBase<Derived>& p) 
00062                 : Base(p) { }
00063 
00064         /// Assign a vector from MatrixBase (needed to play nice with Eigen)
00065     template <typename Derived> TVector &operator=(const Eigen::MatrixBase<Derived>& p) {
00066                 this->Base::operator=(p);
00067                 return *this;
00068     }
00069 
00070         /// Return a human-readable string summary
00071         inline QString toString() const {
00072                 QString result;
00073                 for (size_t i=0; i<Dimension; ++i) {
00074                         result += QString("%1").arg(this->coeff(i));
00075                         if (i+1 < Dimension)
00076                                 result += ", ";
00077                 }
00078                 return "[" + result + "]";
00079         }
00080 };
00081 
00082 /**
00083  * \brief Generic N-dimensional point data structure based on Eigen::Matrix
00084  */
00085 template <typename _Scalar, int _Dimension> struct TPoint : public Eigen::Matrix<_Scalar, _Dimension, 1> {
00086 public:
00087         enum {
00088                 Dimension = _Dimension
00089         };
00090 
00091         typedef _Scalar                             Scalar;
00092         typedef Eigen::Matrix<Scalar, Dimension, 1> Base;
00093         typedef TVector<Scalar, Dimension>          VectorType;
00094         typedef TPoint<Scalar, Dimension>           PointType;
00095 
00096         /// Create a new point with constant component vlaues
00097         inline TPoint(Scalar value = (Scalar) 0) { setConstant(value); }
00098 
00099         /// Create a new 2D point (type error if \c Dimension != 2)
00100         inline TPoint(Scalar x, Scalar y) : Base(x, y) { }
00101         
00102         /// Create a new 3D point (type error if \c Dimension != 3)
00103         inline TPoint(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { }
00104 
00105         /// Create a new 4D point (type error if \c Dimension != 4)
00106         inline TPoint(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { }
00107 
00108         /// Construct a point from MatrixBase (needed to play nice with Eigen)
00109         template <typename Derived> inline TPoint(const Eigen::MatrixBase<Derived>& p) 
00110                 : Base(p) { }
00111 
00112         /// Assign a point from MatrixBase (needed to play nice with Eigen)
00113     template <typename Derived> TPoint &operator=(const Eigen::MatrixBase<Derived>& p) {
00114                 this->Base::operator=(p);
00115                 return *this;
00116     }
00117 
00118         /// Return a human-readable string summary
00119         inline QString toString() const {
00120                 QString result;
00121                 for (size_t i=0; i<Dimension; ++i) {
00122                         result += QString("%1").arg(this->coeff(i));
00123                         if (i+1 < Dimension)
00124                                 result += ", ";
00125                 }
00126                 return "[" + result + "]";
00127         }
00128 };
00129 
00130 /**
00131  * \brief 3-dimensional surface normal representation
00132  */
00133 struct Normal3f : public Eigen::Matrix<float, 3, 1> {
00134 public:
00135         enum {
00136                 Dimension = 3
00137         };
00138 
00139         typedef float                               Scalar;
00140         typedef Eigen::Matrix<Scalar, Dimension, 1> Base;
00141         typedef TVector<Scalar, Dimension>          VectorType;
00142         typedef TPoint<Scalar, Dimension>           PointType;
00143 
00144 
00145         /// Create a new normal with constant component vlaues
00146         inline Normal3f(Scalar value = 0.0f) { setConstant(value); }
00147 
00148         /// Create a new 3D normal 
00149         inline Normal3f(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { }
00150 
00151         /// Construct a normal from MatrixBase (needed to play nice with Eigen)
00152         template <typename Derived> inline Normal3f(const Eigen::MatrixBase<Derived>& p) 
00153                 : Base(p) { }
00154 
00155         /// Assign a normal from MatrixBase (needed to play nice with Eigen)
00156     template <typename Derived> Normal3f &operator=(const Eigen::MatrixBase<Derived>& p) {
00157                 this->Base::operator=(p);
00158                 return *this;
00159     }
00160 
00161         /// Return a human-readable string summary
00162         inline QString toString() const {
00163                 return QString("[%1, %2, %3]").arg(coeff(0)).arg(coeff(1)).arg(coeff(2));
00164         }
00165 };
00166 
00167 /// Complete the set {a} to an orthonormal base
00168 extern void coordinateSystem(const Vector3f &a, Vector3f &b, Vector3f &c);
00169 
00170 NORI_NAMESPACE_END
00171 
00172 #endif /* __VECTOR_H */
00173 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines