Nori

include/nori/frame.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(__FRAME_H)
00020 #define __FRAME_H
00021 
00022 #include <nori/vector.h>
00023 
00024 NORI_NAMESPACE_BEGIN
00025 
00026 /**
00027  * \brief Stores a three-dimensional orthonormal coordinate frame
00028  *
00029  * This class is mostly used to quickly convert between different
00030  * cartesian coordinate systems and to efficiently compute certain
00031  * quantities (e.g. \ref cosTheta(), \ref tanTheta, ..).
00032  */
00033 struct Frame {
00034         Vector3f s, t;
00035         Normal3f n;
00036 
00037         /// Default constructor -- performs no initialization!
00038         inline Frame() { }
00039 
00040         /// Given a normal and tangent vectors, construct a new coordinate frame
00041         inline Frame(const Vector3f &s, const Vector3f &t, const Normal3f &n)
00042          : s(s), t(t), n(n) { }
00043 
00044         /// Construct a frame from the given orthonormal vectors
00045         inline Frame(const Vector3f &x, const Vector3f &y, const Vector3f &z)
00046          : s(x), t(y), n(z) { }
00047 
00048         /// Construct a new coordinate frame from a single vector
00049         inline Frame(const Vector3f &n) : n(n) {
00050                 coordinateSystem(n, s, t);
00051         }
00052 
00053         /// Convert from world coordinates to local coordinates
00054         inline Vector3f toLocal(const Vector3f &v) const {
00055                 return Vector3f(
00056                         v.dot(s), v.dot(t), v.dot(n)
00057                 );
00058         }
00059 
00060         /// Convert from local coordinates to world coordinates
00061         inline Vector3f toWorld(const Vector3f &v) const {
00062                 return s * v.x() + t * v.y() + n * v.z();
00063         }
00064 
00065         /** \brief Assuming that the given direction is in the local coordinate 
00066          * system, return the cosine of the angle between the normal and v */
00067         inline static float cosTheta(const Vector3f &v) {
00068                 return v.z();
00069         }
00070 
00071         /** \brief Assuming that the given direction is in the local coordinate
00072          * system, return the sine of the angle between the normal and v */
00073         inline static float sinTheta(const Vector3f &v) {
00074                 float temp = sinTheta2(v);
00075                 if (temp <= 0.0f)
00076                         return 0.0f;
00077                 return std::sqrt(temp);
00078         }
00079 
00080         /** \brief Assuming that the given direction is in the local coordinate
00081          * system, return the tangent of the angle between the normal and v */
00082         inline static float tanTheta(const Vector3f &v) {
00083                 float temp = 1 - v.z()*v.z();
00084                 if (temp <= 0.0f)
00085                         return 0.0f;
00086                 return std::sqrt(temp) / v.z();
00087         }
00088 
00089         /** \brief Assuming that the given direction is in the local coordinate
00090          * system, return the squared sine of the angle between the normal and v */
00091         inline static float sinTheta2(const Vector3f &v) {
00092                 return 1.0f - v.z() * v.z();
00093         }
00094 
00095         /** \brief Assuming that the given direction is in the local coordinate 
00096          * system, return the sine of the phi parameter in spherical coordinates */
00097         inline static float sinPhi(const Vector3f &v) {
00098                 float sinTheta = Frame::sinTheta(v);
00099                 if (sinTheta == 0.0f)
00100                         return 1.0f;
00101                 return clamp(v.y() / sinTheta, -1.0f, 1.0f);
00102         }
00103 
00104         /** \brief Assuming that the given direction is in the local coordinate 
00105          * system, return the cosine of the phi parameter in spherical coordinates */
00106         inline static float cosPhi(const Vector3f &v) {
00107                 float sinTheta = Frame::sinTheta(v);
00108                 if (sinTheta == 0.0f)
00109                         return 1.0f;
00110                 return clamp(v.x() / sinTheta, -1.0f, 1.0f);
00111         }
00112 
00113         /** \brief Assuming that the given direction is in the local coordinate
00114          * system, return the squared sine of the phi parameter in  spherical
00115          * coordinates */
00116         inline static float sinPhi2(const Vector3f &v) {
00117                 return clamp(v.y() * v.y() / sinTheta2(v), 0.0f, 1.0f);
00118         }
00119 
00120         /** \brief Assuming that the given direction is in the local coordinate
00121          * system, return the squared cosine of the phi parameter in  spherical
00122          * coordinates */
00123         inline static float cosPhi2(const Vector3f &v) {
00124                 return clamp(v.x() * v.x() / sinTheta2(v), 0.0f, 1.0f);
00125         }
00126 
00127         /// Equality test
00128         inline bool operator==(const Frame &frame) const {
00129                 return frame.s == s && frame.t == t && frame.n == n;
00130         }
00131 
00132         /// Inequality test
00133         inline bool operator!=(const Frame &frame) const {
00134                 return !operator==(frame);
00135         }
00136 
00137         /// Return a human-readable string summary of this frame
00138         inline QString toString() const {
00139                 return QString(
00140                                 "Frame[\n"
00141                                 "  s = %1,\n"
00142                                 "  t = %2,\n"
00143                                 "  n = %3\n"
00144                                 "]")
00145                         .arg(s.toString()).arg(t.toString()).arg(n.toString());
00146         }
00147 };
00148 
00149 NORI_NAMESPACE_END
00150 
00151 #endif /* __FRAME_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines