import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; /** * This class abstracts a scalar and vector and all the arithmetic * operations defined on these values. */ public class Value { public static final Value ZERO = new Value( 0 ); private double x = 0.0d; private double y = 0.0d; private double z = 0.0d; public static final int typeScalar = 1; public static final int typeVector = 2; private int type = typeScalar; public Value(double x, double y, double z) { this.x = x; this.y = y; this.z = z; this.type = typeVector; } public Value(double x) { this.x = x; this.type = typeScalar; // this line is reduntant, since // type is initialized with typeScalar; } /** * @return <tt>this + rhs</tt> */ public Value add(Value rhs) throws InvalidParameterException { if (type != rhs.type) throw new InvalidParameterException("rhs" , "incompatible data types, neighter the operation vector + scalar nor scalar + vector are defined" ); if (type == typeScalar) return new Value(x + rhs.x); else return new Value(x + rhs.x, y + rhs.y, z + rhs.z); } public boolean equals( Value rhs, double epsilon ) { return type == rhs.type && ( ( type == typeScalar && Math.abs(x-rhs.x)<epsilon ) || ( type == typeVector && Math.abs(x-rhs.x)<epsilon && Math.abs(y-rhs.y)<epsilon && Math.abs(z-rhs.z)<epsilon ) ); } public boolean equals( double x, double epsilon ) { return ( type == typeScalar && Math.abs(this.x-x)<epsilon ); } public boolean equals( double x, double y, double z, double epsilon ) { return ( type == typeVector && Math.abs(this.x-x)<epsilon && Math.abs(this.y-y)<epsilon && Math.abs(this.z-z)<=epsilon ); } // some getter and setter functions, it's not worth to document them :) public int getType() { return type; } public double getX() { return x; } public double getY() { return y; } public double getZ() { return z; } public void setValue( double x ) { this.type = typeScalar; this.x = x; this.y = 0.0f; this.z = 0.0f; } public void setValue( double x, double y, double z ) { this.type = typeVector; this.x = x; this.y = y; this.z = z; } /** * @return <tt>-this</tt> */ public Value negate() { if (type == typeScalar) return new Value(-x); else return new Value(-x, -y, -z); } /** * Returns a <tt>Value</tt> whos valus <tt>this * rhs</tt> * * The calculation is performed on depanding the Value types. * scalar * scalar -> scalar, vector * scalar -> vector, * scalar * vector -> vector, vector * vector -> vector.<br> * vector * vector -> vector, performes the vector ex-product * * @return <tt>this * rhs</tt> */ public Value multiply(Value rhs) { if (type == typeScalar) { if (rhs.type == typeScalar) return new Value(x * rhs.x); else return new Value(x * rhs.x, x * rhs.y, x * rhs.z); } else { if (rhs.type == typeScalar) return new Value(x * rhs.x, y * rhs.x, z * rhs.x); else // vector ex-product return new Value( y * rhs.z - z * rhs.y , z * rhs.x - x * rhs.z , x * rhs.y - y * rhs.x ); } } /** * Returns a <tt>Value</tt> whos value is <tt>this - rhs</tt> * @param rhs value to be substracted from this Value * @return <tt>this - rhs</tt> */ public Value subtract(Value rhs) throws InvalidParameterException { if (type != rhs.type) throw new InvalidParameterException("rhs" , "incompatible data types, neighter the operation vector - scalar nor scalar - vector are defined" ); if (type == typeScalar) return new Value(x - rhs.x); else return new Value(x - rhs.x, y - rhs.y, z - rhs.z); } /** * @return the string representation of the value */ public String toString() { DecimalFormat df = new DecimalFormat("#0.000"); DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); dfs.setDecimalSeparator('.'); df.setDecimalFormatSymbols(dfs); if ( type == typeScalar ) return df.format(x); else return "[ " + df.format(x) + " , " + df.format(y) + " , " + df.format(z) + " ]"; } }