package primitives3D;
/**
* A 3 dimensional Vector.
*
* @author Curran Kelleher
*
*/
public class Vector3D {
/**
* The x component of this vector.
*/
public double x;
/**
* The y component of this vector.
*/
public double y;
/**
* The z component of this vector.
*/
public double z;
/**
* Temporary variables used in calculating rotation.
*/
private static double sint, cost, newX, newY, newZ;
/**
* Construct a 3D point with the specified components
*
* @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 3D vector with the components of the specified vector.
*
* @param vector
* the vector to copy the components from.
*/
public Vector3D(Vector3D vector) {
this(vector.x, vector.y, vector.z);
}
/**
* Constructs a Vector3D with the values of 0,0,0.
*
*/
public Vector3D() {
this(0, 0, 0);
}
/**
* Calculates the rotation of this vector about the X axis, then puts the
* resulting coordinates into the vectorToPutResultsIn. Calling this method
* never changes the vector it is called in.
*
* @param theta
* the angle specifying the how much to rotate
* @param vectorToPutResultsIn
* the vector which gets the coordinates resulting from the
* rotation calculation.
*/
public void rotateVectorAboutXAxis(double theta,
Vector3D vectorToPutResultsIn) {
sint = Math.sin(theta);
cost = Math.cos(theta);
newX = x;
newY = y * cost - z * sint;
newZ = y * sint + z * cost;
// do calculations first, then apply. otherwise, if vectorToPutResultsIn
// is also the invoking instance, it
// causes problems
vectorToPutResultsIn.x = newX;
vectorToPutResultsIn.y = newY;
vectorToPutResultsIn.z = newZ;
}
/**
* Calculates the rotation of this vector about the Y axis, then puts the
* resulting coordinates into the vectorToPutResultsIn. Calling this method
* never changes the vector it is called in.
*
* @param theta
* the angle specifying the how much to rotate
* @param vectorToPutResultsIn
* the vector which gets the coordinates resulting from the
* rotation calculation.
*/
public void rotateVectorAboutYAxis(double theta,
Vector3D vectorToPutResultsIn) {
sint = Math.sin(theta);
cost = Math.cos(theta);
newX = z * sint + x * cost;
newY = y;
newZ = z * cost - x * sint;
// do calculations first, then apply. otherwise, if vectorToPutResultsIn
// is also the invoking instance, it
// causes problems
vectorToPutResultsIn.x = newX;
vectorToPutResultsIn.y = newY;
vectorToPutResultsIn.z = newZ;
}
/**
* Calculates the rotation of this vector about the Z axis, then puts the
* resulting coordinates into the vectorToPutResultsIn. Calling this method
* never changes the vector it is called in.
*
* @param theta
* the angle specifying the how much to rotate
* @param vectorToPutResultsIn
* the vector which gets the coordinates resulting from the
* rotation calculation.
*/
public void rotateVectorAboutZAxis(double theta,
Vector3D vectorToPutResultsIn) {
sint = Math.sin(theta);
cost = Math.cos(theta);
newX = x * cost - y * sint;
newY = x * sint + y * cost;
newZ = z;
// do calculations first, then apply. otherwise, if vectorToPutResultsIn
// is also the invoking instance, it
// causes problems
vectorToPutResultsIn.x = newX;
vectorToPutResultsIn.y = newY;
vectorToPutResultsIn.z = newZ;
}
/**
* Adds the specified vector to this one and returns the result in a new
* Vector.
*
* @param b
* the Vector to subtract from this one
*/
public Vector3D plus(Vector3D b) {
Vector3D results = new Vector3D(0, 0, 0);
this.plus(b, results);
return results;
}
/**
* Adds the specified vector to this one and returns the result in the
* specified vectorToPutResultsIn
*
* @param b
* the Vector to add to this one
* @param vectorToPutResultsIn
* the Vector to put the results in
*/
public void plus(Vector3D b, Vector3D vectorToPutResultsIn) {
vectorToPutResultsIn.x = x + b.x;
vectorToPutResultsIn.y = y + b.y;
vectorToPutResultsIn.z = z + b.z;
}
/**
* Subtracts the specified vector from this one and returns the result in a
* new Vector.
*
* @param b
* the Vector to subtract from this one
* @return a new Vector with the result of the addition inside it.
*/
public Vector3D minus(Vector3D b) {
Vector3D results = new Vector3D(0, 0, 0);
this.minus(b, results);
return results;
}
/**
* Subtracts the specified vector from this one and returns the result in
* the specified vectorToPutResultsIn
*
* @param b
* the Vector to subtract from this one
* @param vectorToPutResultsIn
* the Vector to put the results in
*/
public void minus(Vector3D b, Vector3D vectorToPutResultsIn) {
vectorToPutResultsIn.x = x - b.x;
vectorToPutResultsIn.y = y - b.y;
vectorToPutResultsIn.z = z - b.z;
}
/**
* Returns the cross product of the current vector (a) and the specified
* vector (b). it returns aXb. The vector resulting from the cross product
* has a direction which is the normal of a and b. The magnitude of the
* cross product is the area of the parallelogram traced by the two vectors
* a and b.
*/
/**
* Calculates the cross-product of this vector with the specified one.
*
* @param b
* the Vector to cross with this one
* @return a new Vector with the result of the cross product inside it.
*/
public Vector3D cross(Vector3D b) {
return cross(new Vector3D());
}
/**
* Calculates the cross-product of this vector with the specified one. The
* result is put into the specified vectorToPutResultsIn.
*
* @param b
* the Vector to cross with this one *
* @param vectorToPutResultsIn
* the Vector to put the results in
*/
public void cross(Vector3D b, Vector3D vectorToPutResultsIn) {
vectorToPutResultsIn.x = y * b.z - z * b.y;
vectorToPutResultsIn.y = z * b.x - x * b.z;
vectorToPutResultsIn.z = x * b.y - y * b.x;
}
/**
* Performs a scalar multiplication on this vector and returns the result in
* a new Vector.
*
* @param scalarFactor
* the scalar factor to multiply each of the vector's components
* by
* @return a new Vector with the result of the scalar multiplication inside
* it.
*/
public Vector3D times(double scalarFactor) {
Vector3D results = new Vector3D();
this.times(scalarFactor, results);
return results;
}
/**
* Performs a scalar multiplication on this vector and puts the result in a
* the specified vectorToPutResultsIn.
*
* @param scalarFactor
* the scalar factor to multiply each of the vector's components
* by
*/
public void times(double scalarFactor, Vector3D vectorToPutResultsIn) {
vectorToPutResultsIn.x = x * scalarFactor;
vectorToPutResultsIn.y = y * scalarFactor;
vectorToPutResultsIn.z = z * scalarFactor;
}
/**
* Calculates the normal from the specified 3 points. The cross product of
* (a-b) and (c-b) is put into the vectorToPutNormalInto vector.
*
* @param a
* Vector a
* @param b
* Vector b, the vertex of the normal
* @param c
* Vector c
* @param vectorToPutNormalInto
* The vector which the normal calculation will be put into. This
* vector will be changed.
*/
public static void calculateNormal(Vector3D a, Vector3D b, Vector3D c,
Vector3D vectorToPutNormalInto) {
// B-b-C
// |
// a
// |
// A
// a = A-B
// b = C-B
// normal = aXb
double Ax = a.x - b.x;
double Ay = a.y - b.y;
double Az = a.z - b.z;
double Bx = c.x - b.x;
double By = c.y - b.y;
double Bz = c.z - b.z;
vectorToPutNormalInto.x = Ay * Bz - Az * By;
vectorToPutNormalInto.y = Az * Bx - Ax * Bz;
vectorToPutNormalInto.z = Ax * By - Ay * Bx;
}
/**
* Calculates the distance between the two specified vectors.
*
* @param a
* @param b
* @return the distance between vectors a and b
*/
public static double calculateDistance(Vector3D a, Vector3D b) {
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)
+ Math.pow(a.z - b.z, 2));
}
/**
* Sets the values of this vector to the values from the specified vector.
*
* @param vectorToCopy
* the vector whose values will be copied into this one.
*/
public void set(Vector3D vectorToCopy) {
x = vectorToCopy.x;
y = vectorToCopy.y;
z = vectorToCopy.z;
}
}