All pastes #2095241 Raw Edit

Vector3D class

public java v1 · immutable
#2095241 ·published 2011-11-24 06:07 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 + ")";    }}