Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

Commit 0e79b446 by Kenneth Vanhoey

### localFrame update : compression with only 3 scalars works fine

parent 2545895b
 ... ... @@ -31,6 +31,33 @@ namespace CGoGN { namespace Utils { /** * Util for rotation of a 3D point (or vector) around a given line (going through the origin) and of a given angle * @param axis the rotation axis direction * @param angle the rotation angle * @param p the point to rotate */ template Geom::Vector<3,REAL> rotate (Geom::Vector<3,REAL> axis, REAL angle, Geom::Vector<3,REAL> p) ; /** * Util for conversion from spherical to carthesian coordinates. * The spherical coordinates are in radius-longitude-latitude * @param sph the spherical coordinates * @return the carthesian coordinates */ template Geom::Vector<3,REAL> sphericalToCarth (const Geom::Vector<3,REAL>& sph) ; /** * Util for conversion from carthesian to spherical coordinates. * The spherical coordinates are in radius-longitude-latitude * @param carth the carthesian coordinates * @return the spherical coordinates */ template Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth) ; /** * 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). ... ... @@ -39,7 +66,7 @@ namespace Utils { * 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 * VEC4 compressed = lf.getCompressedSecure() ; // Extract compressed frame * 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 ... ... @@ -50,7 +77,6 @@ class LocalFrame typedef typename PFP::REAL REAL ; typedef typename Geom::Vector<2,REAL> VEC2 ; typedef typename Geom::Vector<3,REAL> VEC3 ; typedef typename Geom::Vector<4,REAL> VEC4 ; private: // fields /** ... ... @@ -69,16 +95,10 @@ public: // methods /** * Constructor from implicit (compressed representation) * @param compressedFrame an implicit (compressed) version of the local frame * @param compressedFrame an implicit (compressed) version of the local frame (can be produced by localFrame.getCompressed()) */ LocalFrame(const VEC3& compressedFrame) ; /** * Constructor from implicit (compressed representation) * @param secureCompressedFrame an implicit (compressed) version of the local frame */ LocalFrame(const VEC4& secureCompressedFrame) ; ~LocalFrame() {} ; /** ... ... @@ -87,18 +107,13 @@ public: // methods */ VEC3 getCompressed() const ; /** * Returns a compressed version of the current local frame (fully defined, no ambiguities) */ VEC4 getCompressedSecure() const ; /** * Tests if the frames are identical * @param lf the frame to compare to the current frame * @param epsilon the authorized deviation * @return true if frames are identical (or deviate less than epsilon) */ bool equals(const LocalFrame& lf, REAL epsilon = 1e-3) const ; bool equals(const LocalFrame& lf, REAL epsilon = 1e-6) const ; /** * Equality of frames ... ... @@ -118,7 +133,7 @@ public: // methods * Tests if the frame is direct * @return true if the frame is direct */ bool isDirect(REAL epsilon = 1e-5) const ; bool isDirect(REAL epsilon = 1e-7) const ; /** * Tests if the frame is orthogonal ... ... @@ -163,9 +178,10 @@ public: // methods return out ; } ; private : // methods VEC2 carthToSpherical(const VEC3& carth) const ; VEC3 sphericalToCarth(const VEC2& sph) const ; private : // private constants const VEC3 T ; const VEC3 B ; const VEC3 N ; } ; } // Utils ... ...
 ... ... @@ -28,7 +28,10 @@ namespace CGoGN { namespace Utils { template LocalFrame::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) LocalFrame::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) : T(1,0,0), // (T,B,N) can be any orthonormal direct frame B(0,1,0), // but has to be initialized exactly the same N(0,0,1) // in every constructor ! { m_T = T ; m_B = B ; ... ... @@ -36,44 +39,19 @@ LocalFrame::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) } template LocalFrame::LocalFrame(const VEC3& compressedFrame) LocalFrame::LocalFrame(const VEC3& compressedFrame) : T(1,0,0), // (T,B,N) can be any orthonormal direct frame B(0,1,0), // but has to be initialized exactly the same N(0,0,1) // in every constructor !{ { // get known data const REAL& thetaN = compressedFrame[0] ; const REAL& phiN = compressedFrame[1] ; const REAL& thetaT = compressedFrame[2] ; const REAL& theta1 = compressedFrame[0] ; const REAL& phi = compressedFrame[1] ; const REAL& theta2 = compressedFrame[2] ; // compute phiT REAL phiT = -std::atan((std::cos(thetaN)*std::cos(thetaT) + std::sin(thetaN)*std::sin(thetaT))*std::cos(phiN) / std::sin(phiN)) ; // if quot==0, atan returns Pi/2 VEC2 Nspher(thetaN,phiN) ; VEC2 Tspher(thetaT,phiT) ; // convert to carthesian m_N = sphericalToCarth(Nspher) ; m_T = sphericalToCarth(Tspher) ; // compute B m_B = m_N ^ m_T ; } template LocalFrame::LocalFrame(const VEC4& compressedFrame) { // get known data const REAL& thetaN = compressedFrame[0] ; const REAL& phiN = compressedFrame[1] ; const REAL& thetaT = compressedFrame[2] ; const REAL& phiT = compressedFrame[3] ; VEC2 Nspher(thetaN,phiN) ; VEC2 Tspher(thetaT,phiT) ; // convert to carthesian m_N = sphericalToCarth(Nspher) ; m_T = sphericalToCarth(Tspher) ; // compute B const VEC3 Tprime = rotate(N,theta1,T) ; m_N = rotate(Tprime,phi,N) ; m_T = rotate(m_N,theta2,Tprime) ; m_B = m_N ^ m_T ; } ... ... @@ -82,41 +60,16 @@ typename Geom::Vector<3,typename PFP::REAL> LocalFrame::getCompressed() con { 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 typename Geom::Vector<4,typename PFP::REAL> LocalFrame::getCompressedSecure() const { VEC4 res ; REAL& thetaN = res[0] ; REAL& phiN = res[1] ; REAL& thetaT = res[2] ; REAL& phiT = res[3] ; REAL& theta1 = res[0] ; REAL& phi = res[1] ; REAL& theta2 = res[2] ; // convert to spherical coordinates VEC2 Nspher = carthToSpherical(m_N) ; VEC2 Tspher = carthToSpherical(m_T) ; VEC3 Tprime = N ^ m_N ; Tprime.normalize() ; // extract the three scalars thetaN = Nspher[0] ; phiN = Nspher[1] ; thetaT = Tspher[0] ; phiT = Tspher[1] ; theta1 = (B*Tprime > 0 ? 1 : -1) * std::acos(std::max(std::min(REAL(1.0), T*Tprime ),REAL(-1.0))) ; phi = std::acos(std::max(std::min(REAL(1.0), N*m_N ),REAL(-1.0))) ; // phi1 is always positive because the direction of vector Tp=N^N1 (around which a rotation of angle phi is done later on) changes depending on the side on which they lay w.r.t eachother. theta2 = (m_B*Tprime > 0 ? -1 : 1) * std::acos(std::max(std::min(REAL(1.0), m_T*Tprime ),REAL(-1.0))) ; return res ; } ... ... @@ -162,9 +115,9 @@ bool LocalFrame::isOrthogonal(REAL epsilon) const template bool LocalFrame::isNormalized(REAL epsilon) const { return (1-1e-5 < m_N.norm2() && m_N.norm2() < epsilon) && (1-1e-5 < m_T.norm2() && m_T.norm2() < epsilon) && (1-1e-5 < m_B.norm2() && m_B.norm2() < epsilon) ; return (1-epsilon < m_N.norm2() && m_N.norm2() < 1+epsilon) && (1-epsilon < m_T.norm2() && m_T.norm2() < 1+epsilon) && (1-epsilon < m_B.norm2() && m_B.norm2() < 1+epsilon) ; } template ... ... @@ -173,42 +126,45 @@ bool LocalFrame::isOrthoNormalDirect(REAL epsilon) const return isOrthogonal(epsilon) && isNormalized(epsilon) && isDirect(epsilon) ; } template typename Geom::Vector<2,typename PFP::REAL> LocalFrame::carthToSpherical (const VEC3& carth) const template Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth) { VEC2 res ; Geom::Vector<3,REAL> res ; const REAL& x = carth[0] ; const REAL& y = carth[1] ; const REAL& z = carth[2] ; REAL theta = ((y < 0) ? -1 : 1) * std::acos(x / REAL(sqrt(x*x + y*y)) ) ; REAL& rho = res[0] ; REAL& theta = res[1] ; REAL& phi = res[2] ; rho = carth.norm() ; theta = ((y < 0) ? -1 : 1) * std::acos(x / REAL(sqrt(x*x + y*y)) ) ; if (isnan(theta)) theta = 0.0 ; REAL phi = std::asin(z) ; res[0] = theta ; res[1] = phi ; phi = std::asin(z) ; return res ; } template typename Geom::Vector<3,typename PFP::REAL> LocalFrame::sphericalToCarth (const VEC2& sph) const template Geom::Vector<3,REAL> sphericalToCarth (const Geom::Vector<3,REAL>& sph) { VEC3 res ; Geom::Vector<3,REAL> res ; const REAL& theta = sph[0] ; const REAL& phi = sph[1] ; const REAL& rho = sph[0] ; const REAL& theta = sph[1] ; const REAL& phi = sph[2] ; REAL& x = res[0] ; REAL& y = res[1] ; REAL& z = res[2] ; x = cos(theta)*cos(phi) ; y = sin(theta)*cos(phi) ; z = sin(phi) ; x = rho*cos(theta)*cos(phi) ; y = rho*sin(theta)*cos(phi) ; z = rho*sin(phi) ; assert(-1.000001 < x && x < 1.000001) ; assert(-1.000001 < y && y < 1.000001) ; ... ... @@ -217,6 +173,35 @@ typename Geom::Vector<3,typename PFP::REAL> LocalFrame::sphericalToCarth (c return res ; } template Geom::Vector<3,REAL> rotate (Geom::Vector<3,REAL> axis, REAL angle, Geom::Vector<3,REAL> vector) { axis.normalize() ; const REAL& u = axis[0] ; const REAL& v = axis[1] ; const REAL& w = axis[2] ; const REAL& x = vector[0] ; const REAL& y = vector[1] ; const REAL& z = vector[2] ; Geom::Vector<3,REAL> res ; REAL& xp = res[0] ; REAL& yp = res[1] ; REAL& zp = res[2] ; const REAL tmp1 = u*x+v*y+w*z ; const REAL cos = std::cos(angle) ; const REAL sin = std::sin(angle) ; xp = u*tmp1*(1-cos) + x*cos+(v*z-w*y)*sin ; yp = v*tmp1*(1-cos) + y*cos-(u*z-w*x)*sin ; zp = w*tmp1*(1-cos) + z*cos+(u*y-v*x)*sin ; 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!