/* * Copyright (C) 2013 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package interactivespaces.util.geometry; import interactivespaces.util.math.MathUtils; /** * A 4 component vector. * * <p> * Can be used for things such as homogenous coordinates. * * @author Keith M. Hughes */ public class Vector4 { /** * Intepolate along the line between {@code v0} and {@code v1}. * * <ul> * <li>If {@code amount} is {@code 0}, the value will be {@code v0}.</li> * <li>If {@code amount} is {@code 1}, the value will be {@code v1}.</li> * </ul> * * @param v1 * the origin point * @param v2 * the direction point * @param amount * the percentage between the origin and the direction * @param answer * where to place the answer * * @return the answer */ public static Vector4 interpolate(Vector4 v1, Vector4 v2, double amount, Vector4 answer) { answer.v0 = (v2.v0 - v1.v0) * amount + v1.v0; answer.v1 = (v2.v1 - v1.v1) * amount + v1.v1; answer.v2 = (v2.v2 - v1.v2) * amount + v1.v2; answer.v3 = (v2.v3 - v1.v3) * amount + v1.v3; return answer; } /** * Intepolate along the line between {@code v0} and {@code v1}. * * <ul> * <li>If {@code amount} is {@code 0}, the value will be {@code v0}.</li> * <li>If {@code amount} is {@code 1}, the value will be {@code v1}.</li> * </ul> * * @param v1 * the origin point * @param v2 * the direction point * @param amount * the percentage between the origin and the direction * * @return a new vector containing the answer */ public static Vector4 interpolate(Vector4 v1, Vector4 v2, double amount) { return interpolate(v1, v2, amount, new Vector4()); } /** * First component of the vector. */ double v0; /** * Second component of the vector. */ double v1; /** * Third component of the vector. */ double v2; /** * Fourth component of the vector. */ double v3; /** * Construct a new vector with components all equal to 0. */ public Vector4() { this(0.0, 0.0, 0.0, 0.0); } /** * Create a 4 vector with the given coordinates. * * @param v0 * the first component * @param v1 * the second component * @param v2 * the third component * @param v3 * the fourth component */ public Vector4(double v0, double v1, double v2, double v3) { this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v3 = v3; } /** * Create a 4 vector with the given vector's coordinates. * * @param v * the vector */ public Vector4(Vector4 v) { this(v.v0, v.v1, v.v2, v.v3); } /** * Create a 4 vector with the given vector's coordinates. The 4th component * will be 1. * * @param v * the vector */ public Vector4(Vector3 v) { this(v.v0, v.v1, v.v2, 1.0); } /** * Get the first component of the vector. * * @return first component */ public double getV0() { return v0; } /** * Set the first component of the vector. * * @param v * the new component value * * @return this vector */ public Vector4 setV0(double v) { this.v0 = v; return this; } /** * Get the second component of the vector. * * @return the second component */ public double getV1() { return v1; } /** * Set the second component of the vector. * * @param v * the new component value * * @return this vector */ public Vector4 setV1(double v) { this.v1 = v; return this; } /** * Get the third component of the vector. * * @return the third component */ public double getV2() { return v2; } /** * Set the third component of the vector. * * @param v * the new component value * * @return this vector */ public Vector4 setV2(double v) { this.v2 = v; return this; } /** * Get the fourth component of the vector. * * @return the fourth component */ public double getV3() { return v3; } /** * Set the fourth component of the vector. * * @param v * the new component value * * @return this vector */ public Vector4 setV3(double v) { this.v3 = v; return this; } /** * Set the components of the vector. * * @param v0 * the first component value * @param v1 * the second component value * @param v2 * the third component value * @param v3 * the fourth component value * * @return this vector */ public Vector4 set(double v0, double v1, double v2, double v3) { this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v3 = v3; return this; } /** * Multiply the current vector by the matrix. * * @param m * the matrix to multiply by * * @return a new vector whose components are result of the multiplication */ public Vector4 multiply(Matrix4 m) { return new Vector4(this).multiplySelf(m); } /** * Multiple the current vector in homogeneous space, setting the current * vector to the result. * * @param m * the vector to multiply by * * @return this vector whose components are result of the multiplication */ public Vector4 multiplySelf(Matrix4 m) { double tv0 = v0 * m.matrix[0][0] + v1 * m.matrix[0][1] + v2 * m.matrix[0][2] + m.matrix[0][3]; double tv1 = v0 * m.matrix[1][0] + v1 * m.matrix[1][1] + v2 * m.matrix[1][2] + m.matrix[1][3]; double tv2 = v0 * m.matrix[2][0] + v1 * m.matrix[2][1] + v2 * m.matrix[2][2] + m.matrix[2][3]; double tv3 = v0 * m.matrix[3][0] + v1 * m.matrix[3][1] + v2 * m.matrix[3][2] + m.matrix[3][3]; v0 = tv0; v1 = tv1; v2 = tv2; v3 = tv3; return this; } /** * Is this vectors equal to the other within some tolerance factor?. * * @param v * the second vector * @param tolerance * the tolerance for equality * * @return {@code true} if each component is equal to the corresponding * component within the tolerance factor */ public boolean equal(Vector4 v, double tolerance) { return MathUtils.equals(v0, v.v0, tolerance) && MathUtils.equals(v1, v.v1, tolerance) && MathUtils.equals(v2, v.v2, tolerance) && MathUtils.equals(v3, v.v3, tolerance); } }