OpenWalnut  1.4.0
WHistogram2D.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 <utility>
00026 
00027 #include <core/common/math/WMath.h>
00028 #include <core/graphicsEngine/WGETexture.h>
00029 #include "WAssert.h"
00030 #include "WHistogram2D.h"
00031 #include "WLimits.h"
00032 #include "WLogger.h"
00033 
00034 WHistogram2D::WHistogram2D( double minX, double maxX, double minY, double maxY, size_t bucketsX, size_t bucketsY )
00035 {
00036     // use protecte default ctor to workaround missing initializer lists which are part of C++11 and GNU++11 only.
00037     TArray min = {{ minX, minY }}; // NOLINT braces
00038     TArray max = {{ maxX, maxY }}; // NOLINT braces
00039     SizeArray buckets = {{ bucketsX, bucketsY }}; // NOLINT braces
00040     reset( min, max, buckets );
00041 
00042     m_intervalWidth[0] = std::abs( maxX - minX ) / static_cast< double >( bucketsX );
00043     m_intervalWidth[1] = std::abs( maxY - minY ) / static_cast< double >( bucketsY );
00044     m_bins = BinType::Zero( bucketsX, bucketsY );
00045 }
00046 
00047 WHistogram2D::~WHistogram2D()
00048 {
00049 }
00050 
00051 WHistogram2D::WHistogram2D( const WHistogram2D& other )
00052     : WHistogramND( other )
00053 {
00054     m_bins = other.m_bins;
00055 }
00056 
00057 size_t WHistogram2D::operator()( SizeArray index ) const
00058 {
00059     return m_bins( index[0], index[1] );
00060 }
00061 
00062 size_t WHistogram2D::operator()( size_t i, size_t j ) const
00063 {
00064     SizeArray index = {{ i, j }};
00065     return operator()( index );
00066 }
00067 
00068 double WHistogram2D::getBucketSize( SizeArray /* index */ ) const
00069 {
00070     return m_intervalWidth[0] * m_intervalWidth[1];
00071 }
00072 
00073 boost::array< std::pair< double, double >, 2 > WHistogram2D::getIntervalForIndex( SizeArray index ) const
00074 {
00075     boost::array< std::pair< double, double >, 2 > result;
00076 
00077     for( size_t i = 0; i < 2; ++i )
00078     {
00079         result[i] = std::make_pair( m_intervalWidth[i] * index[i] + m_min[i],
00080                                     m_intervalWidth[i] * ( index[i] + 1 ) + m_min[i] );
00081     }
00082 
00083     return result;
00084 }
00085 
00086 void WHistogram2D::insert( TArray values )
00087 {
00088     if( values[0] > m_max[0] || values[0] < m_min[0] || values[1] > m_max[1] || values[1] < m_min[1] )
00089     {
00090         wlog::warn( "WHistogram2D" ) << std::scientific << std::setprecision( 16 ) << "Inserted value out of bounds, thread: ("
00091                                      << values[0] << "," << values[1] << ") whereas min,max are: dim0: (" << m_min[0] << "," << m_max[0] << ") "
00092                                      << "dim1:(" << m_min[1] << "," << m_max[1] << ")";
00093         return;
00094     }
00095 
00096     SizeArray coord = {{ 0, 0 }};
00097 
00098     for( size_t i = 0; i < 2; ++i )
00099     {
00100         if( std::abs( m_min[i] - m_max[i] ) <= 2.0 * wlimits::DBL_EPS )
00101         {
00102             coord[i] = m_buckets[i] - 1;
00103         }
00104         else if( values[i] >= ( m_max[i] - m_intervalWidth[i] ) && values[i] <= m_max[i] )
00105         {
00106             coord[i] = m_buckets[i] - 1;
00107         }
00108         else
00109         {
00110             coord[i] = static_cast< size_t >( ( values[i] - m_min[i] ) / std::abs( m_max[i] - m_min[i] ) * ( m_buckets[i] ) );
00111         }
00112     }
00113 
00114     m_bins( coord[0], coord[1] )++;
00115 }
00116 
00117 void WHistogram2D::insert( double x, double y )
00118 {
00119     TArray values = {{ x, y }};
00120     insert( values );
00121 }
00122 
00123 WGETexture2D::RPtr WHistogram2D::getTexture()
00124 {
00125     osg::ref_ptr< osg::Image > image = new osg::Image();
00126     size_t imageWidth = m_buckets[0];
00127     size_t imageHeight = m_buckets[1];
00128     float maxCount = 0;
00129 
00130     for( size_t j = 0; j < imageHeight; ++j ) // get max bin for scaling
00131     {
00132         for( size_t i = 0; i < imageWidth; ++i )
00133         {
00134             if( m_bins( i, j ) > maxCount )
00135             {
00136                 maxCount = static_cast< float >( m_bins( i, j ) );
00137             }
00138         }
00139     }
00140 
00141     image->allocateImage( imageWidth, imageHeight, 1, GL_RED, GL_FLOAT );
00142     image->setInternalTextureFormat( GL_RED );
00143     float* data = reinterpret_cast< float* >( image->data() );
00144 
00145     for( size_t j = 0; j < imageHeight; ++j )
00146     {
00147         for( size_t i = 0; i < imageWidth; ++i )
00148         {
00149             data[i + j * imageWidth] = static_cast< float >( m_bins( i, j ) ) / maxCount;
00150         }
00151     }
00152 
00153     return WGETexture2D::RPtr( new WGETexture2D( image ) );
00154 }
00155 
00156 /**
00157  * Unnamed namespace for helper functions keeping the code DRY as possible.
00158  */
00159 namespace
00160 {
00161     double calcAreaScale( const double bucket, const size_t j )
00162     {
00163         double theta = piDouble - ( j * bucket + ( bucket / 2.0 ) );
00164         return 1.0 / sin( theta );
00165     }
00166 }
00167 
00168 WGETexture2D::RPtr WHistogram2D::getSphereTexture()
00169 {
00170     osg::ref_ptr< osg::Image > image = new osg::Image();
00171     size_t imageWidth = m_buckets[0];
00172     size_t imageHeight = m_buckets[1];
00173     double maxCount = 0.0;
00174     const double bucket = piDouble / static_cast< double >( imageHeight );
00175     double areaScale = 0.0;
00176 
00177     for( size_t j = 0; j < imageHeight; ++j ) // get max bin for scaling
00178     {
00179         areaScale = calcAreaScale( bucket, j );
00180         for( size_t i = 0; i < imageWidth; ++i )
00181         {
00182             if( areaScale * m_bins( i, j ) > maxCount)
00183             {
00184                 maxCount = areaScale * static_cast< double >( m_bins( i, j ) );
00185             }
00186         }
00187     }
00188 
00189     image->allocateImage( imageWidth, imageHeight, 1, GL_RED, GL_FLOAT );
00190     image->setInternalTextureFormat( GL_RED );
00191     float* data = reinterpret_cast< float* >( image->data() );
00192 
00193     for( size_t j = 0; j < imageHeight; ++j )
00194     {
00195         areaScale = calcAreaScale( bucket, j );
00196         for( size_t i = 0; i < imageWidth; ++i )
00197         {
00198             data[i + j * imageWidth] = areaScale * static_cast< double >( m_bins( i, j ) ) / maxCount;
00199         }
00200     }
00201 
00202     return WGETexture2D::RPtr( new WGETexture2D( image ) );
00203 }
00204