WHistogram2D.cpp 4.82 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//---------------------------------------------------------------------------
//
// 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 <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#include <utility>

27 28
#include <osg/Texture2D>

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
#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 );
}

123 124 125 126 127 128 129
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
Mathias Goldau's avatar
Mathias Goldau committed
130 131
    float maxCount = 0;
    for( size_t j = 0; j < imageHeight; ++j )
132
    {
Mathias Goldau's avatar
Mathias Goldau committed
133
        for( size_t i = 0; i < imageWidth; ++i )
134
        {
Mathias Goldau's avatar
Mathias Goldau committed
135
            if( m_bins( i, j ) > maxCount )
136
            {
Mathias Goldau's avatar
Mathias Goldau committed
137
                maxCount = static_cast< float >( m_bins( i, j ) );
138 139 140
            }
        }
    }
141

142 143 144 145
    image->allocateImage( imageWidth, imageHeight, 1, GL_RED, GL_FLOAT );
    image->setInternalTextureFormat( GL_RED );

    float* data = reinterpret_cast< float* >( image->data() );
Mathias Goldau's avatar
Mathias Goldau committed
146
    for( size_t j = 0; j < imageHeight; ++j )
147
    {
Mathias Goldau's avatar
Mathias Goldau committed
148
        for( size_t i = 0; i < imageWidth; ++i )
149
        {
Mathias Goldau's avatar
Mathias Goldau committed
150
            data[i + j * imageWidth] = static_cast< float >( m_bins( i, j ) ) / maxCount;
151 152 153 154
        }
    }
    return new osg::Texture2D( image );
}