/*
** 2012 March 12
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
*/
package info.ata4.bsplib.vector;
import info.ata4.io.DataReader;
import info.ata4.io.DataWriter;
import java.io.IOException;
/**
* An immutable fluent interface four-dimensional vector class for float values.
*
* @author Sandern
*/
public final class Vector4f extends VectorXf {
public static Vector4f read(DataReader in) throws IOException {
float x = in.readFloat();
float y = in.readFloat();
float z = in.readFloat();
float w = in.readFloat();
return new Vector4f(x, y, z, w);
}
public static void write(DataWriter out, Vector4f vec) throws IOException {
out.writeFloat(vec.x);
out.writeFloat(vec.y);
out.writeFloat(vec.z);
out.writeFloat(vec.w);
}
// frequently used pre-defined vectors
public static final Vector4f NULL = new Vector4f(0, 0, 0, 0);
public static final Vector4f MAX_VALUE = new Vector4f(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
public static final Vector4f MIN_VALUE = MAX_VALUE.scalar(-1); // don't use Float.MIN_VALUE here
// vector values
public final float x;
public final float y;
public final float z;
public final float w;
/**
* Replicating contructor
* Constructs new Vector4f by copying an existing Vector4f
*
* @param v The Vector4f to copy
*/
public Vector4f(Vector4f v) {
this(v.x, v.y, v.z, v.w);
}
/**
* Constructs a new Vector4f using the values out of an array.
* The array must have a size of at least 3.
*
* @param v float array
*/
public Vector4f(float[] v) {
this(v[0], v[1], v[2], v[3]);
}
/**
* Constructs a new Vector4f from x, y and z components
*
* @param x the vector x component
* @param y the vector y component
* @param z the vector z component
*/
public Vector4f(float x, float y, float z, float w) {
super(4);
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
/**
* Returns the value of the n'th component.
*
* @param index component number
* @return component value
*/
@Override
public float get(int index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
case 3:
return this.w;
default:
return 0;
}
}
/**
* Set the value of the n'th component.
*
* @param index component number
* @param value new component value
* @return vector with new value
*/
@Override
public Vector4f set(int index, float value) {
switch (index) {
case 0:
return new Vector4f(value, y, z, w);
case 1:
return new Vector4f(x, value, z, w);
case 2:
return new Vector4f(x, y, value, w);
case 3:
return new Vector4f(x, y, z, value);
default:
return this;
}
}
/**
* Vector dot product: this . that
*
* @param that the Vector4f to take dot product with
* @return the dot product of the two vectors
*/
public float dot(Vector4f that) {
return this.x * that.x + this.y * that.y + this.z * that.z;
}
/**
* Vector normalisation: ^this
*
* @return the normalised vector
*/
public Vector4f normalize() {
float len = length();
float rx = x / len;
float ry = y / len;
float rz = z / len;
float rw = w / len;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Vector addition: this + that
*
* @param that The vector to add
* @return The sum of the two vectors
*/
public Vector4f add(Vector4f that) {
float rx = this.x + that.x;
float ry = this.y + that.y;
float rz = this.z + that.z;
float rw = this.w + that.w;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Vector subtraction: this - that
*
* @param that The vector to subtract
* @return The difference of the two vectors
*/
public Vector4f sub(Vector4f that) {
float rx = this.x - that.x;
float ry = this.y - that.y;
float rz = this.z - that.z;
float rw = this.w - that.w;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Snap vector to nearest value: round(this / value) * value
*
* @param value snap value
* @return This vector snapped to the nearest values of 'value'
*/
public Vector4f snap(float value) {
float rx = Math.round(x / value) * value;
float ry = Math.round(y / value) * value;
float rz = Math.round(z / value) * value;
float rw = Math.round(w / value) * value;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Calculate the length of this vector
*
* @return length of this vector
*/
public float length() {
return (float) Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2) + Math.pow(this.z, 2) + Math.pow(this.w, 2));
}
/**
* Performs a scalar multiplication on this vector: this * mul
*
* @param mul multiplicator
* @return scalar multiplied vector
*/
public Vector4f scalar(float mul) {
float rx = this.x * mul;
float ry = this.y * mul;
float rz = this.z * mul;
float rw = this.w * mul;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Performs a scalar multiplication on this vector: this * that
*
* @param that multiplicator vector
* @return scalar multiplied vector
*/
public Vector4f scalar(Vector4f that) {
float rx = this.x * that.x;
float ry = this.y * that.y;
float rz = this.z * that.z;
float rw = this.w * that.w;
return new Vector4f(rx, ry, rz, rw);
}
/**
* Returns the minima between this vector and another vector.
*
* @param that other vector to compare
* @return minima of this and that vector
*/
public Vector4f min(Vector4f that) {
float rx = Math.min(this.x, that.x);
float ry = Math.min(this.y, that.y);
float rz = Math.min(this.z, that.z);
float rw = Math.min(this.w, that.w);
return new Vector4f(rx, ry, rz, rw);
}
/**
* Returns the maxima between this vector and another vector.
*
* @param that other vector to compare
* @return maxima of this and that vector
*/
public Vector4f max(Vector4f that) {
float rx = Math.max(this.x, that.x);
float ry = Math.max(this.y, that.y);
float rz = Math.max(this.z, that.z);
float rw = Math.max(this.w, that.w);
return new Vector4f(rx, ry, rz, rw);
}
}