A 3x3 matrix implementation : Matrix « 2D Graphics GUI « Java

A 3x3 matrix implementation

```
/**
* Copyright (c) 2008-2010  Morten Silcowitz.
*
* This file is part of the Jinngine physics library
*
* Jinngine is published under the GPL license, available
* at http://www.gnu.org/copyleft/gpl.html.
*/
//package jinngine.math;

import java.io.Serializable;

//3x3 matrix for optimized matrix ops

/**
* A 3x3 matrix implementation
*/
public class Matrix3 {
public double a11, a12, a13;
public double a21, a22, a23;
public double a31, a32, a33;

public Matrix3() {
a11=0; a12=0; a13=0;
a21=0; a22=0; a23=0;
a31=0; a32=0; a33=0;
}

/**
* Assign the zero matrix to this matrix
* @return <code>this</code>
*/
public final Matrix3 assignZero() {
a11 = 0; a12 = 0; a13 = 0;
a21 = 0; a22 = 0; a23 = 0;
a31 = 0; a32 = 0; a33 = 0;
return this;
}

/**
* Construct a 3x3 matrix using specified fields
* @param a11
* @param a12
* @param a13
* @param a21
* @param a22
* @param a23
* @param a31
* @param a32
* @param a33
*/
public Matrix3(double a11, double a12, double a13, double a21, double a22,
double a23, double a31, double a32, double a33) {
this.a11 = a11;
this.a12 = a12;
this.a13 = a13;
this.a21 = a21;
this.a22 = a22;
this.a23 = a23;
this.a31 = a31;
this.a32 = a32;
this.a33 = a33;
}

/**
* create a 3x3 matrix using a set of basis vectors
* @param e1
* @param e2
* @param e3
*/
public Matrix3( Vector3 e1, Vector3 e2, Vector3 e3) {
a11 = e1.x;
a21 = e1.y;
a31 = e1.z;

a12 = e2.x;
a22 = e2.y;
a32 = e2.z;

a13 = e3.x;
a23 = e3.y;
a33 = e3.z;
}

/**
* Construct a new 3x3 matrix as a copy of the given matrix B
* @param B
* @throws NullPointerException
*/
public Matrix3( Matrix3 B) {
assign(B);
}

/**
* assign the value of B to this Matrix3
* @param B
*/
public final Matrix3 assign(Matrix3 B) {
a11 = B.a11; a12 = B.a12; a13 = B.a13;
a21 = B.a21; a22 = B.a22; a23 = B.a23;
a31 = B.a31; a32 = B.a32; a33 = B.a33;
return this;
}

/**
* Assign the scale matrix given by s, to this matrix
*/
public final Matrix3 assignScale(final double s) {
a11 = s; a12 = 0; a13 = 0;
a21 = 0; a22 = s; a23 = 0;
a31 = 0; a32 = 0; a33 = s;
return this;
}

/**
* Assign the non-uniform scale matrix given by s1, s2 and s3, to this matrix
*/
public final Matrix3 assignScale(double sx, double sy, double sz) {
a11 = sx; a12 = 0.; a13 = 0.;
a21 = 0.; a22 = sy; a23 = 0.;
a31 = 0.; a32 = 0.; a33 = sz;
return this;
}

/**
* Assign the identity matrix to this matrix
*/
public final Matrix3 assignIdentity() {
a11 = 1; a12 = 0; a13 = 0;
a21 = 0; a22 = 1; a23 = 0;
a31 = 0; a32 = 0; a33 = 1;
return this;
}

public Matrix3 assign(
double a11, double a12, double a13,
double a21, double a22, double a23,
double a31, double a32, double a33) {
this.a11 = a11;  this.a12 = a12;  this.a13 = a13;
this.a21 = a21;  this.a22 = a22;  this.a23 = a23;
this.a31 = a31;  this.a32 = a32;  this.a33 = a33;
return this;
}
/**
* Get the n'th column vector of this matrix
* @param n
* @return
* @throws IllegalArgumentException
*/
public final Vector3 column(int n) {
switch (n) {
case 0:
return new Vector3(a11,a21,a31);
case 1:
return new Vector3(a12,a22,a32);
case 2:
return new Vector3(a13,a23,a33);
default:
throw new IllegalArgumentException();
}
}

/**
* Get the n'th row vector of this matrix
* @param n
* @return
*/
public Vector3 row(int n) {
switch (n) {
case 0:
return new Vector3(a11,a12,a13);
case 1:
return new Vector3(a21,a22,a23);
case 2:
return new Vector3(a31,a32,a33);
default:
throw new IllegalArgumentException();
}
}

/**
* Get all column vectors of this matrix
* @param c1
* @param c2
* @param c3
*/
public void getColumnVectors( Vector3 c1, Vector3 c2, Vector3 c3) {
c1.x = a11;
c1.y = a21;
c1.z = a31;

c2.x = a12;
c2.y = a22;
c2.z = a32;

c3.x = a13;
c3.y = a23;
c3.z = a33;
}

/**
* Get all row vectors of this matrix
* @param r1
* @param r2
* @param r3
*/
public void getRowVectors( Vector3 r1, Vector3 r2, Vector3 r3) {
r1.x = a11;
r1.y = a12;
r1.z = a13;

r2.x = a21;
r2.y = a22;
r2.z = a23;

r3.x = a31;
r3.y = a32;
r3.z = a33;
}

/**
* Return a new identity Matrix3 instance
* @return
*/
public static Matrix3 identity() {
return new Matrix3().assignIdentity();
}

/**
* Multiply this matrix by a scalar, return the resulting matrix
* @param s
* @return
*/
public final Matrix3 multiply( double s) {
Matrix3 A = new Matrix3();
A.a11 = a11*s; A.a12 = a12*s; A.a13 = a13*s;
A.a21 = a21*s; A.a22 = a22*s; A.a23 = a23*s;
A.a31 = a31*s; A.a32 = a32*s; A.a33 = a33*s;
return A;
}

/**
* Right-multiply by a scaling matrix given by s, so M.scale(s) = M S(s)
* @param s
* @return
*/
public final Matrix3 scale( Vector3 s ) {
Matrix3 A = new Matrix3();
A.a11 = a11*s.x; A.a12 = a12*s.y; A.a13 = a13*s.z;
A.a21 = a21*s.x; A.a22 = a22*s.y; A.a23 = a23*s.z;
A.a31 = a31*s.x; A.a32 = a32*s.y; A.a33 = a33*s.z;
return A;
}

/**
* Multiply this matrix by the matrix A and return the result
* @param A
* @return
*/
public Matrix3 multiply(Matrix3 A) {
return multiply(this,A,new Matrix3());
}

/**
* Multiply this matrix by the matrix A and return the result
* @param A
* @return
*/
public Matrix3 assignMultiply(Matrix3 A) {
return multiply(this,A,this);
}

//C = AxB
public static Matrix3 multiply( final Matrix3 A, final Matrix3 B, final Matrix3 C ) {
//               B | b11 b12 b13
//                 | b21 b22 b23
//                 | b31 b32 b33
//     -------------------------
//  A  a11 a12 a13 | c11 c12 c13
//     a21 a22 a23 | c21 c22 c23
//     a31 a32 a33 | c31 c32 c33  C

double t11 = A.a11*B.a11 + A.a12*B.a21 + A.a13*B.a31;
double t12 = A.a11*B.a12 + A.a12*B.a22 + A.a13*B.a32;
double t13 = A.a11*B.a13 + A.a12*B.a23 + A.a13*B.a33;

double t21 = A.a21*B.a11 + A.a22*B.a21 + A.a23*B.a31;
double t22 = A.a21*B.a12 + A.a22*B.a22 + A.a23*B.a32;
double t23 = A.a21*B.a13 + A.a22*B.a23 + A.a23*B.a33;

double t31 = A.a31*B.a11 + A.a32*B.a21 + A.a33*B.a31;
double t32 = A.a31*B.a12 + A.a32*B.a22 + A.a33*B.a32;
double t33 = A.a31*B.a13 + A.a32*B.a23 + A.a33*B.a33;

//copy to C
C.a11 = t11;
C.a12 = t12;
C.a13 = t13;

C.a21 = t21;
C.a22 = t22;
C.a23 = t23;

C.a31 = t31;
C.a32 = t32;
C.a33 = t33;

return C;
}

//functional
/**
* Multiply a vector by this matrix, return the resulting vector
*/
public final Vector3 multiply( final Vector3 v) {
Vector3 r = new Vector3();
Matrix3.multiply(this, v, r);
return r;
}

//A = A^T
public Matrix3 assignTranspose() {
double t;
t=a12; a12=a21; a21=t;
t=a13; a13=a31; a31=t;
t=a23; a23=a32; a32=t;
return this;
}

/**
* Functional method. Transpose this matrix and return the result
* @return
*/
public final Matrix3 transpose() {
return new Matrix3(this).assignTranspose();
}

//C = A-B
public static Matrix3 subtract( final Matrix3 A, final Matrix3 B, final Matrix3 C ) {
C.a11 = A.a11-B.a11; C.a12 = A.a12-B.a12; C.a13 = A.a13-B.a13;
C.a21 = A.a21-B.a21; C.a22 = A.a22-B.a22; C.a23 = A.a23-B.a23;
C.a31 = A.a31-B.a31; C.a32 = A.a32-B.a32; C.a33 = A.a33-B.a33;
return C;
}
/**
* Substract to this matrix the matrix B, return result in a new matrix instance
* @param B
* @return
*/
public Matrix3 subtract( Matrix3 B ) {
return subtract(this,B,new Matrix3());
}
/**
* Substract to this matrix the matrix B, return result in a new matrix instance
* @param B
* @return
*/
public Matrix3 assignSubtract( Matrix3 B ) {
return subtract(this,B,this);
}
/**
* Add to this matrix the matrix B, return result in a new matrix instance
* @param B
* @return
*/
public Matrix3 add( Matrix3 B ) {
}
/**
* Add to this matrix the matrix B, return result in a new matrix instance
* @param B
* @return
*/
public Matrix3 assignAdd( Matrix3 B ) {
}

//C = A+B
public static Matrix3 add( final Matrix3 A, final Matrix3 B, final Matrix3 C ) {
C.a11 = A.a11+B.a11; C.a12 = A.a12+B.a12; C.a13 = A.a13+B.a13;
C.a21 = A.a21+B.a21; C.a22 = A.a22+B.a22; C.a23 = A.a23+B.a23;
C.a31 = A.a31+B.a31; C.a32 = A.a32+B.a32; C.a33 = A.a33+B.a33;
return C;
}

// rT = (vT)A   NOTE that the result of this is actually a transposed vector!!
public static Vector3 transposeVectorAndMultiply( final Vector3 v, final Matrix3 A, final Vector3 r ){
//            A  | a11 a12 a13
//               | a21 a22 a23
//               | a31 a32 a33
//      ----------------------
// vT   v1 v2 v3 |  c1  c2  c3

double t1 = v.x*A.a11+v.y*A.a21+v.z*A.a31;
double t2 = v.x*A.a12+v.y*A.a22+v.z*A.a32;
double t3 = v.x*A.a13+v.y*A.a23+v.z*A.a33;

r.x = t1;
r.y = t2;
r.z = t3;

return r;
}

/**
* Multiply v by A, and place result in r, so r = Av
* @param A 3 by 3 matrix
* @param v Vector to be multiplied
* @param r Vector to hold result of multiplication
* @return Reference to the given Vector3 r instance
*/
public static Vector3 multiply( final Matrix3 A, final Vector3 v, final Vector3 r ) {
//
//               V | v1
//                 | v2
//                 | v3
//     -----------------
//  A  a11 a12 a13 | c1
//     a21 a22 a23 | c2
//     a31 a32 a33 | c3

double t1 = v.x*A.a11+v.y*A.a12+v.z*A.a13;
double t2 = v.x*A.a21+v.y*A.a22+v.z*A.a23;
double t3 = v.x*A.a31+v.y*A.a32+v.z*A.a33;

r.x = t1;
r.y = t2;
r.z = t3;

return r;
}

/**
* Compute the determinant of Matrix3 A
* @param A
* @return
*/
public double determinant() {
return a11*a22*a33- a11*a23*a32 + a21*a32*a13 - a21*a12*a33 + a31*a12*a23-a31*a22*a13;
}

/**
* Compute the inverse of the matrix A, place the result in C
*/
public static Matrix3 inverse( final Matrix3 A, final Matrix3 C ) {
double d = (A.a31*A.a12*A.a23-A.a31*A.a13*A.a22-A.a21*A.a12*A.a33+A.a21*A.a13*A.a32+A.a11*A.a22*A.a33-A.a11*A.a23*A.a32);
double t11 =  (A.a22*A.a33-A.a23*A.a32)/d;
double t12 = -(A.a12*A.a33-A.a13*A.a32)/d;
double t13 =  (A.a12*A.a23-A.a13*A.a22)/d;
double t21 = -(-A.a31*A.a23+A.a21*A.a33)/d;
double t22 =  (-A.a31*A.a13+A.a11*A.a33)/d;
double t23 = -(-A.a21*A.a13+A.a11*A.a23)/d;
double t31 =  (-A.a31*A.a22+A.a21*A.a32)/d;
double t32 = -(-A.a31*A.a12+A.a11*A.a32)/d;
double t33 =  (-A.a21*A.a12+A.a11*A.a22)/d;

C.a11 = t11; C.a12 = t12; C.a13 = t13;
C.a21 = t21; C.a22 = t22; C.a23 = t23;
C.a31 = t31; C.a32 = t32; C.a33 = t33;
return C;
}

public final Matrix3 assignInverse() {
return inverse(this,this);
}
public final Matrix3 inverse() {
return inverse(this,new Matrix3());
}

public static Matrix3 scaleMatrix( double xs, double ys, double zs) {
return new Matrix3().assignScale(xs,ys,zs);
}

public static Matrix3 scaleMatrix( double s ) {
return new Matrix3().assignScale(s);
}

@Override
public String toString() {
return "["+a11+", " + a12 + ", " + a13 + "]\n"
+ "["+a21+", " + a22 + ", " + a23 + "]\n"
+ "["+a31+", " + a32 + ", " + a33 + "]" ;
}

/**
* Check matrix for NaN values
*/
public final boolean isNaN() {
return Double.isNaN(a11)||Double.isNaN(a12)||Double.isNaN(a13)
|| Double.isNaN(a21)||Double.isNaN(a22)||Double.isNaN(a23)
|| Double.isNaN(a31)||Double.isNaN(a32)||Double.isNaN(a33);
}

public double[] toArray() {
return new double[]{
a11, a21, a31,
a12, a22, a32,
a13, a23, a33};
}

/**
* Return the Frobenius norm of this Matrix3
* @return
*/
public final double fnorm() {
return Math.sqrt(  a11*a11 + a12*a12 + a13*a13  + a21*a21 + a22*a22  + a23*a23  + a31*a31 + a32*a32 + a33*a33 );
}
/**
*
* @param v
* @return
* @throws NullPointerException
*/
public static Matrix3 crossProductMatrix(Vector3 v) {
return new Matrix3(
0., -v.z, v.y,
v.z, 0., -v.x,
-v.y, v.x, 0.);
}
}

/**
* <code>Vector3d</code> defines a Vector for a three double value tuple.
* <code>Vector3d</code> can represent any three dimensional value, such as a
* vertex or normal.
*
* The functional methods like add, sub, multiply that returns new instances, and
* left <code>this</code> unchanged.
*
* Static methods store the resulting vector on a existing reference, which avoid
* allowcation an can improove performances around 20% (profiling performend on vector
*
* Deprecated methods will be removed on October 2010
*
* @author Morten Silcowitz
* @author Pierre Labatut
*/
final class Vector3 implements Serializable {
private static final long serialVersionUID = 1L;

/**
* The x coordinate.
*/
public double x;
/**
* The y coordinate.
*/
public double y;
/**
* The z coordinate.
*/
public double z;

public transient final static double e = 1e-9f;

/**
* Constructs and initializes a <code>Vector3</code> to [0., 0., 0.]
*/
public Vector3 () {
x=0; y=0; z=0;
}
/**
* Constructs and initializes a <code>Vector3</code> from the specified
* xyz coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
*/
public Vector3( double x, double y, double z) {
this.x=x; this.y=y; this.z=z;
}

/**
* Constructs and initializes a <code>Vector3</code> with the coordinates
* of the given <code>Vector3</code>.
* @param v the <code>Vector3</code> containing the initialization x y z data
* @throws NullPointerException when v is null
*/
public Vector3( Vector3 v ) {
x=v.x; y=v.y; z = v.z;
}

/**
* Create a new unit vector heading positive x
* @return a new unit vector heading positive x
*/
public static Vector3 i() {
return new Vector3(1., 0., 0.);
}
/**
* Create a new unit vector heading positive y
* @return a new unit vector heading positive y
*/
public static Vector3 j() {
return new Vector3(0., 1., 0.);
}
/**
* Create a new unit vector heading positive z
* @return a new unit vector heading positive z
*/
public static Vector3 k() {
return new Vector3(0., 0., 1.);
}

/**
* Adds a provided vector to this vector creating a resultant
* vector which is returned.
* Neither <code>this</code> nor <code>v</code> is modified.
*
* @param v the vector to add to this.
* @return resultant vector
* @throws NullPointerException if v is null
*/
public final Vector3 add( Vector3 v) {
return new Vector3( x+v.x, y+v.y, z+v.z );
}
/**
* Multiply the vector coordinates by -1. creating a resultant vector
* which is returned.
* <code>this</code> vector is not modified.
*
* @return resultant vector
* @throws NullPointerException if v is null
*/
public final Vector3 negate() {
return new Vector3(-x,-y,-z);
}
/**
* Returns true if one of the coordinated is not a number
* <code>this</code> vector is not modified.
* @return true if one of the coordinated is not a number
*/
public final boolean isNaN() {
return Double.isNaN(x)||Double.isNaN(y)||Double.isNaN(z);
}
/**
* Get a coordinate from a dimention ordinal.
* @param i the dimention ordinal number. 1 is x, 2 is y 3 is z.
* @return <ul>
*<li>         x coordiante when i is 0</li>
*<li>         y coordiante when i is 1</li>
*<li>         z coordiante when i is 2</li>
* </ul>
*/
public double get( int i ) {
return i>0?(i>1?z:y):x;
}
/**
* Set a coordinate from a dimention ordinal.
* @param i the dimention ordinal number. 1 is x, 2 is y 3 is z.
* @param v new coordinate value
*/
public void set( int i, double v ) {
if (i == 0) {
x = v;
} else {
if ( i==1) {
y=v;
}else {
z=v;
}
}
}

/**
* Add two vectors and place the result in v1.
* <code>v2</code> is not modified.
* @param v1 a not null reference, store the sum
* @param v2 a not null reference
* @throws NullPointerException if v1 or v2 is null
*/
public static void add( final Vector3 v1, final Vector3 v2 ) {
v1.x += v2.x;
v1.y += v2.y;
v1.z += v2.z;
}

/**
* Substract two vectors and place the result in v1.
* <code>v2</code> is not modified.
* @param v1 a not null reference, store the difference
* @param v2 a not null reference
* @throws NullPointerException if v1 or v2 is null
*/
public static void sub( final Vector3 v1, final Vector3 v2 ) {
v1.x -= v2.x;
v1.y -= v2.y;
v1.z -= v2.z;
}

/**
* Substracts a provided vector to this vector creating a resultant
* vector which is returned.
* Neither <code>this</code> nor <code>v</code> is modified.
*
* @param v the vector to add to this.
* @return resultant vector
*/
public final Vector3 sub( Vector3 v ) {
return new Vector3( x-v.x, y-v.y, z-v.z );
}

/**
* Multiply this vector by a provided scalar creating a resultant
* vector which is returned.
* <code>this</code> vector is not modified.
*
* @param s multiplication coeficient
* @return resultant vector
*/
public final Vector3 multiply( double s ) {
return new Vector3( x*s, y*s, z*s);
}

/**
* Scale vector by the scale matrix given by s.
* <code>this</code> vector is not modified.
* @param s scale direction and factor
* @return an new vector
*/
public final Vector3 scale( Vector3 s) {
return new Vector3(x*s.x, y*s.y, z*s.z);
}

/**
* Multiply a given vector by a scalar and place the result in v
* @param v vector multipled
* @param s scalar used to scale the vector
* @throws NullPointerException if v is null
*/
public static void multiply( Vector3 v, double s) {
v.x*=s; v.y*=s; v.z*=s;
}

/**
*
* @param v
* @param s
* @param result
* @throws NullPointerException if v ot result is null
*/
public static void multiplyAndAdd( Vector3 v, double s, Vector3 result) {
result.x += v.x*s;
result.y += v.y*s;
result.z += v.z*s;
}

/**
* Multiply v by s, and store result in v. Add v to result and store in result
* @param v
* @param s
* @param result
* @throws NullPointerException if v ot result is null
*/
public static void  multiplyStoreAndAdd( Vector3 v, double s, Vector3 result) {
v.x *= s;
v.y *= s;
v.z *= s;
result.x += v.x;
result.y += v.y;
result.z += v.z;
}

/**
* Returns the dot product of this vector and vector v.
* Neither <code>this</code> nor <code>v</code> is modified.
* @param v the other vector
* @return the dot product of this and v1
* @throws NullPointerException if v is null
*/
public final double dot( Vector3 v ) {
return this.x*v.x+this.y*v.y+this.z*v.z;
}
/**
* Returns the dot product of this vector and vector v.
* Neither <code>this</code> nor <code>v</code> is modified.
* z coordinated if trucated
* @param v the other vector
* @return the dot product of this and v1
* @throws NullPointerException
*/
public final double xydot( Vector3 v ) {
return this.x*v.x+this.y*v.y;
}

/**
* Return a new new set to the cross product of this vectors and v
* Neither <code>this</code> nor <code>v</code> is modified.
* @param v a not null vector
* @return the cross product
* @throws NullPointerException when v is null
*/
public final Vector3 cross( final Vector3 v ) {
return new Vector3( y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x );
}
/**
* Sets result vector to the vector cross product of vectors v1 and v2.
* Neither <code>v1</code> nor <code>v2</code> is modified.
* @param v1 the first vector
* @param v2 the second vector
* @param result
*/
public static void crossProduct( final Vector3 v1, final Vector3 v2, final Vector3 result ) {
final double tempa1 = v1.y*v2.z-v1.z*v2.y;
final double tempa2 = v1.z*v2.x-v1.x*v2.z;
final double tempa3 = v1.x*v2.y-v1.y*v2.x;

result.x = tempa1;
result.y = tempa2;
result.z = tempa3;
}

/**
* Return a new vector set to the normalization of vector v1.
* <code>this</code> vector is not modified.
* @return the normalized vector
*/
public final Vector3 normalize() {
double l = Math.sqrt(x*x+y*y+z*z);
if ( l == 0.0 ) {return new Vector3(1,0,0); }
l=1./l;
return new Vector3( x*l, y*l, z*l);
}
/**
* Sets the value of this <code>Vector3</code> to the specified x, y and  coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @return return this
*/
public final Vector3 assign( double x, double y, double z ) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
/**
* A this vector to the provided coordinates creating a new resultant vector.
* <code>this</code> vector is not modified
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @return the result vector
*/
public final Vector3 add( double x, double y, double z ) {
return new Vector3( this.x+x, this.y+y, this.z+z);
}

/**
* Sets the value of this vector to the value of the xyz coordinates of the
* given vector.
* <code>v</code> is not modified
* @param v the vector to be copied
* @return <code>this</code>
* @throws NullPointerException
*/
public final Vector3 assign( Vector3 v ) {
double t1 =v.x;
double t2 =v.y;
double t3 =v.z;
x = t1;
y = t2;
z = t3;
return this;
}
/**
*
* @return
*/
public final Vector3 assignZero() {
x = 0;
y = 0;
z = 0;
return this;
}

/**
* Returns the length of this vector.
* <code>this</code> vector is not modified.
* @return Returns the length of this vector.
*/
public final double norm() {
return Math.sqrt( x*x + y*y + z*z );
}
/**
* Returns the length of this vector.
* z coordinate is truncated.
* <code>this</code> vector is not modified.
* @return Double.NaN when Double.isNaN(x) || Double.isNaN(y)
*/
public final double xynorm() {
return Math.sqrt( x*x + y*y );
}

/**
* Returns the length of this vector.
* <code>this</code> vector is not modified.
* @return the length of this vector
*/
public final double squaredNorm() {
return x*x+y*y+z*z;
}

/**
* Returns <tt>true</tt> if the absolute value of the three coordinates are
* smaller or equal to epsilon.
*
* @param epsilon positive tolerance around zero
* @return true when the coordinates are next to zero
*         false in the other cases
*/
public final boolean isEpsilon(double epsilon) {
if (epsilon < 0.) {
throw new IllegalArgumentException("epsilon must be positive");
}
return -epsilon <= x && x <= epsilon
&& -epsilon <= y && y <= epsilon
&& -epsilon <= z && z <= epsilon;
}
/**
* Pack the three coorindates into a new double array
* <code>this</code> vector is not modified.
* @return a array set with x, y and z
*/
public final double[] toArray() {
return new double[]{x,y,z};
}

/**
* Returns a string representation of this vector.  The string
* representation consists of the three dimentions in the order x, y, z,
* enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
* separated by the characters <tt>", "</tt> (comma and space).
* Elements are converted to strings as by {@link Double#toString(double)}.
*
* @return a string representation of this vector
*/
@Override
public final String toString() {
return  "[" + x + ", " +y+ ", " +z + "]";
}
}

```

Related examples in the same category

 1 Implementation of a 4x4 matrix suited for use in a 2D and 3D graphics rendering engine 2 Rotations in a three-dimensional space 3 This class represents a lower (or upper) triangle matrix that stores ints. 4 The Java Matrix Class provides the fundamental operations of numerical linear algebra 5 Vector extends Matrix 6 4 x 4 Matrix 7 Various geometric transformations on matrix form 8 Inertia Matrix 9 Simulate a matrix. Provides method to travers vectors that compose the matrix.