WQuadNode.cpp 4.44 KB
Newer Older
1 2 3 4
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
5
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// 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 <iostream>

#include "WQuadTree.h"
#include "WQuadNode.h"

const size_t WQuadNode::vX[] = {0, 1, 0, 1};
const size_t WQuadNode::vY[] = {0, 0, 1, 1};

WQuadNode::WQuadNode( double centerX, double centerY, double radius )
{
    m_pointCount = 0;
36
    m_id = 0;
37
    m_xMin = m_xMax = m_yMin = m_yMax = m_valueMin = m_valueMax = 0;
38 39 40 41 42 43 44 45 46 47
    m_center[0] = centerX;
    m_center[1] = centerY;
    this->m_radius = radius;
    for  ( size_t index = 0; index < 4; index++ )
        m_child[index] = 0;
}

WQuadNode::~WQuadNode()
{
    m_pointCount = 0;
48 49
    for( size_t index = 0; index < 4; index++ )
        delete m_child[index];
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
}

WQuadNode* WQuadNode::getChild( size_t drawer )
{
    return m_child[ drawer ];
}

bool WQuadNode::fitsIn( double x, double y )
{
    if  ( x < m_center[0]-m_radius || x >= m_center[0]+m_radius )
        return false;
    if  ( y < m_center[1]-m_radius || y >= m_center[1]+m_radius )
        return false;
    return true;
}

size_t WQuadNode::getFittingCase( double x, double y )
{
    if  ( !fitsIn( x, y ) )
        return false;
    size_t caseX = x < m_center[0] ?0 :1;
    size_t caseY = y < m_center[1] ?0 :1;
    size_t quad = 0;
    while  ( vX[quad] != caseX || vY[quad] != caseY )
        quad++;
    return quad;
}

void WQuadNode::expand()
{
    for  ( size_t quad = 0; quad < 4; quad++ )
    {
        if  ( m_child[quad] != 0 )
        {
            size_t newCase = 0;
            while  ( vX[newCase] == vX[quad] || vY[newCase] == vY[quad] )
                newCase++;

            double centerX = ( static_cast<double>( vX[quad] )*2.0 - 1.0 ) * m_radius + m_center[0];
            double centerY = ( static_cast<double>( vY[quad] )*2.0 - 1.0 ) * m_radius + m_center[1];
            WQuadNode* newChild = new WQuadNode( centerX, centerY, m_radius );
            newChild->setChild( m_child[quad], newCase );
            setChild( newChild, quad );
        }
    }
    m_radius *= 2.0;
}

void WQuadNode::touchNode( size_t drawer )
{
    if  ( m_child[drawer] == 0 )
    {
        double centerX = m_center[0] - m_radius*0.5 + static_cast<double>( vX[drawer] )*m_radius;
        double centerY = m_center[1] - m_radius*0.5 + static_cast<double>( vY[drawer] )*m_radius;
        m_child[drawer] = new WQuadNode( centerX, centerY, m_radius * 0.5 );
    }
}

double WQuadNode::getRadius()
{
    return m_radius;
}
112

113 114 115 116
double WQuadNode::getCenter( size_t dimension )
{
    return m_center[dimension];
}
117

118
void WQuadNode::updateMinMax( double x, double y, double value )
119
{
120
    if( !( m_pointCount > 0 ) )
121 122 123
    {
        m_xMin = m_xMax = x;
        m_yMin = m_yMax = y;
124
        m_valueMin = m_valueMax = value;
125 126 127 128 129
    }
    if( x < m_xMin ) m_xMin = x;
    if( x > m_xMax ) m_xMax = x;
    if( y < m_yMin ) m_yMin = y;
    if( y > m_yMax ) m_yMax = y;
130 131
    if( value < m_valueMin ) m_valueMin = value;
    if( value > m_valueMax ) m_valueMax = value;
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    m_pointCount++;
}




void WQuadNode::setChild( WQuadNode* child, size_t drawer )
{
    m_child[drawer] = child;
}

size_t WQuadNode::getPointCount()
{
    return m_pointCount;
}
147

148 149 150 151
double WQuadNode::getXMin()
{
    return m_xMin;
}
152

153 154 155 156
double WQuadNode::getXMax()
{
    return m_xMax;
}
157

158 159 160 161
double WQuadNode::getYMin()
{
    return m_yMin;
}
162

163 164 165 166
double WQuadNode::getYMax()
{
    return m_yMax;
}
167

168
double WQuadNode::getValueMin()
169
{
170
    return m_valueMin;
171
}
172

173
double WQuadNode::getValueMax()
174
{
175
    return m_valueMax;
176
}
177 178 179 180 181

size_t WQuadNode::getID()
{
    return m_id;
}
182

183 184 185 186
void WQuadNode::setID( size_t id )
{
    m_id = id;
}