//ShowTree Tree Visualization System
//Copyright (C) 2009 Yuvi Masory
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation, version 3 only.
//
//This program 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 General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package logic.positioningAlgorithms;
import display.Start;
import logic.Node;
import logic.treeIterators.PostorderIterator;
/*
* Implements Algorithm 3 from:
* C.Wetherell and A. Shannon. Tidy drawings of trees. IEEE Transactions
* on Software Engineering, 7(2):223-228, 1979
* WS call "height" what I call "depth"
*/
public class WS79_Tidy implements PositioningAlgorithm {
public void embed(Node n, double s) {
n.assignDepths();
n.assignHeights();
double[] shiftingUnits = new double[n.getHeight() + 1];
double[] nextPosition = new double[n.getHeight() + 1];
// first pass
PostorderIterator iter = new PostorderIterator(n);
Node cur;
while(iter.hasNext()) {
cur = iter.next();
int level = cur.getDepth();
cur.setY(Start.Y_SEPARATION * level);
double provisionalX = 0;
if(cur.isLeaf()) {
provisionalX = nextPosition[level];
}
else if(cur.degree() == 1) {
provisionalX = cur.getLeft().getX();
}
else if(cur.degree() > 1){
provisionalX = (cur.getLeft().getX() + cur.getRight().getX())/2;
}
shiftingUnits[level] = Math.max(shiftingUnits[level], nextPosition[level] - provisionalX);
if(cur.isLeaf()) {
cur.setX(provisionalX);
}
else {
cur.setX(provisionalX + shiftingUnits[level]);
}
nextPosition[level] = cur.getX() + s;
cur.setModifier(shiftingUnits[level]);
}
// second pass
shift(n, 0);
}
public void shift(Node n, double baseShift) {
n.setX(n.getX() + baseShift);
baseShift += n.getModifier();
if(n.hasLeft()) {
shift(n.getLeft(), baseShift);
}
if(n.hasRight()) {
shift(n.getRight(), baseShift);
}
}
public boolean isBinary() {
return true;
}
public boolean handlesNodeWidths() {
return false;
}
public String toString() {
return "2: WS79 Tidy";
}
}