001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/rtree/HyperBoundingBox.java $ 002 //---------------------------------------- 003 //RTree implementation. 004 //Copyright (C) 2002-2004 Wolfgang Baer - WBaer@gmx.de 005 // 006 //This library is free software; you can redistribute it and/or 007 //modify it under the terms of the GNU Lesser General Public 008 //License as published by the Free Software Foundation; either 009 //version 2.1 of the License, or (at your option) any later version. 010 // 011 //This library is distributed in the hope that it will be useful, 012 //but WITHOUT ANY WARRANTY; without even the implied warranty of 013 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 //Lesser General Public License for more details. 015 // 016 //You should have received a copy of the GNU Lesser General Public 017 //License along with this library; if not, write to the Free Software 018 //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 019 //---------------------------------------- 020 021 package org.deegree.io.rtree; 022 023 import java.io.Serializable; 024 025 /** 026 * <p> 027 * HyperBoundingBox implementing a bounding box object in the multidimensional space. 028 * </p> 029 * 030 * @author Wolfgang Baer - WBaer@gmx.de 031 */ 032 033 public class HyperBoundingBox implements Serializable { 034 035 private HyperPoint pMin; 036 037 private HyperPoint pMax; 038 039 /** 040 * Constructor.<br> 041 * Creates a HyperBoundingBox for given HyperPoints. 042 * 043 * @param pMin - 044 * min point 045 * @param pMax - 046 * max point 047 */ 048 public HyperBoundingBox( HyperPoint pMin, HyperPoint pMax ) { 049 if ( pMin.getDimension() != pMax.getDimension() ) 050 throw new IllegalArgumentException( "HyperPoints need same dimension: " + pMin.getDimension() + " != " 051 + pMax.getDimension() ); 052 053 this.pMin = pMin; 054 this.pMax = pMax; 055 } 056 057 /** 058 * Creates a null HyperBoundingBox with null HyperPoints. Mostly used internal. 059 * 060 * @param dimension - 061 * int for dimension of point 062 * @return HyperBoundingBox 063 */ 064 protected static HyperBoundingBox getNullHyperBoundingBox( int dimension ) { 065 return new HyperBoundingBox( HyperPoint.getNullHyperPoint( dimension ), 066 HyperPoint.getNullHyperPoint( dimension ) ); 067 } 068 069 /** 070 * Returns the minimum HyperPoint 071 * 072 * @return HyperPoint 073 * 074 */ 075 public HyperPoint getPMin() { 076 return pMin; 077 } 078 079 /** 080 * Returns the maximum HyperPoint 081 * 082 * @return HyperPoint 083 * 084 */ 085 public HyperPoint getPMax() { 086 return pMax; 087 } 088 089 /** 090 * Returns the dimension of this HyperBoundingBox. 091 * 092 * @return int 093 */ 094 public int getDimension() { 095 return pMin.getDimension(); 096 } 097 098 /** 099 * Tests if this and the given HyperBoundingBox overlaps. 100 * 101 * @param box - 102 * HyperBoundingBox to test 103 * @return boolean 104 */ 105 public boolean overlaps( HyperBoundingBox box ) { 106 boolean intersect = true; 107 108 for ( int i = 0; i < getDimension(); i++ ) { 109 if ( ( pMin.getCoord( i ) > box.getPMax().getCoord( i ) ) 110 || ( pMax.getCoord( i ) < box.getPMin().getCoord( i ) ) ) { 111 intersect = false; 112 break; 113 } 114 } 115 116 return intersect; 117 } 118 119 /** 120 * Tests if this contains the given HyperBoundingBox overlaps. 121 * 122 * @param box - 123 * HyperBoundingBox to test 124 * @return boolean 125 */ 126 public boolean contains( HyperBoundingBox box ) { 127 boolean contains = true; 128 129 for ( int i = 0; i < getDimension(); i++ ) { 130 if ( ( pMin.getCoord( i ) > box.getPMin().getCoord( i ) ) 131 || ( pMax.getCoord( i ) < box.getPMax().getCoord( i ) ) ) { 132 contains = false; 133 break; 134 } 135 } 136 137 return contains; 138 } 139 140 /** 141 * Computes the area (over all dimension) of this. 142 * 143 * @return double 144 */ 145 public double getArea() { 146 double area = 1; 147 148 for ( int i = 0; i < pMin.getDimension(); i++ ) 149 area = area * ( pMax.getCoord( i ) - pMin.getCoord( i ) ); 150 151 return area; 152 } 153 154 /** 155 * Computes the union of this with the given HyperBoundingBox. 156 * 157 * @param box - 158 * given HyperBoundingBox 159 * @return HyperBoundingBox 160 */ 161 public HyperBoundingBox unionBoundingBox( HyperBoundingBox box ) { 162 163 if ( this.getDimension() != box.getDimension() ) 164 throw new IllegalArgumentException( "HyperBoundingBoxes need same dimension " + this.getDimension() 165 + " != " + box.getDimension() ); 166 167 if ( this.equals( HyperBoundingBox.getNullHyperBoundingBox( this.getDimension() ) ) ) 168 return box; 169 if ( box.equals( HyperBoundingBox.getNullHyperBoundingBox( this.getDimension() ) ) ) 170 return this; 171 172 double[] min = new double[this.getDimension()]; 173 double[] max = new double[this.getDimension()]; 174 175 for ( int i = 0; i < this.getDimension(); i++ ) { 176 177 if ( this.getPMin().getCoord( i ) <= box.getPMin().getCoord( i ) ) { 178 min[i] = this.getPMin().getCoord( i ); 179 } else { 180 min[i] = box.getPMin().getCoord( i ); 181 } 182 if ( this.getPMax().getCoord( i ) >= box.getPMax().getCoord( i ) ) { 183 max[i] = this.getPMax().getCoord( i ); 184 } else { 185 max[i] = box.getPMax().getCoord( i ); 186 } 187 } 188 return new HyperBoundingBox( new HyperPoint( min ), new HyperPoint( max ) ); 189 } 190 191 /** 192 * Computes the minimal distance square of this to the given HyperPoint. After Roussopoulos 193 * Nick: Nearest Neighbor Queries - MINDIST 194 * 195 * @param point - 196 * HyperPoint 197 * @return double 198 */ 199 public double minDist( HyperPoint point ) { 200 double min = 0; 201 double ri = 0; 202 203 for ( int i = 0; i < point.getDimension(); i++ ) { 204 if ( point.getCoord( i ) < this.pMin.getCoord( i ) ) { 205 ri = this.pMin.getCoord( i ); 206 } else { 207 if ( point.getCoord( i ) > this.pMax.getCoord( i ) ) { 208 ri = this.pMax.getCoord( i ); 209 } else { 210 ri = point.getCoord( i ); 211 } 212 } 213 min = min + Math.pow( point.getCoord( i ) - ri, 2 ); 214 } 215 return min; 216 } 217 218 /** 219 * Deep copy. 220 * 221 * @see java.lang.Object#clone() 222 */ 223 protected Object clone() { 224 return new HyperBoundingBox( (HyperPoint) pMin.clone(), (HyperPoint) pMax.clone() ); 225 } 226 227 /** 228 * Builds a String representation of the HyperBoundingBox. 229 * 230 * @return String 231 */ 232 public String toString() { 233 return "BOX: P-Min (" + pMin.toString() + "), P-Max (" + pMax.toString() + ")"; 234 } 235 236 /** 237 * Implements equals 238 * 239 * @see java.lang.Object#equals(java.lang.Object) 240 */ 241 public boolean equals( Object obj ) { 242 HyperBoundingBox box = (HyperBoundingBox) obj; 243 return ( this.pMin.equals( box.pMin ) && this.pMax.equals( box.pMax ) ); 244 } 245 }