/* * Copyright (c) 2005–2012 Goethe Center for Scientific Computing - Simulation and Modelling (G-CSC Frankfurt) * Copyright (c) 2012-2015 Goethe Center for Scientific Computing - Computational Neuroscience (G-CSC Frankfurt) * * This file is part of NeuGen. * * NeuGen is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * see: http://opensource.org/licenses/LGPL-3.0 * file://path/to/NeuGen/LICENSE * * NeuGen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * This version of NeuGen includes copyright notice and attribution requirements. * According to the LGPL this information must be displayed even if you modify * the source code of NeuGen. The copyright statement/attribution may not be removed. * * Attribution Requirements: * * If you create derived work you must do the following regarding copyright * notice and author attribution. * * Add an additional notice, stating that you modified NeuGen. In addition * you must cite the publications listed below. A suitable notice might read * "NeuGen source code modified by YourName 2012". * * Note, that these requirements are in full accordance with the LGPL v3 * (see 7. Additional Terms, b). * * Publications: * * S. Wolf, S. Grein, G. Queisser. NeuGen 2.0 - * Employing NeuGen 2.0 to automatically generate realistic * morphologies of hippocapal neurons and neural networks in 3D. * Neuroinformatics, 2013, 11(2), pp. 137-148, doi: 10.1007/s12021-012-9170-1 * * * J. P. Eberhard, A. Wanner, G. Wittum. NeuGen - * A tool for the generation of realistic morphology * of cortical neurons and neural networks in 3D. * Neurocomputing, 70(1-3), pp. 327-343, doi: 10.1016/j.neucom.2006.01.028 * */ /** * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use, * copy, modify and redistribute is granted, provided that this copyright * notice is retained and the author is given credit whenever appropriate. * * This software is distributed "as is", without any warranty, including * any implied warranty of merchantability or fitness for a particular * use. The author assumes no responsibility for, and shall not be liable * for, any special, indirect, or consequential damages, or any damages * whatsoever, arising out of or in connection with the use of this * software. */ package org.neugen.quickhull3d; import java.util.Random; /** * A three-element vector. This class is actually a reduced version of the * Vector3d class contained in the author's matlib package (which was partly * inspired by javax.vecmath). Only a mininal number of methods which are * relevant to convex hull generation are supplied here. * * @author John E. Lloyd, Fall 2004 */ public class Vector3d { /** * Precision of a double. */ static private final double DOUBLE_PREC = 2.2204460492503131e-16; /** * First element */ public double x; /** * Second element */ public double y; /** * Third element */ public double z; /** * Creates a 3-vector and initializes its elements to 0. */ public Vector3d() { } /** * Creates a 3-vector by copying an existing one. * * @param v * vector to be copied */ public Vector3d(Vector3d v) { set(v); } /** * Creates a 3-vector with the supplied element values. * * @param x * first element * @param y * second element * @param z * third element */ public Vector3d(double x, double y, double z) { set(x, y, z); } /** * Gets a single element of this vector. Elements 0, 1, and 2 correspond * to x, y, and z. * * @param i * element index * @return element value throws ArrayIndexOutOfBoundsException if i is * not in the range 0 to 2. */ public double get(int i) { switch (i) { case 0: { return x; } case 1: { return y; } case 2: { return z; } default: { throw new ArrayIndexOutOfBoundsException(i); } } } /** * Sets a single element of this vector. Elements 0, 1, and 2 correspond * to x, y, and z. * * @param i * element index * @param value * element value * element value throws ArrayIndexOutOfBoundsException if i is * not in the range 0 to 2. */ public void set(int i, double value) { switch (i) { case 0: { x = value; break; } case 1: { y = value; break; } case 2: { z = value; break; } default: { throw new ArrayIndexOutOfBoundsException(i); } } } /** * Sets the values of this vector to those of v1. * * @param v1 * vector whose values are copied */ public void set(Vector3d v1) { x = v1.x; y = v1.y; z = v1.z; } /** * Adds vector v1 to v2 and places the result in this vector. * * @param v1 * left-hand vector * @param v2 * right-hand vector */ public void add(Vector3d v1, Vector3d v2) { x = v1.x + v2.x; y = v1.y + v2.y; z = v1.z + v2.z; } /** * Adds this vector to v1 and places the result in this vector. * * @param v1 * right-hand vector */ public void add(Vector3d v1) { x += v1.x; y += v1.y; z += v1.z; } /** * Subtracts vector v1 from v2 and places the result in this vector. * * @param v1 * left-hand vector * @param v2 * right-hand vector */ public void sub(Vector3d v1, Vector3d v2) { x = v1.x - v2.x; y = v1.y - v2.y; z = v1.z - v2.z; } /** * Subtracts v1 from this vector and places the result in this vector. * * @param v1 * right-hand vector */ public void sub(Vector3d v1) { x -= v1.x; y -= v1.y; z -= v1.z; } /** * Scales the elements of this vector by <code>s</code>. * * @param s * scaling factor */ public void scale(double s) { x = s * x; y = s * y; z = s * z; } /** * Scales the elements of vector v1 by <code>s</code> and places the * results in this vector. * * @param s * scaling factor * @param v1 * vector to be scaled */ public void scale(double s, Vector3d v1) { x = s * v1.x; y = s * v1.y; z = s * v1.z; } /** * Returns the 2 norm of this vector. This is the square root of the sum * of the squares of the elements. * * @return vector 2 norm */ public double norm() { return Math.sqrt(x * x + y * y + z * z); } /** * Returns the square of the 2 norm of this vector. This is the sum of * the squares of the elements. * * @return square of the 2 norm */ public double normSquared() { return x * x + y * y + z * z; } /** * Returns the Euclidean distance between this vector and vector v. * * @return distance between this vector and v */ public double distance(Vector3d v) { double dx = x - v.x; double dy = y - v.y; double dz = z - v.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); } /** * Returns the squared of the Euclidean distance between this vector and * vector v. * * @return squared distance between this vector and v */ public double distanceSquared(Vector3d v) { double dx = x - v.x; double dy = y - v.y; double dz = z - v.z; return (dx * dx + dy * dy + dz * dz); } /** * Returns the dot product of this vector and v1. * * @param v1 * right-hand vector * @return dot product */ public double dot(Vector3d v1) { return x * v1.x + y * v1.y + z * v1.z; } /** * Normalizes this vector in place. */ public void normalize() { double lenSqr = x * x + y * y + z * z; double err = lenSqr - 1; if (err > (2 * DOUBLE_PREC) || err < -(2 * DOUBLE_PREC)) { double len = Math.sqrt(lenSqr); x /= len; y /= len; z /= len; } } /** * Sets the elements of this vector to zero. */ public void setZero() { x = 0; y = 0; z = 0; } /** * Sets the elements of this vector to the prescribed values. * * @param x * value for first element * @param y * value for second element * @param z * value for third element */ public void set(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } /** * Computes the cross product of v1 and v2 and places the result in this * vector. * * @param v1 * left-hand vector * @param v2 * right-hand vector */ public void cross(Vector3d v1, Vector3d v2) { double tmpx = v1.y * v2.z - v1.z * v2.y; double tmpy = v1.z * v2.x - v1.x * v2.z; double tmpz = v1.x * v2.y - v1.y * v2.x; x = tmpx; y = tmpy; z = tmpz; } /** * Sets the elements of this vector to uniformly distributed random * values in a specified range, using a supplied random number * generator. * * @param lower * lower random value (inclusive) * @param upper * upper random value (exclusive) * @param generator * random number generator */ protected void setRandom(double lower, double upper, Random generator) { double range = upper - lower; x = generator.nextDouble() * range + lower; y = generator.nextDouble() * range + lower; z = generator.nextDouble() * range + lower; } /** * Returns a string representation of this vector, consisting of the x, * y, and z coordinates. * * @return string representation */ public String toString() { return x + " " + y + " " + z; } }