Package aspect.util

Source Code of aspect.util.Vector3

/*
* Copyright (C) 2014 MillerV
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package aspect.util;

import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.vector.Vector3f;

/**
* A vector quantity with 3 components. This class also contains static utility
* methods for performing mathematical operations on 3-component vectors.
* Instances are mutable, so copy() should be used whenever a separate copy is
* needed.
*
* @author MillerV
*/
public class Vector3 extends Vector3f {

    /**
     * Return a Vector3 with the components (0, 0, 0).
     *
     * @return the origin
     */
    public static Vector3 zero() {
        return new Vector3(0, 0, 0);
    }

    public static Vector3 one() {
        return new Vector3(1, 1, 1);
    }

    public static Vector3 xAxis() {
        return new Vector3(1, 0, 0);
    }

    public static Vector3 yAxis() {
        return new Vector3(0, 1, 0);
    }

    public static Vector3 zAxis() {
        return new Vector3(0, 0, 1);
    }

    /**
     * Create a new Vector3 with the specified x, y, and z components.
     *
     * @param x the x component of the vector
     * @param y the y component of the vector
     * @param z the z component of the vector
     */
    public Vector3(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
   
    public void set(Vector3 v) {
        this.x = v.x;
        this.y = v.y;
        this.z = v.z;
    }

    public Vector3(float val) {
        this(val, val, val);
    }

    public Vector3(float x, float y) {
        this(x, y, 0);
    }

    /**
     * Copy this Vector3.
     *
     * @return a copy of this Vector3
     */
    public Vector3 copy() {
        return new Vector3(x, y, z);
    }

    /**
     * Get the magnitude of this Vector3, or its distance from the origin.
     *
     * @return the magnitude of this Vector3
     */
    public float mag() {
        return mag(this);
    }
   
    public float mag2() {
        return mag2(this);
    }

    /**
     * Get a Vector2 whose x component is equal to this Vector3's x component
     * and whose y component is equal to this Vector3's y component.
     *
     * @return a Vector2 with the (x, y) components of this Vector3
     */
    public Vector2 xy() {
        return new Vector2(x, y);
    }

    /**
     * Get a Vector2 whose x component is equal to this Vector3's y component
     * and whose y component is equal to this Vector3's z component.
     *
     * @return a Vector2 with the (y, z) components of this Vector3
     */
    public Vector2 zy() {
        return new Vector2(z, y);
    }

    /**
     * Get a Vector2 whose x component is equal to this Vector3's x component
     * and whose y component is equal to this Vector3's z component.
     *
     * @return a Vector2 with the (x, z) components of this Vector3
     */
    public Vector2 xz() {
        return new Vector2(x, z);
    }
   
    public Vector3 component(Vector3 axis) {
        return new Vector3(x * axis.x, y * axis.y, z * axis.z);
    }
   
    public Vector3 project1D(Vector3 line) {
        return line.times(dot(this, line) / dot(line, line));
    }
   
    public Vector3 project1D(Vector3 a, Vector3 b) {
        Vector3 ab = b.minus(a);
        Vector3 ap = this.minus(a);
       
        return a.plus(ap.project1D(ab));
    }

    /**
     * Find the sum of this Vector3 and another Vector3.
     *
     * @param v the other Vector3
     * @return the sum of the two vectors
     */
    public Vector3 plus(Vector3 v) {
        return add(this, v);
    }

    /**
     * Find the difference between this Vector3 and another Vector3.
     *
     * @param v the other Vector3
     * @return the sum of the two vectors
     */
    public Vector3 minus(Vector3 v) {
        return subtract(this, v);
    }

    /**
     * Get a Vector3 whose components are equal to the opposite of this
     * Vector3's components, resulting in equal magnitude and opposite
     * direction.
     *
     * @return the negated Vector3
     */
    @Override
    public Vector3 negate() {
        return negate(this);
    }

    /**
     * Get a Vector3 whose components are equal to this Vector3's components
     * multiplied by the given value.
     *
     * @param f the multiplier
     * @return the multiplied Vector3
     */
    public Vector3 times(float f) {
        return multiply(this, f);
    }

    /**
     * Get a Vector3 whose magnitude is equal to this vector's magnitude and
     * whose direction is equal to this vector's direction plus the given
     * angles.
     *
     * @param angles the angles to add
     * @return the rotated vector
     */
    public Vector3 rotate(Angles angles) {
        return fromAngles(angles.plus(dir()), mag());
    }

    /**
     * Get the direction of this vector as a set of Angles.
     *
     * @return the direction of this vector
     */
    public Angles dir() {
        return dir(this);
    }

    /**
     * Get a Vector3 whose magnitude is 1 and whose direction is equal to the
     * direction of this Vector3.
     *
     * @return the normalized Vector3
     */
    public Vector3 normalize() {
        return normalize(this);
    }

    public Vector3 abs() {
        return new Vector3(Math.abs(x), Math.abs(y), Math.abs(z));
    }

    /**
     * Convert the Cartesian components of a Vector3 to pitch and yaw. Roll will
     * always be 0 because a vector has no roll.
     *
     * @param v the Vector3 to convert
     * @return the direction of this vector
     */
    public static Angles dir(Vector3 v) {
        float pitch = Trig.asin(v.y / v.mag());
        float yaw = Trig.atan2(v.x, -v.z);

        return new Angles(pitch, yaw, 0);
    }

    /**
     * Find the Angles pointing from one Vector3 to another.
     *
     * @param v1 the first Vector3
     * @param v2 the second Vector3
     * @return the angles pointing from v1 to v2
     */
    public static Angles toAngles(Vector3 v1, Vector3 v2) {
        return dir(v2.minus(v1));
    }

    /**
     * Construct a new Vector3 from standard form (direction, magnitude).
     *
     * @param direction the direction of the new Vector3
     * @param magnitude the magnitude of the new Vector3
     * @return a new Vector3 with the given direction and magnitude
     */
    public static Vector3 fromAngles(Angles direction, float magnitude) {
        float x = Trig.cos(direction.pitch) * Trig.sin(direction.yaw) * magnitude;
        float z = -Trig.cos(direction.pitch) * Trig.cos(direction.yaw) * magnitude;
        float y = Trig.sin(direction.pitch) * magnitude;

        return new Vector3(x, y, z);
    }

    private static Vector3 move(Vector3 dir, float amount, boolean flat) {
        if (flat) {
            Angles angles = dir.dir();
            Vector2 newPos = Vector2.fromAngle(angles.yaw, amount);
            return new Vector3(newPos.x, 0, newPos.y);
        } else {
            return dir.times(amount);
        }
    }

    /**
     * Get a Vector3 that represents a move along the local negative z axis of
     * the given Vector3. If flat is set to true, the new Vector3 will only
     * represent a move along the absolute x and z axes.
     *
     * @param dir the forward direction
     * @param amount the the amount to move forward
     * @param flat whether the new Vector3 should have 0 as the y component
     * @return the vector representing a move
     */
    public static Vector3 moveForward(Vector3 dir, float amount, boolean flat) {
        return move(dir, amount, flat);
    }

    /**
     * Get a Vector3 that represents a move along the local positive z axis of
     * the given Vector3. If flat is set to true, the new Vector3 will only
     * represent a move along the absolute x and z axes.
     *
     * @param dir the forward direction
     * @param amount the amount to move backward
     * @param flat whether the new Vector3 should have 0 as the y component
     * @return the vector representing a move
     */
    public static Vector3 moveBackward(Vector3 dir, float amount, boolean flat) {
        return move(dir, -amount, flat);
    }

    public static Vector3 moveUp(Vector3 dir, float amount) {
        Vector3 localX = cross(dir, yAxis());
        return move(cross(dir, localX), amount, false);
    }

    public static Vector3 moveDown(Vector3 dir, float amount) {
        return moveUp(dir, -amount);
    }

    /**
     * Get a Vector3 that represents a move along the local negative x axis of
     * the given Vector3. If flat is set to true, the new Vector3 will only
     * represent a move along the absolute x and z axes.
     *
     * @param dir the forward direction
     * @param amount the amount to move left
     * @param flat whether the new Vector3 should have 0 as the y component
     * @return the vector representing a move
     */
    public static Vector3 strafeLeft(Vector3 dir, float amount, boolean flat) {
        return move(cross(dir, yAxis()), -amount, flat);
    }

    /**
     * Get a Vector3 that represents a move along the local positive x axis of
     * the given Vector3. If flat is set to true, the new Vector3 will only
     * represent a move along the absolute x and z axes.
     *
     * @param dir the forward direction
     * @param amount the amount to move right
     * @param flat whether the new Vector3 should have 0 as the y component
     * @return the vector representing a move
     */
    public static Vector3 strafeRight(Vector3 dir, float amount, boolean flat) {
        return move(cross(dir, yAxis()), amount, flat);
    }
   
    public Vector3 rotateTowards(Vector3 target, float maxAngle) {
        float angle = angle(this, target);
       
        if (angle <= maxAngle) {
            return target;
        } else {
            Vector3 axis = cross(this, target).normalize();
            Matrix4x4 m = Matrix4x4.identity().rotate(axis, maxAngle);
            return m.transformVector(this);
        }
    }

    /**
     * Find the sum of two Vector3s.
     *
     * @param v1 the first Vector3
     * @param v2 the second Vector3
     * @return the sum p1 + p2
     */
    public static Vector3 add(Vector3 v1, Vector3 v2) {
        return new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
    }

    /**
     * Find the difference of two Vector3s.
     *
     * @param s the subtrahend Vector3
     * @param m the minuend Vector3
     * @return the difference s - m
     */
    public static Vector3 subtract(Vector3 s, Vector3 m) {
        return new Vector3(s.x - m.x, s.y - m.y, s.z - m.z);
    }

    /**
     * Get a Vector3 whose components are equal to the given Vector3's
     * components multiplied by -1.
     *
     * @param v the Vector3 to negate
     * @return the negated Vector3
     */
    public static Vector3 negate(Vector3 v) {
        return new Vector3(-v.x, -v.y, -v.z);
    }

    /**
     * Find the dot product of two Vector3s, or
     * <code>v1.x * v2.x + v1.y * v2.y + v1.z * v2.z</code>
     *
     * @param v1 the first Vector3
     * @param v2 the second Vector3
     * @return the dot product of v1 and v2
     */
    public static float dot(Vector3 v1, Vector3 v2) {
        return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
    }

    /**
     * Find the cross product of two Vector3s, a Vector3 perpendicular to the
     * plane containing v1 and v2.
     *
     * @param v1 the first Vector3
     * @param v2 the second Vector3
     * @return the cross product
     */
    public static Vector3 cross(Vector3 v1, Vector3 v2) {
        float nx = v1.y * v2.z - v1.z * v2.y;
        float ny = v1.z * v2.x - v1.x * v2.z;
        float nz = v1.x * v2.y - v1.y * v2.x;
        return new Vector3(nx, ny, nz);
    }

    /**
     * Get a Vector3 whose magnitude is 1 and whose direction is the sum of the
     * directions of the given Vector3s.
     *
     * @param v1 the first Vector
     * @param v2 the second Vector
     * @return the angular sum
     */
    public static Vector3 addAngular(Vector3 v1, Vector3 v2) {
        Angles a1 = dir(v1);
        Angles a2 = dir(v2);

        return fromAngles(Angles.add(a1, a2), 1);
    }

    public static float angle(Vector3 v1, Vector3 v2) {
        return Vector3f.angle(v1, v2);
    }

    /**
     * Get a Vector3 whose components are equal to the components of the given
     * Vector3 multiplied by the given value.
     *
     * @param v the Vector3 to multiply
     * @param scale the multiplier
     * @return the scaled Vector3
     */
    public static Vector3 multiply(Vector3 v, float scale) {
        return new Vector3(v.x * scale, v.y * scale, v.z * scale);
    }

    public static Vector3 divide(Vector3 v, float scale) {
        return new Vector3(v.x / scale, v.y / scale, v.z / scale);
    }

    public static Vector3 divide(float scale, Vector3 v) {
        return new Vector3(scale / v.x, scale / v.y, scale / v.z);
    }

    /**
     * Get a Vector3 whose direction is equal to the direction of the given
     * Vector3 and whose magnitude is 1.
     *
     * @param v the Vector3 to normalize
     * @return the normalized Vector3
     */
    public static Vector3 normalize(Vector3 v) {
        if (v.equals(zero())) {
            return v;
        }

        float distance = mag(v);

        return multiply(v, 1 / distance);
    }

    /**
     * Find the distance between the two given Vector3s.
     *
     * @param v1 the first Vector3
     * @param v2 the second Vector3
     * @return the distance between v1 and v2
     */
    public static float distance(Vector3 v1, Vector3 v2) {
        return (float) Math.sqrt(distance2(v1, v2));
    }

    public static float distance2(Vector3 v1, Vector3 v2) {
        Vector3 v = v2.minus(v1);
        return dot(v, v);
    }

    /**
     * Get the magnitude of the given Vector3.
     *
     * @param v the Vector3
     * @return the magnitude of v
     */
    public static float mag(Vector3 v) {
        return (float) Math.sqrt(mag2(v));
    }
   
    public static float mag2(Vector3 v) {
        return dot(v, v);
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ", " + z + ")";
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Vector3)) {
            return false;
        }

        Vector3 v = (Vector3) obj;

        return x == v.x && y == v.y && z == v.z;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 79 * hash + Float.floatToIntBits(this.x);
        hash = 79 * hash + Float.floatToIntBits(this.y);
        hash = 79 * hash + Float.floatToIntBits(this.z);
        return hash;
    }

    public FloatBuffer getBuffer() {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(3);
        store(buffer);
        buffer.clear();
        return buffer;
    }
}
TOP

Related Classes of aspect.util.Vector3

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.