/* * Moonlight|3D Copyright (C) 2005 The Moonlight|3D team * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Created on Jan 5, 2005 */ package ml.math; import ml.core.exceptions.Exception; /** * This class represents a threedimensional vector and some of the operations * possible on it. * * @author gregor */ public class Vector3D implements Cloneable { public double X1, X2, X3; /** * Constructor. Does not initialise the component values. */ public Vector3D() { } /** * Constructor taking the vector components as arguments. * * @param x the x component * @param y the y component * @param z the z component */ public Vector3D(double x, double y, double z) { X1 = x; X2 = y; X3 = z; } /** * Constructor taking another Vector3D as an argument. Copies * the component values over. * * @param aVector the vector to take the initial values from */ public Vector3D(Vector3D aVector) { X1 = aVector.X1; X2 = aVector.X2; X3 = aVector.X3; } /** * Clear the component values. This sets this vector equal to the * 0 vector. */ public void clear() { X1=0.0; X2=0.0; X3=0.0; } /** * Test if this vector is mathematical equal to the given vector, * i.e. if all the components are equal. * * @param a the vector to test against * @return true if the vectors are equal */ public boolean equals(Vector3D a) { if (X1 != a.X1) { return false; } if (X2 != a.X2) { return false; } if (X3 != a.X3) { return false; } return true; } /** * Return a complete copy of this Vector3D. */ @Override public Vector3D clone() { Vector3D ret=null; try { ret = (Vector3D) super.clone(); } catch (CloneNotSupportedException e) { // cannot happen } return ret; } /** * Return the absolute value of this vector, i.e. calculate * \f$ \sqrt{x^2 + y^2 + z^2} \f$. * * @return the absolute value */ public double abs() { double abs = Math.sqrt(X1 * X1 + X2 * X2 + X3 * X3); return abs; } /** * Return a normalised copy of this vector. * * @return normalised vector */ public Vector3D norm() { Vector3D ret = new Vector3D(); double length = abs(); ret.X1 = X1 / length; ret.X2 = X2 / length; ret.X3 = X3 / length; return ret; } /** * Convert this vector to a string representation of its compoentents. * Useful for debugging. */ @Override public String toString() { return "(" + X1 + ", " + X2 + ", " + X3 + ")"; } /** * Add the given vector to this vector and return the result. * * @param a the vector to add * @return the sum of the two vectors */ public Vector3D add(Vector3D a) { Vector3D ret = new Vector3D(); ret.X1 = X1 + a.X1; ret.X2 = X2 + a.X2; ret.X3 = X3 + a.X3; return ret; } /** * Subtract the given vector from this vector and return * the result. * * @param a the vector to subtract * @return the difference between the two vectors */ public Vector3D sub(Vector3D a) { Vector3D ret = new Vector3D(); ret.X1 = X1 - a.X1; ret.X2 = X2 - a.X2; ret.X3 = X3 - a.X3; return ret; } /** * Perform scalar multiplication with the given value. * * @param a the value with which to multiply * @return the multiplied vector */ public Vector3D multiply(double a) { Vector3D ret = new Vector3D(); ret.X1 = X1 * a; ret.X2 = X2 * a; ret.X3 = X3 * a; return ret; } /** * Perform inner product between this and the given vector * and return the result. * * @param a the vector to multiply * @return the resulting value */ public double multiply(Vector3D a) { double ret = 0; ret += X1 * a.X1; ret += X2 * a.X2; ret += X3 * a.X3; return ret; } /** * Perform outer product between this and the given vector, * that is \f$a \times b\f$ and return the result. * * @param a the vector to mulitply * @return the resulting value. */ public Vector3D crossMultiply(Vector3D a) { Vector3D ret = new Vector3D(); ret.X1 = X2 * a.X3 - X3 * a.X2; ret.X2 = X3 * a.X1 - X1 * a.X3; ret.X3 = X1 * a.X2 - X2 * a.X1; return ret; } /** * Return the angle between this and the given vector. * * @param b the vector to compute the angle to * @return the angle between the vectors * @throws Exception */ public double angleTo(Vector3D b) throws Exception { if (abs() == 0 || b.abs() == 0) { throw new Exception("cannot calculate angle to null vector"); } double cosAngle = multiply(b) / (abs() * b.abs()); double angle = Math.acos(cosAngle); return angle; } }