/* * Vector3D.java * * Created on November 21, 2006, 5:13 PM * */ package edu.oregonstate.cartography.app; /** * Vector3D is a vector in three-dimensional space. */ public final class Vector3D { /** * X component of the vector. */ public double x; /** * Y component of the vector. */ public double y; /** * Z component of the vector. */ public double z; /** * Creates a new instance of Vector3D. * * @param x X component of the vector. * @param y Y component of the vector. * @param z Z component of the vector. */ public Vector3D(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } /** * Creates a new instance of Vector3D. The new vector has a length of 1. Its * orientation is specified by azimuth and a zenith. * * @param azimuth Azimuth of the direction. Counted from north in counter- * clockwise direction. Between 0 and 360 degrees. * @param zenith The vertical angle of the light direction from the zenith * towards the horizon. Between 0 and 90 degrees. */ public Vector3D(double azimuth, double zenith) { double a = azimuth / 180. * Math.PI; zenith *= Math.PI / 180.; double sinz = Math.sin(zenith); x = Math.sin(a) * sinz; y = Math.cos(a) * sinz; z = Math.cos(zenith); } /** * Construct a vector of unary length from an azimuth and a zenith angle. * @param azimuthRad From y axis in clockwise direction. In radians. * @param zenithRad From z axis towards xy plane. In radians. */ public void direction(double azimuthRad, double zenithRad) { double sinz = Math.sin(zenithRad); x = Math.sin(azimuthRad) * sinz; y = Math.cos(azimuthRad) * sinz; z = Math.cos(zenithRad); } /** * Normalize the length of the vector. After calling this method, the vector * has a length of 1. */ public void normalize() { double length = Math.sqrt(x * x + y * y + z * z); x /= length; y /= length; z /= length; } /** * Normalize the length of a vector. After calling this method, the passed * vector has a length of 1. * @param v vector to normalize * @return passed normalized vector v */ public static Vector3D normalize(Vector3D v) { v.normalize(); return v; } /** * Computes the dot product with another vector. * * @param v The second vector. * @return Returns the scalar product: cos(angle between the vectors). */ public double dotProduct(Vector3D v) { return v.x * this.x + v.y * this.y + v.z * this.z; } /** * Compute the dot product of two vectors * * @param v1 The first vector. * @param v2 The second vector. * @return The dot product (between 0 and 1) */ public static double dotProduct(Vector3D v1, Vector3D v2) { return v1.dotProduct(v2); } /** * Computes a new vector perpendicular to this and a second vector. * * @param v The second vector. * @return A new Vector3D that is perpendicular to the two other vectors. */ public Vector3D vectorProduct(Vector3D v) { double vx = y * v.z - z * v.y; double vy = z * v.x - x * v.z; double vz = x * v.y - y * v.x; return new Vector3D(vx, vy, vz); } /** * Adds two vectors together * * @param v the second vector. * @return A new Vector3D that is the sum of the input vectors. */ public Vector3D vectorSum(Vector3D v) { double vx = x + v.x; double vy = y + v.y; double vz = z + v.z; return new Vector3D(vx, vy, vz); } /** * Component-wise add of another vector. * @param v vector to add */ public void add(Vector3D v) { x += v.x; y += v.y; z += v.z; } /** * Makes the xyz components of a vector accessible from outside this class. * * @param v the vector whose components we're interested in * @return A double array of length 3 containing the x, y, and z components * of the vector. * */ public static double[] getVectorComponents(Vector3D v) { return new double[]{v.x, v.y, v.z}; } /** * Compute the vector product of two vectors. * * @param v1 The first vector. * @param v2 The second vector. * @return A new vector perpendicular to the plane defined by v1 and v2. */ public static Vector3D vectorProduct(Vector3D v1, Vector3D v2) { return v1.vectorProduct(v2); } /** * Vector product of two three-dimensional vectors. * @param v1x x component of first vector * @param v1y y component of first vector * @param v1z z component of first vector * @param v2x x component of second vector * @param v2y y component of second vector * @param v2z z component of second vector * @param n Vector to store the result. */ public static void vectorProduct(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z, Vector3D n) { n.x = v1y * v2z - v1z * v2y; n.y = v1z * v2x - v1x * v2z; n.z = v1x * v2y - v1y * v2x; } }