Commit 06e4aca5 by Kenneth Vanhoey

add localFrame compression support

parent 98f4c489
 /******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 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 Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: http://cgogn.u-strasbg.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ #ifndef LOCALFRAME_H_ #define LOCALFRAME_H_ namespace CGoGN { namespace Utils { /** * Class for representing a direct local frame composed of 3 orthonormal vectors T (tangent), B (bitangent) and N (normal). * This class can compress/decompress a local frame, switching from its explicit representation (3 vectors) to its compressed representation (1 vector). * Usage : * VEC3 T,B,N ; // current set of orthonormal vectors composing the direct frame. * LocalFrame lf(T,B,N) ; // Constructor from explicit expression. * if (lf.isOrthoNormalDirect()) // test if the frame is Orthogonal, Normalized and Direct * VEC3 compressed = lf.getCompressed() ; // Extract compressed frame * LocalFrame decompressed(compressed) ; // Constructor from implicit (compressed) expression. * * All formulae were provided by "Représentation compacte d'un repère local", june 14th, 2011 by K. Vanhoey */ template class LocalFrame { typedef typename PFP::REAL REAL ; typedef typename PFP::VEC2 VEC2 ; typedef typename PFP::VEC3 VEC3 ; private: // fields /** * The three explicit vectors */ VEC3 m_T,m_B,m_N ; public: // methods /** * Constructor from explicit data * @param T the tangent vector * @param B the bitangent vector * @param N the normal vector */ LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) ; /** * Constructor from implicit (compressed representation) * @param compressedFrame an implicit (compressed) version of the local frame */ LocalFrame(const VEC3& compressedFrame) ; ~LocalFrame() {} ; /** * Returns a compressed version of the current local frame */ VEC3 getCompressed() ; /** * Tests if the frame is direct * @return true if the frame is direct */ bool isDirect() ; /** * Tests if the frame is orthogonal * @return true if the frame is orthogonal */ bool isOrthogonal() ; /** * Tests if the frame is normalized * @return true if the frame is normalized */ bool isNormalized() ; /** * Tests if the frame is direct, normalized and orthogonal * @return true if the frame is direct, normalized and orthogonal */ bool isOrthoNormalDirect() ; /** * @return current tangent vector */ VEC3& getT() { return m_T ; } const VEC3& getT() const { return m_T ; } /** * @return current bitangent vector */ VEC3& getB() { return m_B ; } const VEC3& getB() const { return m_B ; } /** * @return current normal vector */ VEC3& getN() { return m_N ; } const VEC3& getN() const { return m_N ; } friend std::ostream& operator<< (std::ostream &out, const LocalFrame& lf) { out << "T : " << lf.m_T << std::endl ; out << "B : " << lf.m_B << std::endl ; out << "N : " << lf.m_N << std::endl ; return out ; } ; private : // methods VEC2 carthToSpherical(const VEC3& carth) const ; VEC3 sphericalToCarth(const VEC2& sph) const ; } ; } // Utils } // CGoGN #include "localFrame.hpp" #endif /* LOCALFRAME_H_ */
 /******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 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 Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: http://cgogn.u-strasbg.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ namespace CGoGN { namespace Utils { template LocalFrame::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) { m_T = T ; m_B = B ; m_N = N ; } template LocalFrame::LocalFrame(const VEC3& compressedFrame) { VEC2 Nspher ; VEC2 Tspher ; REAL& thetaN = Nspher[0] ; // known REAL& phiN = Nspher[1] ; // known REAL& thetaT = Tspher[0] ; // known REAL& phiT = Tspher[1] ; // to be decoded // compute phiT REAL Den,Nom ; Den = sin(phiN)*(cos(thetaN)*cos(thetaT) + sin(thetaN)*sin(thetaT)) ; // Based on orthogonality Nom = cos(phiN) ; phiT = -atan(Nom/Den) ; // if A==0, atan returns Pi/2 if (phiT < 0.0) phiT = M_PI + phiT ; // = Pi - |phiT| // convert to carthesian m_N = sphericalToCarth(Nspher) ; m_T = sphericalToCarth(Tspher) ; // compute B m_B = m_N ^ m_T ; } template typename PFP::VEC3 LocalFrame::getCompressed() { VEC3 res ; REAL& thetaN = res[0] ; REAL& phiN = res[1] ; REAL& thetaT = res[2] ; // convert to spherical coordinates VEC2 Nspher = carthToSpherical(m_N) ; VEC2 Tspher = carthToSpherical(m_T) ; // extract the three scalars thetaN = Nspher[0] ; phiN = Nspher[1] ; thetaT = Tspher[0] ; return res ; } template bool LocalFrame::isDirect() { VEC3 new_B = m_N ^ m_T ; // direct VEC3 diffs = new_B - m_B ; // differences with existing B REAL diffNorm = diffs.norm2() ; // Norm of this differences vector return (diffNorm < 1e-10) ; // Verify that this difference is very small } template bool LocalFrame::isOrthogonal() { return (abs(m_T * m_B) < 1e-10) && (abs(m_N * m_B) < 1e-10) && (abs(m_T * m_N) < 1e-10) ; } template bool LocalFrame::isNormalized() { return (1-1e-10 < m_N.norm2() && m_N.norm2() < 1+1e-10) && (1-1e-10 < m_T.norm2() && m_T.norm2() < 1+1e-10) && (1-1e-10 < m_B.norm2() && m_B.norm2() < 1+1e-10) ; } template bool LocalFrame::isOrthoNormalDirect() { return isOrthogonal() && isNormalized() && isDirect() ; } template typename PFP::VEC2 LocalFrame::carthToSpherical (const VEC3& carth) const { VEC2 res ; const REAL& x = carth[0] ; const REAL& y = carth[1] ; const REAL& z = carth[2] ; REAL& theta = res[0] ; REAL& phi = res[1] ; phi = acos(z) ; const REAL sinphi = sin(phi) ; if (sinphi == 0.0) theta = 0.0 ; else theta = ((y > 0) ? 1 : -1) * acos(std::min(REAL(1.0),std::max(REAL(-1.0),x / sinphi))) ; assert (-(M_PI+0.000001) <= theta && theta <= M_PI+0.000001) ; assert (-0.000001 < phi && phi <= M_PI+0.000001) ; assert (!isnan(theta) || !"carthToSpherical : Theta is NaN !") ; assert (!isnan(phi) || !"carthToSpherical : Phi is NaN !") ; return res ; } template typename PFP::VEC3 LocalFrame::sphericalToCarth (const VEC2& sph) const { VEC3 res ; const REAL& theta = sph[0] ; const REAL& phi = sph[1] ; REAL& x = res[0] ; REAL& y = res[1] ; REAL& z = res[2] ; x = cos(theta)*sin(phi) ; y = sin(theta)*sin(phi) ; z = cos(phi) ; assert(-1.000001 < x && x < 1.000001) ; assert(-1.000001 < y && y < 1.000001) ; assert(-1.000001 < z && z < 1.000001) ; return res ; } } // Utils } // CGoGN
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment