//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS // For more information see http://www.openwalnut.org/copying // // This file is part of OpenWalnut. // // OpenWalnut 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 3 of the License, or // (at your option) any later version. // // OpenWalnut 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 OpenWalnut. If not, see . // //--------------------------------------------------------------------------- #include #include #include "WAssert.h" #include "WHistogram2D.h" #include "WLimits.h" #include "WLogger.h" WHistogram2D::WHistogram2D( double minX, double maxX, double minY, double maxY, size_t bucketsX, size_t bucketsY ) { // use protecte default ctor to workaround missing initializer lists which are part of C++11 and GNU++11 only. TArray min = {{ minX, minY }}; // NOLINT braces TArray max = {{ maxX, maxY }}; // NOLINT braces SizeArray buckets = {{ bucketsX, bucketsY }}; // NOLINT braces reset( min, max, buckets ); m_intervalWidth[0] = std::abs( maxX - minX ) / static_cast< double >( bucketsX ); m_intervalWidth[1] = std::abs( maxY - minY ) / static_cast< double >( bucketsY ); m_bins = BinType::Zero( bucketsX, bucketsY ); } WHistogram2D::~WHistogram2D() { } WHistogram2D::WHistogram2D( const WHistogram2D& other ) : WHistogramND( other ) { m_bins = other.m_bins; } size_t WHistogram2D::operator()( SizeArray index ) const { return m_bins( index[0], index[1] ); } size_t WHistogram2D::operator()( size_t i, size_t j ) const { SizeArray index = {{ i, j }}; return operator()( index ); } double WHistogram2D::getBucketSize( SizeArray /* index */ ) const { return m_intervalWidth[0] * m_intervalWidth[1]; } boost::array< std::pair< double, double >, 2 > WHistogram2D::getIntervalForIndex( SizeArray index ) const { boost::array< std::pair< double, double >, 2 > result; for( size_t i = 0; i < 2; ++i ) { result[i] = std::make_pair( m_intervalWidth[i] * index[i] + m_min[i], m_intervalWidth[i] * ( index[i] + 1 ) + m_min[i] ); } return result; } void WHistogram2D::insert( TArray values ) { if( values[0] > m_max[0] || values[0] < m_min[0] || values[1] > m_max[1] || values[1] < m_min[1] ) { wlog::warn( "WHistogram2D" ) << std::scientific << std::setprecision( 16 ) << "Inserted value out of bounds, thread: (" << values[0] << "," << values[1] << ") whereas min,max are: dim0: (" << m_min[0] << "," << m_max[0] << ") " << "dim1:(" << m_min[1] << "," << m_max[1] << ")"; return; } SizeArray coord = {{ 0, 0 }}; for( size_t i = 0; i < 2; ++i ) { if( std::abs( m_min[i] - m_max[i] ) <= 2.0 * wlimits::DBL_EPS ) { coord[i] = m_buckets[i] - 1; } else if( values[i] >= ( m_max[i] - m_intervalWidth[i] ) && values[i] <= m_max[i] ) { coord[i] = m_buckets[i] - 1; } else { coord[i] = static_cast< size_t >( ( values[i] - m_min[i] ) / std::abs( m_max[i] - m_min[i] ) * ( m_buckets[i] ) ); } } m_bins( coord[0], coord[1] )++; } void WHistogram2D::insert( double x, double y ) { TArray values = {{ x, y }}; insert( values ); } osg::ref_ptr< osg::Texture2D > WHistogram2D::getTexture() { osg::ref_ptr< osg::Image > image = new osg::Image(); size_t imageWidth = m_buckets[0]; size_t imageHeight = m_buckets[1]; //get max bin for scaling float maxCount = 0; for( size_t j = 0; j < imageHeight; ++j ) { for( size_t i = 0; i < imageWidth; ++i ) { if( m_bins( i, j ) > maxCount ) { maxCount = static_cast< float >( m_bins( i, j ) ); } } } image->allocateImage( imageWidth, imageHeight, 1, GL_RED, GL_FLOAT ); image->setInternalTextureFormat( GL_RED ); float* data = reinterpret_cast< float* >( image->data() ); for( size_t j = 0; j < imageHeight; ++j ) { for( size_t i = 0; i < imageWidth; ++i ) { data[i + j * imageWidth] = static_cast< float >( m_bins( i, j ) ) / maxCount; } } return new osg::Texture2D( image ); }