001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.math.geometry.point; 031 032import java.io.DataInput; 033import java.io.DataOutput; 034import java.io.IOException; 035import java.io.PrintWriter; 036import java.util.Scanner; 037 038import Jama.Matrix; 039 040/** 041 * Simple concrete implementation of a three dimensional point. 042 * 043 * @author Jonathon Hare 044 */ 045public class Point3dImpl implements Point3d, Cloneable { 046 /** 047 * The x-ordinate 048 */ 049 public double x; 050 051 /** 052 * The y-ordinate 053 */ 054 public double y; 055 056 /** 057 * The z-ordinate 058 */ 059 public double z; 060 061 /** 062 * Construct a Point3dImpl with the given (x, y, z) coordinates 063 * 064 * @param x 065 * x-ordinate 066 * @param y 067 * y-ordinate 068 * @param z 069 * z-ordinate 070 */ 071 public Point3dImpl(double x, double y, double z) 072 { 073 this.x = x; 074 this.y = y; 075 this.z = z; 076 } 077 078 /** 079 * Construct a Point3dImpl with the given (x, y, z) coordinates packed into 080 * an array 081 * 082 * @param array 083 * the coordinates ([x, y, z]) 084 */ 085 public Point3dImpl(double[] array) 086 { 087 this.x = array[0]; 088 this.y = array[1]; 089 this.z = array[2]; 090 } 091 092 /** 093 * Construct a Point3dImpl with the (x,y,z) coordinates given via another 094 * point. 095 * 096 * @param p 097 * The point to copy from. 098 */ 099 public Point3dImpl(Point3d p) 100 { 101 this.copyFrom(p); 102 } 103 104 /** 105 * Construct a Point3dImpl at the origin. 106 */ 107 public Point3dImpl() 108 { 109 // do nothing 110 } 111 112 @Override 113 public double getX() { 114 return x; 115 } 116 117 @Override 118 public void setX(double x) { 119 this.x = x; 120 } 121 122 @Override 123 public double getY() { 124 return y; 125 } 126 127 @Override 128 public void setY(double y) { 129 this.y = y; 130 } 131 132 @Override 133 public double getZ() { 134 return z; 135 } 136 137 @Override 138 public void setZ(double z) { 139 this.z = z; 140 } 141 142 @Override 143 public void copyFrom(Point3d p) 144 { 145 this.x = p.getX(); 146 this.y = p.getY(); 147 this.z = p.getZ(); 148 } 149 150 @Override 151 public String toString() { 152 return "(" + x + "," + y + "," + z + ")"; 153 } 154 155 @Override 156 public Point3dImpl clone() { 157 Point3dImpl clone; 158 try { 159 clone = (Point3dImpl) super.clone(); 160 } catch (final CloneNotSupportedException e) { 161 return null; 162 } 163 return clone; 164 } 165 166 @Override 167 public Double getOrdinate(int dimension) { 168 if (dimension == 0) 169 return x; 170 if (dimension == 1) 171 return y; 172 return z; 173 } 174 175 @Override 176 public int getDimensions() { 177 return 3; 178 } 179 180 @Override 181 public void translate(double x, double y, double z) { 182 this.x += x; 183 this.y += y; 184 this.z += z; 185 } 186 187 @Override 188 public void translate(Point3d v) { 189 this.x += v.getX(); 190 this.y += v.getY(); 191 this.z += v.getZ(); 192 } 193 194 @Override 195 public Point3dImpl transform(Matrix transform) { 196 if (transform.getRowDimension() == 4) { 197 double xt = transform.get(0, 0) * getX() + transform.get(0, 1) * getY() + transform.get(0, 2) * getZ() 198 + transform.get(0, 3); 199 double yt = transform.get(1, 0) * getX() + transform.get(1, 1) * getY() + transform.get(1, 2) * getZ() 200 + transform.get(1, 3); 201 double zt = transform.get(2, 0) * getX() + transform.get(2, 1) * getY() + transform.get(2, 2) * getZ() 202 + transform.get(2, 3); 203 final double ft = transform.get(3, 0) * getX() + transform.get(3, 1) * getY() + transform.get(3, 2) * getZ() 204 + transform.get(3, 3); 205 206 xt /= ft; 207 yt /= ft; 208 zt /= ft; 209 210 return new Point3dImpl(xt, yt, zt); 211 } 212 throw new IllegalArgumentException("Transform matrix has unexpected size"); 213 } 214 215 @Override 216 public boolean equals(Object o) { 217 if (!(o instanceof Point3d)) 218 return false; 219 final Point3d p = (Point3d) o; 220 return p.getX() == this.x && p.getY() == this.y && p.getZ() == this.getZ(); 221 } 222 223 @Override 224 public int hashCode() 225 { 226 return toString().hashCode(); 227 } 228 229 @Override 230 public Point3d minus(Point3d a) { 231 return new Point3dImpl(this.x - a.getX(), this.y - a.getY(), this.z - a.getZ()); 232 } 233 234 @Override 235 public void readASCII(Scanner in) throws IOException { 236 x = in.nextDouble(); 237 y = in.nextDouble(); 238 z = in.nextDouble(); 239 } 240 241 @Override 242 public String asciiHeader() { 243 return "Point3d"; 244 } 245 246 @Override 247 public void readBinary(DataInput in) throws IOException { 248 x = in.readDouble(); 249 y = in.readDouble(); 250 z = in.readDouble(); 251 } 252 253 @Override 254 public byte[] binaryHeader() { 255 return "PT3D".getBytes(); 256 } 257 258 @Override 259 public void writeASCII(PrintWriter out) throws IOException { 260 out.format("%f %f %f", x, y, z); 261 } 262 263 @Override 264 public void writeBinary(DataOutput out) throws IOException { 265 out.writeDouble(x); 266 out.writeDouble(y); 267 out.writeDouble(z); 268 } 269 270 @Override 271 public Point3dImpl copy() { 272 return clone(); 273 } 274 275 /** 276 * Create a random point in ([0..1], [0..1], [0..1]). 277 * 278 * @return random point. 279 */ 280 public static Point3d createRandomPoint() { 281 return new Point3dImpl(Math.random(), Math.random(), Math.random()); 282 } 283 284 @Override 285 public void setOrdinate(int dimension, Number value) { 286 if (dimension == 0) 287 x = value.floatValue(); 288 if (dimension == 1) 289 y = value.floatValue(); 290 if (dimension == 2) 291 z = value.floatValue(); 292 } 293}