001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.ui.geom; 033 034/** 035 * 3D point. 036 * 037 * A Point3 is a 3D location in an affine space described by three values along 038 * the X, the Y and the Z axis. Note the difference with Vector3 wich is defined 039 * as an array and ensures that the three coordinates X, Y and Z are consecutive 040 * in memory. Here there are three separate attributes. Further, a point has no 041 * vector arithmetic bound to it (to points cannot be added, this would have no 042 * mathematical meaning). 043 * 044 * @author Antoine Dutot 045 * @since 19990829 046 * @version 0.1 047 */ 048public class Point3 extends Point2 implements java.io.Serializable { 049 // Attributes 050 051 private static final long serialVersionUID = 5971336344439693816L; 052 053 /** 054 * Z axis value. 055 */ 056 public double z; 057 058 // Attributes -- Shared 059 060 /** 061 * Specific point at (0,0,0). 062 */ 063 public static final Point3 NULL_POINT3 = new Point3(0, 0, 0); 064 065 // Constructors 066 067 /** 068 * New 3D point at(0,0,0). 069 */ 070 public Point3() { 071 } 072 073 /** 074 * New 3D point at (x,y,0). 075 */ 076 public Point3(double x, double y) { 077 set(x, y, 0); 078 } 079 080 /** 081 * New 3D point at(x,y,z). 082 */ 083 public Point3(double x, double y, double z) { 084 set(x, y, z); 085 } 086 087 /** 088 * New copy of other. 089 */ 090 public Point3(Point3 other) { 091 copy(other); 092 } 093 094 public Point3(Vector3 vec) { 095 copy(vec); 096 } 097 098 public Point3(float data[]) { 099 this(0, data); 100 } 101 102 public Point3(double data[]) { 103 this(0, data); 104 } 105 106 public Point3(int start, float data[]) { 107 if(data != null) { 108 if(data.length>start+0) x = data[start+0]; 109 if(data.length>start+1) y = data[start+1]; 110 if(data.length>start+2) z = data[start+2]; 111 } 112 } 113 114 public Point3(int start, double data[]) { 115 if(data != null) { 116 if(data.length>start+0) x = data[start+0]; 117 if(data.length>start+1) y = data[start+1]; 118 if(data.length>start+2) z = data[start+2]; 119 } 120 } 121 122 // Predicates 123 124 /** 125 * Are all components to zero?. 126 */ 127 @Override 128 public boolean isZero() { 129 return (x == 0 && y == 0 && z == 0); 130 } 131 132 // /** 133 // * Is other equal to this ? 134 // */ 135 // public boolean 136 // equals( const Point3 < double > & other ) const 137 // { 138 // return( x == other.x 139 // and y == other.y 140 // and z == other.z ); 141 // } 142 143 /** 144 * Create a new point linear interpolation of this and <code>other</code>. 145 * The new point is located between this and <code>other</code> if 146 * <code>factor</code> is between 0 and 1 (0 yields this point, 1 yields the 147 * <code>other</code> point). 148 */ 149 public Point3 interpolate(Point3 other, double factor) { 150 Point3 p = new Point3(x + ((other.x - x) * factor), y 151 + ((other.y - y) * factor), z + ((other.z - z) * factor)); 152 153 return p; 154 } 155 156 /** 157 * Distance between this and <code>other</code>. 158 */ 159 public double distance(Point3 other) { 160 double xx = other.x - x; 161 double yy = other.y - y; 162 double zz = other.z - z; 163 return Math.abs(Math.sqrt((xx * xx) + (yy * yy) + (zz * zz))); 164 } 165 166 /** 167 * Distance between this and point (x,y,z). 168 */ 169 public double distance(double x, double y, double z) { 170 double xx = x - this.x; 171 double yy = y - this.y; 172 double zz = z - this.z; 173 return Math.abs(Math.sqrt((xx * xx) + (yy * yy) + (zz * zz))); 174 } 175 176 // Commands 177 178 /** 179 * Make this a copy of other. 180 */ 181 public void copy(Point3 other) { 182 x = other.x; 183 y = other.y; 184 z = other.z; 185 } 186 187 public void copy(Vector3 vec) { 188 x = vec.data[0]; 189 y = vec.data[1]; 190 z = vec.data[2]; 191 } 192 193 /** 194 * Like #moveTo(). 195 */ 196 public void set(double x, double y, double z) { 197 this.x = x; 198 this.y = y; 199 this.z = z; 200 } 201 202 // Commands -- moving 203 204 /** 205 * Move to absolute position (x,y,z). 206 */ 207 public void moveTo(double x, double y, double z) { 208 this.x = x; 209 this.y = y; 210 this.z = z; 211 } 212 213 /** 214 * Move of given vector(dx,dy,dz). 215 */ 216 public void move(double dx, double dy, double dz) { 217 this.x += dx; 218 this.y += dy; 219 this.z += dz; 220 } 221 222 /** 223 * Move of given point <code>p</code>. 224 */ 225 public void move(Point3 p) { 226 this.x += p.x; 227 this.y += p.y; 228 this.z += p.z; 229 } 230 231 /** 232 * Move of given vector d. 233 */ 234 public void move(Vector3 d) { 235 this.x += d.data[0]; 236 this.y += d.data[1]; 237 this.z += d.data[2]; 238 } 239 240 /** 241 * Move in depth of dz. 242 */ 243 public void moveZ(double dz) { 244 z += dz; 245 } 246 247 /** 248 * Scale of factor (sx,sy,sz). 249 */ 250 public void scale(double sx, double sy, double sz) { 251 x *= sx; 252 y *= sy; 253 z *= sz; 254 } 255 256 /** 257 * Scale by factor s. 258 */ 259 public void scale(Point3 s) { 260 x *= s.x; 261 y *= s.y; 262 z *= s.z; 263 } 264 265 /** 266 * Scale by factor s. 267 */ 268 public void scale(Vector3 s) { 269 x *= s.data[0]; 270 y *= s.data[1]; 271 z *= s.data[2]; 272 } 273 274 /** 275 * Scale by a given scalar. 276 * 277 * @param scalar 278 * The multiplier. 279 */ 280 public void scale(double scalar) { 281 x *= scalar; 282 y *= scalar; 283 z *= scalar; 284 } 285 286 /** 287 * Change only depth at absolute coordinate z. 288 */ 289 public void setZ(double z) { 290 this.z = z; 291 } 292 293 /** 294 * Exchange the values of this and other. 295 */ 296 public void swap(Point3 other) { 297 double t; 298 299 if (other != this) { 300 t = this.x; 301 this.x = other.x; 302 other.x = t; 303 304 t = this.y; 305 this.y = other.y; 306 other.y = t; 307 308 t = this.z; 309 this.z = other.z; 310 other.z = t; 311 } 312 } 313 314 // Commands -- misc. 315 316 @Override 317 public String toString() { 318 StringBuffer buf; 319 320 buf = new StringBuffer("Point3["); 321 322 buf.append(x); 323 buf.append('|'); 324 buf.append(y); 325 buf.append('|'); 326 buf.append(z); 327 buf.append("]"); 328 329 return buf.toString(); 330 } 331}