Document Actions

LineTree.java

Hierarchical line simplification tree

Click here to get the file

Size 5.1 kB - File type text/plain

File contents

// Name: LineTree.java
// Intent: hierarchical line simplification tree
// Programmer: John P. Kavanagh  #2748 2405
// Date Modified: 9 May 2002
// Audit: Clifford Meyers (cmeyers@buffalo.edu)

public class LineTree {

	private Line myComplexLine;
	private TreeNode root;

	// Initialize a null LineTree
	public LineTree() {
		myComplexLine = null;
		System.out.println("");		
		System.out.println("[ Instantiated null LineTree. ]");			
	}

	// Initialize a LineTree with a complex Line	
	public LineTree(Line complexLine) {
		root = new TreeNode();		
		findSplitNode(complexLine, root);
		setComplexLine(complexLine); 
		System.out.println("");		
		System.out.println("[ Populated LineTree. ]");		
	}
		
	
	// split a line at favorable point and distance
	// this is the deusenberg!
	private void findSplitNode(Line splitMe, TreeNode thisNode) {

		//System.out.println("");
		//System.out.println("[ Find split node ]");
	
		Point begin = splitMe.GetBeginPoint(); // Find first point of line segment
		Point end = splitMe.GetEndPoint(); // Find last point of line segment

		Point candidate = begin; // Test this point for split favorability
		Point extremePoint = null; // This is the most favorable split point, so far

		double segmentLength = begin.FindDistance(end); // Determine length of triangle base
		thisNode.setBandwidth(segmentLength);
		
		double displacement = 0; // Distance from end and beginning to extreme point
		
		
		// Test all candidate points for "extremeness"
		// Always place most extreme split point in splitNode
		// If newer point is more extreme, then replace old one
		while (splitMe.GetNextPoint(candidate) != null) {
			
			//System.out.println("Evaluate next line point bandwidth.");
			
			// This is the displacement of the test point 
			// from the end and beginning
			displacement = (begin.FindDistance(candidate) + end.FindDistance(candidate));
		
			if (displacement > thisNode.getBandwidth()){
				thisNode.setPoint(candidate);
				thisNode.setBandwidth(displacement);
			}
			
			if (splitMe.GetNextPoint(candidate) != null) {
				candidate = splitMe.GetNextPoint(candidate); // select next point to test
			}		
		}
		
		// unless there are no points left to split the line
		if (thisNode.getPoint() != null) {
			System.out.println(" ");		
			System.out.println("> This node point: (" + thisNode.getPoint().getXvalue() + "," + thisNode.getPoint().getYvalue() + ") <");
			System.out.println("> This node bandwidth: " + thisNode.getBandwidth() +" <");		
			System.out.println(" ");
			
			// Split old line and create two new lines
			Line lineA = SubLine(begin, thisNode.getPoint(), splitMe);
			Line lineB = SubLine(thisNode.getPoint(), end, splitMe);
			
	
			// Make left and right nodes
			TreeNode righty = new TreeNode();
			thisNode.setRightNode(righty);
			TreeNode lefty = new TreeNode();		
			thisNode.setLeftNode(lefty);
					
			
			// Continue finding further split points for generalization
			// inside the two new lines
			if (thisNode.getLeftNode() != null){
				findSplitNode(lineA, thisNode.getLeftNode());
			}  
			if (thisNode.getRightNode() != null){		
				findSplitNode(lineB, thisNode.getRightNode());	
			}
		}
	}	

	
	// accessor method for complex line
	public Line getComplexLine(){
		return myComplexLine;
	}		
	
	
	// a tree is simplified, create smaller lines to evaluate for node bandwidth
	public Line SubLine(Point begin, Point end,  Line ComplexLine){

		Line smallerLine = new Line();
		LineSegment thisSegment = ComplexLine.GetBeginSegment();
		
		// Find the segment with the given beginning point
		// Set that segment as the first to be added to the smaller line
		while (thisSegment.IsBeginPoint(begin) == false){
			thisSegment = thisSegment.GetNextSegment();
		}

		// Add segments to smaller line until the end point is reached
		// If line segment begins with last point, do not add
		while (thisSegment != null){ 

			if (thisSegment.IsBeginPoint(end)){			
				thisSegment = null;
			}
			else {
				// Make new line segment, duplicate of old without prev and next links
				LineSegment addSegment = new LineSegment(thisSegment.GetBeginPoint(), thisSegment.GetEndPoint());
				// Add new line segment to simpler line
				smallerLine.AddLineSegment(addSegment);				
				// Get next segment on original complex line
				thisSegment = thisSegment.GetNextSegment();			
			}				

		}	 		
		//System.out.println("Line end point: (" + smallerLine.GetEndPoint().getXvalue() + "," + smallerLine.GetEndPoint().getYvalue() + ")");
		return smallerLine;
	}
	
	
	
	// accessor method for complex linew
	public void setComplexLine(Line newLine){
		myComplexLine = newLine;
	}		
	
	// accessor method for root node
	public TreeNode getRoot(){
		return root;
	}	
	
	// modifer method for root node
	public void setRoot(TreeNode newRoot){
		root = newRoot;
	}		
	
	// destroy LineTree
	public void Destroy(){

		if (myComplexLine != null) { // destroy existing left node
			myComplexLine.Destroy();
		}
		
		root.Destroy();
	}



}
www.flickr.com