/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.routing.algorithm1; import java.awt.geom.Path2D; import org.simantics.g2d.routing.Constants; public class RoutePencil extends Rectangle { public final Direction direction; public final RoutePencil parent; public double penalty; public double distanceConstant; public double distanceX; public double distanceY; public RoutePencil(double x0, double y0, double x1, double y1, double penalty, Direction direction, RoutePencil parent) { super(x0, y0, x1, y1); this.penalty = penalty; this.direction = direction; this.parent = parent; if(parent == null) { distanceConstant = 0.0; distanceX = 0.0; distanceY = 0.0; } else { switch(direction.getId()) { case Constants.EAST: { distanceX = 1.0; distanceY = parent.distanceY; double x = Math.min(parent.x1, x0); distanceConstant = parent.distanceConstant + x * (parent.distanceX - distanceX); } break; case Constants.SOUTH: { distanceX = parent.distanceX; distanceY = 1.0; double y = Math.min(parent.y1, y0); distanceConstant = parent.distanceConstant + y * (parent.distanceY - distanceY); } break; case Constants.WEST: { distanceX = -1.0; distanceY = parent.distanceY; double x = Math.max(parent.x0, x1); distanceConstant = parent.distanceConstant + x * (parent.distanceX - distanceX); } break; case Constants.NORTH: { distanceX = parent.distanceX; distanceY = -1.0; double y = Math.max(parent.y0, y1); distanceConstant = parent.distanceConstant + y * (parent.distanceY - distanceY); } break; } } } double distance(double x, double y) { double result = distanceConstant; if(x < x0) result += distanceX * x0 + (x0 - x); else if(x > x1) result += distanceX * x1 + (x - x1); else result += distanceX * x; if(y < y0) result += distanceY * y0 + (y0 - y); else if(x > x1) result += distanceY * y1 + (y - y1); else result += distanceY * y; return result; } double distance() { return distanceConstant + distanceX * x0 + distanceY * y0; } void createPath(Path2D path, double x, double y) { if(parent == null) { /*switch(direction.getId()) { case Constants.EAST: path.moveTo(x0, y); break; case Constants.SOUTH: path.moveTo(x, y0); break; case Constants.WEST: path.moveTo(x1, y); break; case Constants.NORTH: path.moveTo(x, y1); break; } */ path.moveTo(makeFinite(x), makeFinite(y)); } else { if(parent.contains(x, y)) parent.createPath(path, x, y); else { switch(direction.getId()) { case Constants.EAST: if(parent.distanceX < 1.0) parent.createPath(path, parent.x1, y); else parent.createPath(path, (parent.x0+parent.x1)*0.5, y); break; case Constants.SOUTH: if(parent.distanceY < 1.0) parent.createPath(path, x, parent.y1); else parent.createPath(path, x, (parent.y0+parent.y1)*0.5); break; case Constants.WEST: if(parent.distanceX > -1.0) parent.createPath(path, parent.x0, y); else parent.createPath(path, (parent.x0+parent.x1)*0.5, y); break; case Constants.NORTH: if(parent.distanceY > -1.0) parent.createPath(path, x, parent.y0); else parent.createPath(path, x, (parent.y0+parent.y1)*0.5); break; } path.lineTo(makeFinite(x), makeFinite(y)); } } } static double makeFinite(double x) { if(x == Double.POSITIVE_INFINITY) return 10000.0; if(x == Double.NEGATIVE_INFINITY) return -10000.0; return x; } public Path2D createPath(double x, double y) { Path2D path = new Path2D.Double(); createPath(path, x, y); return path; } @Override public String toString() { if(parent == null) return Integer.toString(direction.getId()); else return parent.toString() + " " + Integer.toString(direction.getId()); } }