/** * Vector.java * * Vector class for representing and manipulating mathematical * vector's of real (double) numbers. * * @ Authors: * * @ Wayne Witzel * @ University of Utah, Aspire * @ * @ Copyright 1999, All Rights Reserved */ package matrix; // Vector class with some common functions that // apply to vectors of any dimension. public class Vector { private double[] data; // create a vector of the given dimension initialized // to the ZERO vector in that dimensionality. public Vector(int size) { data = new double[size]; for (int i = 0; i < size; i++) data[i] = 0; //{{INIT_CONTROLS //}} } public Vector assign(Vector v2) { if (size() != v2.size()) throw new VectorDimensionError(this, v2); for (int i = 0; i < size(); i++) setComponent(i, v2.component(i)); return this; } // return the size of the vector public int size() { return data.length; } // return component i public double component(int i) { return data[i]; } // set component i public void setComponent(int i, double value) { data[i] = value; } /* vector addition */ public Vector add(Vector v2) throws VectorDimensionError { if (size() != v2.size()) throw new VectorDimensionError(this, v2); Vector result = new Vector(size()); for (int i = 0; i < size(); i++) result.setComponent(i, component(i) + v2.component(i)); return result; } public static Vector add(Vector v1, Vector v2) { return v1.add(v2); } /* vector subtraction */ public Vector subtract(Vector v2) throws VectorDimensionError { if (size() != v2.size()) throw new VectorDimensionError(this, v2); Vector result = new Vector(size()); for (int i = 0; i < size(); i++) result.setComponent(i, component(i) - v2.component(i)); return result; } public static Vector subtract(Vector v1, Vector v2) { return v1.subtract(v2); } /* scalar multiplication */ public Vector mult(double a) { Vector result = new Vector(size()); for (int i = 0; i < size(); i++) result.setComponent(i, component(i) * a); return result; } public static Vector mult(Vector v, double a) { return v.mult(a); } /* vector dot product (component-wise multiplication) */ public double dotProduct(Vector v2) throws VectorDimensionError { if (size() != v2.size()) throw new VectorDimensionError(this, v2); double result = 0; for (int i = 0; i < size(); i++) result += component(i) * v2.component(i); return result; } public static double dotProduct(Vector v1, Vector v2) { return v1.dotProduct(v2); } /* implemented functions that make use of one or more of the abstract functions */ public double squared() { return this.dotProduct(this); } public double length() { return Math.pow(this.dotProduct(this), .5); } public static Vector normalized(Vector v) { return v.mult(1 / v.length()); } public static Vector rescaled(Vector v, double newLength) { return v.mult(newLength / v.length()); } // Reflect an incident vector about a surface whose // normal vector is provided (normal should point in // direction of reflection and should NOT be zero). // If the incident vector is pointing away from the // surface (in similar direction as the normal) then // this will simple return the original incident vector. public Vector reflected(Vector normal) { double i_dot_n = this.dotProduct(normal); if (i_dot_n > 0) return this; else { // reflected = incident + 2*incident*cos(angle)*(normal/|normal|) double scale = -2 * i_dot_n / normal.squared(); return this.add(normal.mult(scale)); } } // returns the t such that x + v * t = R. // If there is no such t, then Double.NEGATIVE_INFINITY // is returned. public double radiusImpactParam(Vector v, double R) { // |d| = |(x0, y0)| = R // x = x0 + v.x * t // y = y0 + v.y * t // (v*v) * t^2 + 2*(d*v) * t + d*d - R^2 = 0 // a * t^2 + b * t + c = 0 double a = v.squared(); double b = 2 * this.dotProduct(v); if (b >= 0) return -1; // obj is moving away so there won't be a collision double c = this.squared() - R*R; double det = b*b - 4*a*c; if (det > 0) { double t = (-b - Math.pow(det, .5)) / (2*a); return (t < 0) ? -t : t; } else return Double.NEGATIVE_INFINITY; // doesn't collide - return negative infinity } //{{DECLARE_CONTROLS //}} }