OpenWalnut  1.4.0
WDataSetSphericalHarmonics.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <stdint.h>
00026 
00027 #include <cmath>
00028 #include <string>
00029 #include <vector>
00030 
00031 #include "../common/WAssert.h"
00032 #include "../common/math/linearAlgebra/WPosition.h"
00033 #include "../common/math/WSymmetricSphericalHarmonic.h"
00034 #include "WDataSetSingle.h"
00035 #include "WDataSetSphericalHarmonics.h"
00036 
00037 // prototype instance as singleton
00038 boost::shared_ptr< WPrototyped > WDataSetSphericalHarmonics::m_prototype = boost::shared_ptr< WPrototyped >();
00039 
00040 WDataSetSphericalHarmonics::WDataSetSphericalHarmonics( boost::shared_ptr< WValueSetBase > newValueSet,
00041                                                         boost::shared_ptr< WGrid > newGrid ) :
00042     WDataSetSingle( newValueSet, newGrid ), m_valueSet( newValueSet )
00043 {
00044     m_gridRegular3D = boost::dynamic_pointer_cast< WGridRegular3D >( newGrid );
00045     WAssert( newValueSet, "No value set given." );
00046     WAssert( newGrid, "No grid given." );
00047 }
00048 
00049 WDataSetSphericalHarmonics::WDataSetSphericalHarmonics()
00050     : WDataSetSingle()
00051 {
00052 }
00053 
00054 WDataSetSphericalHarmonics::~WDataSetSphericalHarmonics()
00055 {
00056 }
00057 
00058 WDataSetSingle::SPtr WDataSetSphericalHarmonics::clone( boost::shared_ptr< WValueSetBase > newValueSet ) const
00059 {
00060     return WDataSetSingle::SPtr( new WDataSetSphericalHarmonics( newValueSet, getGrid() ) );
00061 }
00062 
00063 WDataSetSingle::SPtr WDataSetSphericalHarmonics::clone( boost::shared_ptr< WGrid > newGrid ) const
00064 {
00065     return WDataSetSingle::SPtr( new WDataSetSphericalHarmonics( getValueSet(), newGrid ) );
00066 }
00067 
00068 WDataSetSingle::SPtr WDataSetSphericalHarmonics::clone() const
00069 {
00070     return WDataSetSingle::SPtr( new WDataSetSphericalHarmonics( getValueSet(), getGrid() ) );
00071 }
00072 
00073 boost::shared_ptr< WPrototyped > WDataSetSphericalHarmonics::getPrototype()
00074 {
00075     if( !m_prototype )
00076     {
00077         m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetSphericalHarmonics() );
00078     }
00079 
00080     return m_prototype;
00081 }
00082 
00083 WSymmetricSphericalHarmonic< double > WDataSetSphericalHarmonics::interpolate( const WPosition& pos, bool* success ) const
00084 {
00085     *success = m_gridRegular3D->encloses( pos );
00086 
00087     bool isInside = true;
00088     size_t cellId = m_gridRegular3D->getCellId( pos, &isInside );
00089 
00090     if( !isInside )
00091     {
00092         *success = false;
00093         return WSymmetricSphericalHarmonic< double >();
00094     }
00095 
00096     // ids of vertices for interpolation
00097     WGridRegular3D::CellVertexArray vertexIds = m_gridRegular3D->getCellVertexIds( cellId );
00098 
00099     WPosition localPos = pos - m_gridRegular3D->getPosition( vertexIds[0] );
00100 
00101     double lambdaX = localPos[0] / m_gridRegular3D->getOffsetX();
00102     double lambdaY = localPos[1] / m_gridRegular3D->getOffsetY();
00103     double lambdaZ = localPos[2] / m_gridRegular3D->getOffsetZ();
00104     WValue< double > h( 8 );
00105 //         lZ     lY
00106 //         |      /
00107 //         | 6___/_7
00108 //         |/:    /|
00109 //         4_:___5 |
00110 //         | :...|.|
00111 //         |.2   | 3
00112 //         |_____|/ ____lX
00113 //        0      1
00114     h[0] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00115     h[1] = (     lambdaX ) * ( 1 - lambdaY ) * ( 1 - lambdaZ );
00116     h[2] = ( 1 - lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00117     h[3] = (     lambdaX ) * (     lambdaY ) * ( 1 - lambdaZ );
00118     h[4] = ( 1 - lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00119     h[5] = (     lambdaX ) * ( 1 - lambdaY ) * (     lambdaZ );
00120     h[6] = ( 1 - lambdaX ) * (     lambdaY ) * (     lambdaZ );
00121     h[7] = (     lambdaX ) * (     lambdaY ) * (     lambdaZ );
00122 
00123     // take
00124     WValue<double> interpolatedCoefficients( m_valueSet->dimension() );
00125     for( size_t i = 0; i < 8; ++i )
00126     {
00127         interpolatedCoefficients += h[i] * m_valueSet->getWValueDouble( vertexIds[i] );
00128     }
00129 
00130     *success = true;
00131 
00132     return WSymmetricSphericalHarmonic< double >( interpolatedCoefficients );
00133 }
00134 
00135 WSymmetricSphericalHarmonic< double > WDataSetSphericalHarmonics::getSphericalHarmonicAt( size_t index ) const
00136 {
00137     if( index < m_valueSet->size() ) return WSymmetricSphericalHarmonic< double >( m_valueSet->getWValueDouble( index ) );
00138     return WSymmetricSphericalHarmonic< double >();
00139 }
00140 
00141 const std::string WDataSetSphericalHarmonics::getName() const
00142 {
00143     return "WDataSetSphericalHarmonics";
00144 }
00145 
00146 const std::string WDataSetSphericalHarmonics::getDescription() const
00147 {
00148     return "Contains factors for spherical harmonics.";
00149 }
00150 
00151 bool WDataSetSphericalHarmonics::isTexture() const
00152 {
00153     return false;
00154 }
00155