/* * Created on 09.12.2004 * * SVN header information: * $Author: LBST-PF-3\orahn $ * $Rev: 2509 $ * $Date: 2006-10-06 12:01:50 +0200 (Fr, 06 Okt 2006) $ * $Id: PirolPoint.java 2509 2006-10-06 10:01:50Z LBST-PF-3\orahn $ */ package org.openjump.core.graph.pirolProject; import org.openjump.core.apitools.comparisonandsorting.CoordinateComparator; import org.openjump.core.apitools.comparisonandsorting.Sortable; import com.vividsolutions.jts.geom.Coordinate; /** * Base class for objects that describe an n-dimensional point. * There are derived classes e.g. to suit the requirements of a * triangulation or an interpolation. * Offers methods e.g. to determine distances between different * punkt objects or to mark and unmark punkt objects. * * punkt objects implement Sortable and have a choseable natural * order (implement Comparable), so they can be sorted with the tools * from the Java Collection Framework. * * @author Ole Rahn * <br> * <br>FH Osnabrück - University of Applied Sciences Osnabrück, * <br>Project: PIROL (2005), * <br>Subproject: Daten- und Wissensmanagement * * @version $Rev: 2509 $ * * @see PirolEdge * modified: [sstein]: 16.Feb.2009 changed logger-entries to comments */ public class PirolPoint extends Sortable { protected double[] coordinates = null; protected int dimension = 0, index = -1; public static final PirolPoint NULLPUNKT = new PirolPoint(new double[]{0.0,0.0,0.0}); protected ScaleChanger scaler = null; protected boolean scaled = false; protected boolean marked = false; //protected static PersonalLogger logger = new PersonalLogger(DebugUserIds.OLE); /** * For classLoaders */ public PirolPoint(){ super(); } public PirolPoint( double[] coords ){ this.coordinates = coords; this.index = -1; this.dimension = coords.length; } public PirolPoint( double[] coords, int index){ this.coordinates = coords; this.index = index; this.dimension = coords.length; } public PirolPoint( double[] coords, int index, ScaleChanger scaler, boolean prescaled){ this.coordinates = coords; this.index = index; this.scaler = scaler; this.dimension = coords.length; this.scaled = prescaled; } public PirolPoint( double[] coords, int index, ScaleChanger scaler){ this.coordinates = coords; this.index = index; this.scaler = scaler; this.dimension = coords.length; } /** * creates a punkt object that represents a vector (x,y(,z)) that shows the direction * that leads from point "from" to point "to". *@param from source points of the vector *@param to destination point of the vector *@return a vector from from to to ;-) */ public static PirolPoint createVector(PirolPoint from, PirolPoint to){ int dim = Math.min(from.getDimension(), to.getDimension()); double[] vectorComponents = new double[dim]; for (int i=0; i<dim; i++){ try { vectorComponents[i] = to.getCoordinate(i) - from.getCoordinate(i); } catch (Exception e) { //logger.printError(e.getMessage()); } } return new PirolPoint(vectorComponents); } /** * Method to create a deep copy of the given punkt object, that doesn't share any references with the original *@param pkt the punkt object to clone *@return copy of the given punkt object *@since 1.15 */ public static PirolPoint clone(PirolPoint pkt){ double[] newCoords = new double[pkt.getDimension()]; for (int i=0; i<pkt.getDimension(); i++){ try { newCoords[i] = pkt.getCoordinate(i); } catch (Exception e) { //logger.printError(e.getMessage()); } } PirolPoint cloned = new PirolPoint(newCoords, pkt.index); cloned.setMarked(pkt.isMarked()); cloned.setScaler(pkt.scaler); cloned.setSortFor(pkt.sortFor); return cloned; } /** * Method to create a deep copy of the calling punkt object, that doesn't share any references with the original *@return copy of the punkt object *@since 1.15 */ public PirolPoint clonePunkt(){ return PirolPoint.clone(this); } /** * check if <code>marked</code> was set or not *@return true, if <code>marked</code> is true */ public boolean isMarked() { return marked; } /** * set boolean flag of the object, to e.g. mark if this point was already passed or whatever. *@param marked boolean value to set the internal flag to */ public void setMarked(boolean marked) { this.marked = marked; } public boolean liegtAuf(PirolPoint p) { try { if (this == p){ return true; } else if (p.getX()==this.getX() && p.getY() == this.getY()) { return true; } } catch (Exception e) { return false; } return false; } public boolean equals(Object obj) { PirolPoint p; try { p = (PirolPoint)obj; } catch (Exception e ){ return false; } try { if (this == p){ return true; } else if (p.getIndex() == this.getIndex() && !(this.getIndex()<0)){ return true; } else if (Math.min(p.getDimension(), this.getDimension())>=3 && p.getX()==this.getX() && p.getY() == this.getY() && p.getZ() == this.getZ()) { return true; } else if (p.getX()==this.getX() && p.getY() == this.getY()) { return true; } } catch (Exception e) {} return false; } public int getSortFor() { return sortFor; } public void setSortFor(int sortFor) { this.sortFor = sortFor; } public void setScaler(ScaleChanger scaler) { this.scaler = scaler; } public void scale( ) throws RuntimeException { if ( scaled || this.scaler == null ) return; for ( int i=0; i<this.dimension; i++ ){ this.setCoordinate(this.scaler.scale(this.getCoordinate(i),i),i); } scaled = true; } public void unScale( ) throws RuntimeException { if ( !scaled || this.scaler == null ) return; for ( int i=0; i<this.dimension; i++ ){ this.setCoordinate(this.scaler.unScale(this.getCoordinate(i),i),i); } scaled = false; } public double[] getCoordinates() { return coordinates; } public void setCoordinates(double[] coordinates) { this.coordinates = coordinates; this.dimension = coordinates.length; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public int getDimension() { return dimension; } /** * get the <code>nr</code>-th coordinate. This method is used within getX(), getY(), getZ(). *@return the <code>nr</code>-th coordinate *@throws RuntimeException if the point has less coordniates than <code>nr</code> or if <code>nr</code> is less than zero */ public double getCoordinate( int nr ) throws RuntimeException { if (dimension > nr){ return this.coordinates[nr]; } throw new RuntimeException("invalid dimension: "+nr + " (vs. " + this.dimension +")"); } /** * set the <code>nr</code>-th coordinate. This method is used within setX(), setY(), setZ(). *@param newCoord new Coordinate *@param nr number of coordinate to set */ public void setCoordinate( double newCoord, int nr ){ if (dimension > nr){ this.coordinates[nr] = newCoord; } } /** * get 0-th coordinate *@return 0-th coordinate *@throws RuntimeException */ public double getX() throws RuntimeException{ return this.getCoordinate(0); } /** * get 1-st coordinate *@return 1-st coordinate *@throws RuntimeException */ public double getY() throws RuntimeException{ return this.getCoordinate(1); } /** * get 2-nd coordinate *@return 2-nd coordinate *@throws RuntimeException */ public double getZ() throws RuntimeException{ return this.getCoordinate(2); } /** * set the 0-th coordinate *@param val 0-th coordinate */ public void setX(double val){ this.setCoordinate(val, 0); } /** * set the 1-st coordinate *@param val 1-st coordinate */ public void setY(double val){ this.setCoordinate(val, 1); } /** * set the 2-nd coordinate *@param val 2-nd coordinate */ public void setZ(double val){ this.setCoordinate(val, 2); } /** * calculates the distance of <code>this</code> point to the other point. * The distance will be calculated in as many dimensions as both points have. * If the two points have a different amount of coordinates, this will happen: <code>int checkDim = Math.min(this.dimension, p.getDimension());</code> *@param p the other point *@return distance between the two points *@throws RuntimeException */ public double distanceTo(PirolPoint p) throws RuntimeException{ return PirolPoint.distanceBetween(this, p); } /** * calculates the distance of point <b>p1</b> to the other point <b>p2</b>. * The distance will be calculated in as many dimensions as both points have. * If the two points have a different amount of coordinates, this will happen: <code>int checkDim = Math.min(this.dimension, p.getDimension());</code> *@param p1 one point *@param p2 the other point *@return distance between the two points *@throws RuntimeException */ public static double distanceBetween(PirolPoint p1, PirolPoint p2) throws RuntimeException{ int checkDim = Math.min(p2.dimension, p1.getDimension()); double checkSum = 0; for ( int i=0; i<checkDim; i++ ){ checkSum += Math.pow( p2.getCoordinate(i) - p1.getCoordinate(i), 2 ); } return Math.sqrt(checkSum); } /** * @inheritDoc */ public String toString(){ String className = this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1); String str = className + " #"+this.index+"("; String tmp; double c; for ( int i=0; i<this.dimension;i++){ try { c = this.getCoordinate(i); if (this.scaled && this.scaler!=null){ c = this.scaler.unScale(c,i); } tmp = Double.toString(c); str += tmp; } catch (Exception e) { str += "NAN"; e.printStackTrace(); } if (i!=this.dimension-1) str += ","; } str += ")"; return str; } /** * @inheritDoc */ public int compareTo(Object arg0) { if ( this.getSortFor() != ((PirolPoint)arg0).getSortFor() ){ //logger.printError("Can't compare for coordinates "+this.sortFor+" and "+((PirolPoint)arg0).getSortFor() ); return 0; } double local, remote; /* changed by oster * if getSortFor is SORTFOR_XY then sum x and y coordinate! * */ try { if (this.getSortFor()!=CoordinateComparator.SORTFOR_XY) { local = this.getCoordinate(this.sortFor); remote = ((PirolPoint)arg0).getCoordinate(((PirolPoint)arg0).getSortFor()); } else { local = this.getCoordinate(CoordinateComparator.SORTFOR_X) + this.getCoordinate(CoordinateComparator.SORTFOR_Y); remote = ((PirolPoint)arg0).getCoordinate(CoordinateComparator.SORTFOR_X) + ((PirolPoint)arg0).getCoordinate(CoordinateComparator.SORTFOR_Y); } } catch (Exception e) { //logger.printError("Can't compare for coordinate "+this.sortFor); e.printStackTrace(); return 0; } if (local < remote){ return -1; } else if (local > remote){ return 1; } return 0; } public Coordinate toCoordinate() throws RuntimeException { return PirolPoint.toCoordinate(this); } public static Coordinate toCoordinate( PirolPoint p ) throws RuntimeException { if (p.getDimension()==2) return new Coordinate(p.getX(), p.getY()); return new Coordinate(p.getX(), p.getY(), p.getZ()); } }