Skip to content
Snippets Groups Projects
Commit 0ac1a007 authored by rhchen2's avatar rhchen2
Browse files

400 line hw

parent 7ba0a2a9
No related branches found
No related tags found
No related merge requests found
/**
* @file quadtree.cpp
* Quadtree class implementation.
* @date Spring 2008
*/
#include <cstdio>
#include "quadtree.h"
#include <iostream>
#include <math.h>
Quadtree::Quadtree()
{
root = NULL;
}
Quadtree::Quadtree(const PNG & source, int resolution)
{
buildTree(source, resolution);
}
Quadtree::Quadtree(Quadtree const & other)
{
if (other.root == NULL)
{
root = NULL;
return;
}
root = copy(other.root);
}
Quadtree::QuadtreeNode * Quadtree::copy( QuadtreeNode *other)
{
if (other == NULL)
{
return NULL;
}
QuadtreeNode *T = new QuadtreeNode::QuadtreeNode(other);
T->nwChild = copy(other->nwChild);
T->neChild = copy(other->neChild);
T->swChild = copy(other->swChild);
T->seChild = copy(other->seChild);
return T;
}
Quadtree::~Quadtree()
{
clear(root);
}
void Quadtree::clear( QuadtreeNode * & node)
{
// base case
if ( node == NULL )
return;
// recursively clear all other nodes
clear(node->nwChild);
clear(node->neChild);
clear(node->swChild);
clear(node->seChild);
// delete the root and set it to NULL
delete node;
node = NULL;
}
/**
* Member Fucntion
*/
Quadtree const & Quadtree::operator= (Quadtree const &other)
{
//check self-assignment
if (root == other.root)
return *this;
//clear self
clear(root);
//copy other
root = copy(other.root);
return *this;
}
void Quadtree::buildTree (PNG const & source, int resolution)
{
root = new QuadtreeNode(0,0,resolution);
buildHelper (source, resolution, root);
}
void Quadtree::buildHelper (PNG const & source, int resolution, QuadtreeNode *node)
{
//base case when res == 1
//load correct pixels
if (resolution ==1){
node->element = *(source(node->x,node->y));
return;
}
//initialize new nodes
node->nwChild = new QuadtreeNode(node->x, node->y, resolution/2);
node->neChild = new QuadtreeNode(node->x + resolution/2, node->y, resolution/2);
node->swChild = new QuadtreeNode(node->x, node->y + resolution/2, resolution/2);
node->seChild = new QuadtreeNode(node->x + resolution/2, node->y + resolution/2, resolution/2);
//recursively build tree on children
buildHelper(source, resolution/2, node->nwChild);
buildHelper(source, resolution/2, node->neChild);
buildHelper(source, resolution/2, node->swChild);
buildHelper(source, resolution/2, node->seChild);
//store average color
node->element.red = (node->nwChild->element.red + node->neChild->element.red + node->swChild->element.red + node->seChild->element.red)/4;
node->element.green = (node->nwChild->element.green + node->neChild->element.green + node->swChild->element.green + node->seChild->element.green)/4;
node->element.blue = (node->nwChild->element.blue + node->neChild->element.blue + node->swChild->element.blue + node->seChild->element.blue)/4;
}
RGBAPixel Quadtree::getPixel (int x, int y) const
{
return pixelHelper(x,y,root);
}
RGBAPixel Quadtree::pixelHelper(int x, int y, QuadtreeNode *node) const
{
if ((node->x == x && node->y == y && node->res == 1) || (node->nwChild == NULL))
return node->element;
if (range(x,y,node->nwChild))
{
//in nw
return pixelHelper(x,y,node->nwChild);
} else if (range(x,y,node->neChild))
{
//in ne
return pixelHelper(x,y,node->neChild);
} else if (range(x,y,node->swChild))
{
//in sw
return pixelHelper(x,y,node->swChild);
} else
{
//in se
return pixelHelper(x,y,node->seChild);
}
}
/**
* Computes whether a given (x,y) is in range of a QuadtreeNode with its left-top most index as startX and startY
*/
bool Quadtree::range(int x, int y, QuadtreeNode *node) const
{
int x_range = node->x+node->res;
int y_range = node->y+node->res;
return (x >= node->x && x< x_range)&& (y >= node->y && y < y_range);
}
PNG Quadtree::decompress() const
{
if (root == NULL)
return *(new PNG());
int resolution = root->res;
PNG retVal(resolution, resolution);
for (int i = 0; i < resolution; i++)
{
for (int j = 0; j < resolution; j++)
{
*(retVal(i,j)) = getPixel(i,j);
}
}
return retVal;
}
void Quadtree:: clockwiseRotate(){
rotateHelper(root);
}
void Quadtree::rotateHelper(QuadtreeNode* node){
if(node->nwChild==NULL)
return;
QuadtreeNode* temp = node->nwChild;
node->nwChild=node->swChild;
node->swChild=node->seChild;
node->seChild=node->neChild;
node->neChild=temp;
//reassign x,y
node->nwChild->x=node->x;
node->nwChild->y=node->y;
node->neChild->x=node->x+node->res/2;
node->neChild->y=node->y;
node->swChild->x=node->x;
node->swChild->y=node->y+node->res/2;
node->seChild->x=node->x+node->res/2;
node->seChild->y=node->y+node->res/2;
//recurse
rotateHelper(node->nwChild);
rotateHelper(node->neChild);
rotateHelper(node->swChild);
rotateHelper(node->seChild);
}
//if the node elem is inside the tolerance value then we can delete it from the tree
void Quadtree::prune(int tolerance){
pruneHelper(root, tolerance);
}
void Quadtree::pruneHelper(QuadtreeNode* n, int tolerance){
if (n->nwChild == NULL)
return;
if (checkTol(n, n, tolerance))
{
//prune
clear(n->nwChild);
clear(n->neChild);
clear(n->swChild);
clear(n->seChild);
return;
}
//recursively call prune on children
pruneHelper(n->nwChild,tolerance);
pruneHelper(n->neChild,tolerance);
pruneHelper(n->swChild,tolerance);
pruneHelper(n->seChild,tolerance);
}
//function returns a boolean statement seeing if the pixels are within the tolerance
bool Quadtree:: checkTol(QuadtreeNode* n,QuadtreeNode* avgRoot,int tol)const{
if (n == NULL)
return true;
if (n->nwChild != NULL)
{
return (checkTol(n->nwChild, avgRoot,tol) && checkTol(n->neChild, avgRoot,tol) &&
checkTol(n->swChild, avgRoot,tol) && checkTol(n->seChild, avgRoot,tol));
}
if (difference(n, avgRoot) > tol)
return false;
return true;
}
int Quadtree::difference(QuadtreeNode*n, QuadtreeNode* avg)const{
int dif = 0;
dif += pow(n->element.red - avg->element.red, 2);
dif += pow(n->element.green - avg->element.green, 2);
dif += pow(n->element.blue - avg->element.blue, 2);
return dif;
}
int Quadtree::pruneSize(int tolerance) const{
return sizeHelper(root, tolerance);
}
int Quadtree::sizeHelper(QuadtreeNode*n, int tolerance)const{
if (n == NULL)
return 0;
if (n->nwChild == NULL || checkTol(n, n,tolerance))
return 1;
return (sizeHelper(n->nwChild, tolerance) + sizeHelper(n->neChild, tolerance) +
sizeHelper(n->swChild, tolerance) + sizeHelper(n->seChild, tolerance));
}
int Quadtree::idealPrune(int numLeaves)const{
int max = (255*255) + (255*255) + (255*255);
int min = 0;
int t = (min + max) / 2;
int n = 0;
int last = max;
while ((t > min) && (t < max))
{
n = pruneSize(t);
if (n <= numLeaves)
{
last = t;
max = t;
}
else
min = t;
t = (min + max)/2;
}
if (last == 1)
last=0;
return last;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment