OpenWalnut
1.4.0
|
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