All pastes #2095239 Raw Edit

Vector3D class

public java v1 · immutable
#2095239 ·published 2011-11-24 06:06 UTC
rendered paste body
/* * Runtime Math - Java 3D math classes * Copyright (C) 2009 Kostas Michalopoulos *  * This software is provided 'as-is', without any express or implied * warranty.  In no event will the authors be held liable for any damages * arising from the use of this software. *  * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: *  * 1. The origin of this software must not be misrepresented; you must not *    claim that you wrote the original software. If you use this software *    in a product, an acknowledgment in the product documentation would be *    appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be *    misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. *  * Kostas Michalopoulos <badsector@runtimelegend.com> */package com.runtimeterror.math.algebra;/** * A vector in 3D space. *  * @author Bad Sector */public class Vector3D{    /** Zero */	public static final int ZERO = 0;	/** X axis */	public static final int X_AXIS = 1;    /** Y axis */	public static final int Y_AXIS = 2;    /** Z axis */	public static final int Z_AXIS = 3;    /** The vector's x component */	public double x;    /** The vector's y component */	public double y;    /** The vector's z component */	public double z;		/**	 * Construct a zero vector.	 */	public Vector3D()	{	}		/**	 * Construct a vector with all components set to v.	 * 	 * @param v the value for the vector's components	 */	public Vector3D(double v)	{		x = y = z = v;	}	/**	 * Construct a clone of the given vector.	 * 	 * @param v the source vector	 */	public Vector3D(Vector3D v)	{		x = v.x;		y = v.y;		z = v.z;	}		/**	 * Construct a vector using the given coordinates.	 * 	 * @param x the x component	 * @param y the y component	 * @param z the z component	 */	public Vector3D(double x, double y, double z)	{		this.x = x;		this.y = y;		this.z = z;	}	/**	 * Construct a vector using the first 3 values of the given array.	 *	 * @param values the values array.	 */	public Vector3D(double[] values)	{	    x = values[0];	    y = values[1];	    z = values[2];	}		/**	 * Zero the vector.	 */	public void zero()	{		x = y = z = 0.0;	}		/**	 * Set the vector's components to the given value.	 * 	 * @param v the value to use	 */	public void set(double v)	{		x = y = z = v;	}		/**	 * Set the vector's component to the components of the given vector.	 * 	 * @param v the source vector	 */	public void set(Vector3D v)	{		x = v.x;		y = v.y;		z = v.z;	}	/**	 * Set the vector's components to the given coordinates.	 * 	 * @param x the x component	 * @param y the y component	 * @param z the z component	 */	public void set(double x, double y, double z)	{		this.x = x;		this.y = y;		this.z = z;	}	    /**     * Set the vector's components to the first 3 values of the given array.     *     * @param values the values array.     */    public void set(double[] values)    {        x = values[0];        y = values[1];        z = values[2];    }    /**	 * Add the given vector to this vector.	 * 	 * @param v the vector to add	 */	public void add(Vector3D v)	{		x += v.x;		y += v.y;		z += v.z;	}		/**	 * Add the vector v to this vector and store the result in vector r.	 * 	 * @param r the vector to store the result in	 * @param v the vector to add	 */	public void addTo(Vector3D r, Vector3D v)	{		r.x = x + v.x;		r.y = y + v.y;		r.z = z + v.z;	}		/**	 * Create a clone of this vector with the given vector added to it.	 * 	 * @param v the vector to add	 * @return the new vector	 */	public Vector3D added(Vector3D v)	{		return new Vector3D(x + v.x, y + v.y, z + v.z);	}	/**	 * Add the given coordinates to this vector's components.	 * 	 * @param vx the x coordinate	 * @param vy the y coordinate	 * @param vz the z coordinate	 */	public void add(double vx, double vy, double vz)	{		x += vx;		y += vy;		z += vz;	}	    /**     * Add the given coordinates to this vector's components and store the     * result in r.     *      * @param r the vector to store the result of the addition into     * @param vx the x coordinate     * @param vy the y coordinate     * @param vz the z coordinate     */	public void addTo(Vector3D r, double vx, double vy, double vz)	{		r.x = x + vx;		r.y = y + vy;		r.z = z + vz;	}	    /**     * Create a clone of this vector with the given coordinates added to its     * components.     *      * @param vx the x coordinate     * @param vy the y coordinate     * @param vz the z coordinate     * @return the new vector     */	public Vector3D added(double vx, double vy, double vz)	{		return new Vector3D(x + vx, y + vy, z + vz);	}    /**     * Subtract the given vector from this vector.     *      * @param v the vector to subtract     */	public void sub(Vector3D v)	{		x -= v.x;		y -= v.y;		z -= v.z;	}	    /**     * Subtract the vector v from this vector and store the result in the     * vector r.     *      * @param r the vector to store the subtraction result into     * @param v the vector to subtract     */	public void subTo(Vector3D r, Vector3D v)	{		r.x = x - v.x;		r.y = y - v.y;		r.z = z - v.z;	}	    /**     * Create a clone of this vector with the given vector subtracted from it.     *      * @param v the vector to subtract     * @return the new vector     */	public Vector3D subbed(Vector3D v)	{		return new Vector3D(x - v.x, y - v.y, z - v.z);	}		/**	 * Subtract the given coordinates from this vector's components.	 * 	 * @param vx the x coordinate	 * @param vy the y coordinate	 * @param vz the z coordinate	 */	public void sub(double vx, double vy, double vz)	{		x -= vx;		y -= vy;		z -= vz;	}		/**	 * Subtract the given coordinates from this vector's components and store	 * the result in the vector r.	 * 	 * @param r the vector to store the result into	 * @param vx the x coordinate	 * @param vy the y coordinate	 * @param vz the z coordinate	 */	public void subTo(Vector3D r, double vx, double vy, double vz)	{		r.x = x - vx;		r.y = y - vy;		r.z = z - vz;	}	    /**     * Create a clone of this vector with the given coordinates subtracted     * from its components.     *      * @param vx the x coordinate     * @param vy the y coordinate     * @param vz the z coordinate     * @return the new vector     */	public Vector3D subbed(double vx, double vy, double vz)	{		return new Vector3D(x - vx, y - vy, z - vz);	}		/**	 * Scale the vector.	 * 	 * @param s the scalar	 */	public void scale(double s)	{		x *= s;		y *= s;		z *= s;	}		/**	 * Scale the vector and store the result in the vector r.	 * 	 * @param r the vector to store the result into	 * @param s the scalar	 */	public void scaleTo(Vector3D r, double s)	{		r.x = x*s;		r.y = y*s;		r.z = z*s;	}	    /**     * Create a scaled clone of this vector.     *      * @param s the scalar     * @return the new vector     */	public Vector3D scaled(double s)	{		return new Vector3D(x*s, y*s, z*s);	}	    /**     * Scale this vector's components irregularly using the given vector's     * components as scalars for each coordinate.     *      * @param s the vector to use for scaling     */	public void scale(Vector3D s)	{		x *= s.x;		y *= s.y;		z *= s.z;	}	    /**     * Scale this vector's components irregularly using the given vector's     * components as scalars for each coordinate. The result will be stored in     * the vector r.     *      * @param r the vector to store the result into     * @param s the vector to use for scaling     */	public void scaleTo(Vector3D r, Vector3D s)	{		r.x = x*s.x;		r.y = y*s.y;		r.z = z*s.z;	}	    /**     * Create an irregularly scaled clone of this vector using the given     * vector's components as scalars for each coordinate.     *      * @param s the vector to use for scaling     * @return the new vector     */	public Vector3D scaled(Vector3D s)	{		return new Vector3D(x*s.x, y*s.y, z*s.z);	}	    /**     * Scale this vector's components irregularly using the given scalars for     * each component     *      * @param sx the scalar for the x component     * @param sy the scalar for the y component     * @param sz the scalar for the z component     */	public void scale(double sx, double sy, double sz)	{		x *= sx;		y *= sy;		z *= sz;	}	    /**     * Scale this vector's components irregularly using the given scalars for     * each component and store the result in the vector r.     *      * @param r the vector to store the result into     * @param sx the scalar for the x component     * @param sy the scalar for the y component     * @param sz the scalar for the z component     */	public void scaleTo(Vector3D r, double sx, double sy, double sz)	{		r.x = x*sx;		r.y = y*sy;		r.z = z*sz;	}	    /**     * Create a new irregularly scaled clone of this vector using the given     * scalars for each component.     *      * @param sx the scalar for the x component     * @param sy the scalar for the y component     * @param sz the scalar for the z component     * @return the new vector     */	public Vector3D scaled(double sx, double sy, double sz)	{		return new Vector3D(x*sx, y*sy, z*sz);	}		/**	 * Return the vector's length. Note that since this function uses a square	 * root calculation, if the actual length is not desired but only comparison	 * between lengths is needed (like, for example, which point is nearest to	 * some othe reference point), it is highly recommended to use the	 * {@link #lengthSq()} instead.	 * 	 * @return the vector's length	 */	public double length()	{		return Math.sqrt(x*x + y*y + z*z);	}		/**	 * Return the square of the vector's length. This is the preferred method	 * to use when comparing lengths.	 */	public double lengthSq()	{		return x*x + y*y + z*z;	}        /**     * Return the distance between this vector (as point) and the given vector     * (as point). Note that since this function uses a square root calculation,     * if the actual distance is not desired but only comparison between     * distances is needed (like, for example, which point is nearest to some     * othe reference point), it is highly recommended to use the     * {@link #distanceSq} instead.     *      * @param v the other point     * @return the distance between this and v     */	public double distance(Vector3D v)	{		double xx = x - v.x;		double yy = y - v.y;		double zz = z - v.z;		return Math.sqrt(xx*xx + yy*yy + zz*zz);	}        /**     * Return the square of the distance between this vector (as point) and the     * given vector (as point). This is the recommended method when comparing     * distance between two vectors because no expensive square root is     * calculated.     *      * @param v the other vector     * @return the square of the distance between this and v.     */	public double distanceSq(Vector3D v)	{		double xx = x - v.x;		double yy = y - v.y;		double zz = z - v.z;		return xx*xx + yy*yy + zz*zz;	}	    /**     * Return the distance between this vector and the point indicated by the     * given coordinates. Note that since this function uses a square root     * calculation, if the actual distance is not desired but only comparison     * between distances is needed (like, for example, which point is nearest to     * some othe reference point), it is highly recommended to use the     * {@link #distanceSq} instead.     *      * @param vx the point's x coordinate     * @param vy the point's y coordinate     * @param vz the point's z coordinate     * @return the distance between this and v     */	public double distance(double vx, double vy, double vz)	{		double xx = x - vx;		double yy = y - vy;		double zz = z - vz;		return Math.sqrt(xx*xx + yy*yy + zz*zz);	}	    /**     * Return the square of the distance between this vector (as point) and the     * point indicated by the given coordinates. This is the recommended method     * when comparing distance between two vectors because no expensive square     * root is calculated.     *      * @param vx the point's x coordinate     * @param vy the point's y coordinate     * @param vz the point's z coordinate     * @return the distance between this and v     */	public double distanceSq(double vx, double vy, double vz)	{		double xx = x - vx;		double yy = y - vy;		double zz = z - vz;		return xx*xx + yy*yy + zz*zz;	}	/**	 * Normalize this vector.	 */	public void normalize()	{		double len = length();		if (len != 0.0) {			x /= len;			y /= len;			z /= len;		}	}		/**	 * Normalize this vector and store the normalized version in the given	 * vector.	 * 	 * @param r the vector to store the normalized version into	 */	public void normalizeTo(Vector3D r)	{		double len = length();		if (len != 0.0) {			r.x = x/len;			r.y = y/len;			r.z = z/len;		} else {			r.x = r.y = r.z = 0.0;		}	}		/**	 * Create a normalized clone of this vector.	 */	public Vector3D normalized()	{		double len = length();		if (len != 0.0) {			return new Vector3D(x/len, y/len, z/len);		} else {			return new Vector3D();		}	}		/**	 * Return the dot product between this vector and the given vector.	 * 	 * @param v the other vector	 * @return the dot product	 */	public double dot(Vector3D v)	{		return x*v.x + y*v.y + z*v.z;	}		/**	 * Calculate the cross product between this vector and the given vector and	 * replace this vector's components with the result.	 * 	 * @param v the other vector	 */	public void cross(Vector3D v)	{		double nx = y*v.z - v.y*z;		double ny = z*v.x - v.z*x;		z = x*v.y - v.x*y;		x = nx;		y = ny;	}	/**	 * Calculate the cross product between this vector and the given vector and	 * store the result into the vector r.	 * 	 * @param r the vector to store the result into 	 * @param v the other vector to use for cross product calculation	 */	public void crossTo(Vector3D r, Vector3D v)	{		r.x = y*v.z - v.y*z;		r.y = z*v.x - v.z*x;		r.z = x*v.y - v.x*y;	}		/**	 * Return a new vector containing the cross product between this vector	 * and the given vector. 	 * 	 * @param v the other vector	 * @return a new vector containing the cross product	 */	public Vector3D crossed(Vector3D v)	{		return new Vector3D(y*v.z - v.y*z, z*v.x - v.z*x, x*v.y - v.x*y);	}		/**	 * Calculate the normal for the given triangle.	 * 	 * @param a the first point of the triangle	 * @param b the second point of the triangle	 * @param c the third point of the triangle	 * @return the triangle's normal	 */	public static Vector3D getNormal(Vector3D a, Vector3D b, Vector3D c)	{		double abx = b.x - a.x;		double aby = b.y - a.y;		double abz = b.z - a.z;		double acx = c.x - a.x;		double acy = c.y - a.y;		double acz = c.z - a.z;		Vector3D n = new Vector3D(aby*acz - acy*abz, abz*acx - acz*abx, abx*acy - acx*aby);		n.normalize();		return n;	}		/**	 * Return the major axis of this vector. The major axis is the axis that	 * the greatest absolute value of the vector represents. For example in the	 * vector (7, 5, 3), the major axis is {@link #X_AXIS}, for (5, 8, 6) the	 * major axis is {@link #Y_AXIS} and for (4, 8, 12) the major axis is	 * {@link #Z_AXIS}. Note that since the absolute value is used, for the	 * vector (4, -9, 6) the major axis is {@link #Y_AXIS}, not {@link #Z_AXIS}!	 * 	 * @return the major axis	 */	public int getMajorAxis()	{		double ax = Math.abs(x);		double ay = Math.abs(y);		double az = Math.abs(z);		if (ax > ay) {			if (ax > az) return X_AXIS; else return Z_AXIS;		} else {			if (ay > az) return Y_AXIS; else return Z_AXIS;		}	}	/**	 * Return the major axis for the vector that the given coordinates	 * indicate. See {@link #getMajorAxis()} for more information.	 * 	 * @param x the vector's x component	 * @param y the vector's y component	 * @param z the vector's z component	 * @return the major axis	 */	public static int getMajorAxis(double x, double y, double z)	{		double ax = Math.abs(x);		double ay = Math.abs(y);		double az = Math.abs(z);				if (ax > ay) {			if (ax > az) return X_AXIS; else return Z_AXIS;		} else {			if (ay > az) return Y_AXIS; else return Z_AXIS;		}	}		/**	 * Convert this vector to an array containing the vector's components.	 */	public double[] toArray()	{	    double[] values = new double[3];	    values[0] = x;	    values[1] = y;	    values[2] = z;	    return values;	}    /**     * Convert this vector to an array containing the vector's components.     *      * @param values the array to store the value components into     */    public void toArray(double[] values)    {        values[0] = x;        values[1] = y;        values[2] = z;    }    /**	 * Return a string representation of the vector.	 */	public String toString()	{		return "(" + x + "," + y + "," + z + ")";	}}