source-cvs/ 0000755 0001750 0001750 00000000000 11101655734 012226 5 ustar jonny jonny source-cvs/vecmath/ 0000755 0001750 0001750 00000000000 11101655740 013652 5 ustar jonny jonny source-cvs/vecmath/README-build.html 0000644 0001750 0001750 00000005031 10563126733 016577 0 ustar jonny jonny
README-build: build instructions for the vecmath project
Building
the Vecmath Package
To
build the vecmath package, you must first checkout the vecmath
CVS
repository on java.net. For example, run
the cvs checkout command as follows:
cd <cvs-root-dir>
cvs checkout vecmath
This top-level directory must be named "vecmath".
System Requirements
Vecmath is 100% Java, so any operating environment that supports
J2SE should work. We have built vecmath on the following
operating environments:
- Solaris: Sparc (Ultra60 or better) running Solaris 9
- Linux: i386/i586 running SuSE 9 or RedHat 9.0
- Windows: Windows/XP (Windows
2000 should work, but is untested)
The following software must be installed:
Building
Vecmath
Before you start building,
please check that your PATH must
include the
following directories:
- <ant-root-dir>/bin
- <jdk-root_dir>/bin
The default target, jar-opt, creates an optimized jar files.
Steps:
cd <cvs-root-dir>/vecmath
ant
This will build the javax.vecmath
package, which will
be put
in the vecmath/build/opt
sub-directory.
To see other targets that are available, type "ant
-projecthelp". Note that ant must be run from the top-level
directory.
source-cvs/vecmath/LICENSE-SPEC.html 0000644 0001750 0001750 00000001603 10761613451 016356 0 ustar jonny jonny
3D Graphics API for the Java Platform
Copyright 1996-2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
This javadoc-generated API documentation is not an
official API specification. This documentation may contain references to
Java and Java 3D, both of which are trademarks of Sun Microsystems, Inc.
Any reference to these and other trademarks of Sun Microsystems are
for explanatory purposes only. Their use does impart any rights beyond
those listed in the source code license. In particular, Sun Microsystems
retains all intellectual property and trademark rights as described in
the proprietary rights notice in the COPYRIGHT.txt file.
source-cvs/vecmath/build.xml 0000644 0001750 0001750 00000021035 10761613451 015500 0 ustar jonny jonny
The following ant targets are available ("jar-debug" is the default):
all - execute targets jar-debug and dist
clean - removes WS/build/ and WS/dist/
clean-dist - removes WS/dist
compile - execute targets compile-debug and compile-opt
compile-debug - builds all classes in WS/src into class files
under WS/build/classes/debug
compile-opt - builds all classes in WS/src/ into class files
under WS/build/classes/opt
dist - creates WS/dist/lib/opt/ext/vecmath.jar
from class files under WS/build/classes/opt and
creates WS/dist/doc/vecmath-${version}-doc.zip from
javadoc under WS/build/javadocs
docs - builds all classes in WS/src into javadoc under
WS/build/javadocs
echo - echo some useful information, such as user.home,
ant.home and java.home
jar - execute targets jar-debug and jar-opt
jar-debug - creates WS/build/lib/debug/ext/vecmath.jar
from class files under WS/build/classes/debug
jar-opt - creates WS/build/lib/opt/ext/vecmath.jar
from class files under WS/build/classes/opt
source-cvs/vecmath/src/ 0000755 0001750 0001750 00000000000 11101655734 014444 5 ustar jonny jonny source-cvs/vecmath/src/VECMATH.MF 0000644 0001750 0001750 00000001050 10761613452 015755 0 ustar jonny jonny Manifest-Version: 1.0
Specification-Title: @SPEC_TITLE@
Specification-Version: 1.5
Specification-Vendor: @SPEC_VENDOR@
Implementation-Title: @IMPL_TITLE@
Implementation-Version: @VERSION_BASE@
Implementation-Vendor: @IMPL_VENDOR@
Extension-Name: javax.vecmath
Implementation-Vendor-Id: @IMPL_VENDOR_ID@
Bundle-ManifestVersion: 2
Bundle-Name: Vecmath Library
Bundle-Vendor: @IMPL_VENDOR@
Bundle-Localization: plugin
Bundle-SymbolicName: javax.vecmath; singleton:=true
Bundle-Version: @VERSION_BASE@
Eclipse-AutoStart: true
Export-Package: javax.vecmath
source-cvs/vecmath/src/javax/ 0000755 0001750 0001750 00000000000 11101655734 015555 5 ustar jonny jonny source-cvs/vecmath/src/javax/vecmath/ 0000755 0001750 0001750 00000000000 11101655740 017201 5 ustar jonny jonny source-cvs/vecmath/src/javax/vecmath/Matrix4f.java 0000644 0001750 0001750 00000305461 10761613452 021560 0 ustar jonny jonny /*
* $RCSfile: Matrix4f.java,v $
*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.8 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A single precision floating point 4 by 4 matrix.
* Primarily to support 3D rotations.
*
*/
public class Matrix4f implements java.io.Serializable, Cloneable {
// Compatible with 1.1
static final long serialVersionUID = -8405036035410109353L;
/**
* The first element of the first row.
*/
public float m00;
/**
* The second element of the first row.
*/
public float m01;
/**
* The third element of the first row.
*/
public float m02;
/**
* The fourth element of the first row.
*/
public float m03;
/**
* The first element of the second row.
*/
public float m10;
/**
* The second element of the second row.
*/
public float m11;
/**
* The third element of the second row.
*/
public float m12;
/**
* The fourth element of the second row.
*/
public float m13;
/**
* The first element of the third row.
*/
public float m20;
/**
* The second element of the third row.
*/
public float m21;
/**
* The third element of the third row.
*/
public float m22;
/**
* The fourth element of the third row.
*/
public float m23;
/**
* The first element of the fourth row.
*/
public float m30;
/**
* The second element of the fourth row.
*/
public float m31;
/**
* The third element of the fourth row.
*/
public float m32;
/**
* The fourth element of the fourth row.
*/
public float m33;
/*
double[] tmp = new double[9];
double[] tmp_scale = new double[3];
double[] tmp_rot = new double[9];
*/
private static final double EPS = 1.0E-8;
/**
* Constructs and initializes a Matrix4f from the specified 16 values.
* @param m00 the [0][0] element
* @param m01 the [0][1] element
* @param m02 the [0][2] element
* @param m03 the [0][3] element
* @param m10 the [1][0] element
* @param m11 the [1][1] element
* @param m12 the [1][2] element
* @param m13 the [1][3] element
* @param m20 the [2][0] element
* @param m21 the [2][1] element
* @param m22 the [2][2] element
* @param m23 the [2][3] element
* @param m30 the [3][0] element
* @param m31 the [3][1] element
* @param m32 the [3][2] element
* @param m33 the [3][3] element
*/
public Matrix4f(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m03 = m03;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
this.m13 = m13;
this.m20 = m20;
this.m21 = m21;
this.m22 = m22;
this.m23 = m23;
this.m30 = m30;
this.m31 = m31;
this.m32 = m32;
this.m33 = m33;
}
/**
* Constructs and initializes a Matrix4f from the specified 16
* element array. this.m00 =v[0], this.m01=v[1], etc.
* @param v the array of length 16 containing in order
*/
public Matrix4f(float[] v)
{
this.m00 = v[ 0];
this.m01 = v[ 1];
this.m02 = v[ 2];
this.m03 = v[ 3];
this.m10 = v[ 4];
this.m11 = v[ 5];
this.m12 = v[ 6];
this.m13 = v[ 7];
this.m20 = v[ 8];
this.m21 = v[ 9];
this.m22 = v[10];
this.m23 = v[11];
this.m30 = v[12];
this.m31 = v[13];
this.m32 = v[14];
this.m33 = v[15];
}
/**
* Constructs and initializes a Matrix4f from the quaternion,
* translation, and scale values; the scale is applied only to the
* rotational components of the matrix (upper 3x3) and not to the
* translational components.
* @param q1 the quaternion value representing the rotational component
* @param t1 the translational component of the matrix
* @param s the scale value applied to the rotational components
*/
public Matrix4f(Quat4f q1, Vector3f t1, float s)
{
m00 = (float)(s*(1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z));
m10 = (float)(s*(2.0*(q1.x*q1.y + q1.w*q1.z)));
m20 = (float)(s*(2.0*(q1.x*q1.z - q1.w*q1.y)));
m01 = (float)(s*(2.0*(q1.x*q1.y - q1.w*q1.z)));
m11 = (float)(s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z));
m21 = (float)(s*(2.0*(q1.y*q1.z + q1.w*q1.x)));
m02 = (float)(s*(2.0*(q1.x*q1.z + q1.w*q1.y)));
m12 = (float)(s*(2.0*(q1.y*q1.z - q1.w*q1.x)));
m22 = (float)(s*(1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y));
m03 = t1.x;
m13 = t1.y;
m23 = t1.z;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
/**
* Constructs a new matrix with the same values as the
* Matrix4d parameter.
* @param m1 the source matrix
*/
public Matrix4f(Matrix4d m1)
{
this.m00 = (float)m1.m00;
this.m01 = (float)m1.m01;
this.m02 = (float)m1.m02;
this.m03 = (float)m1.m03;
this.m10 = (float)m1.m10;
this.m11 = (float)m1.m11;
this.m12 = (float)m1.m12;
this.m13 = (float)m1.m13;
this.m20 = (float)m1.m20;
this.m21 = (float)m1.m21;
this.m22 = (float)m1.m22;
this.m23 = (float)m1.m23;
this.m30 = (float)m1.m30;
this.m31 = (float)m1.m31;
this.m32 = (float)m1.m32;
this.m33 = (float)m1.m33;
}
/**
* Constructs a new matrix with the same values as the
* Matrix4f parameter.
* @param m1 the source matrix
*/
public Matrix4f(Matrix4f m1)
{
this.m00 = m1.m00;
this.m01 = m1.m01;
this.m02 = m1.m02;
this.m03 = m1.m03;
this.m10 = m1.m10;
this.m11 = m1.m11;
this.m12 = m1.m12;
this.m13 = m1.m13;
this.m20 = m1.m20;
this.m21 = m1.m21;
this.m22 = m1.m22;
this.m23 = m1.m23;
this.m30 = m1.m30;
this.m31 = m1.m31;
this.m32 = m1.m32;
this.m33 = m1.m33;
}
/**
* Constructs and initializes a Matrix4f from the rotation matrix,
* translation, and scale values; the scale is applied only to the
* rotational components of the matrix (upper 3x3) and not to the
* translational components of the matrix.
* @param m1 the rotation matrix representing the rotational components
* @param t1 the translational components of the matrix
* @param s the scale value applied to the rotational components
*/
public Matrix4f(Matrix3f m1, Vector3f t1, float s)
{
this.m00 = m1.m00*s;
this.m01 = m1.m01*s;
this.m02 = m1.m02*s;
this.m03 = t1.x;
this.m10 = m1.m10*s;
this.m11 = m1.m11*s;
this.m12 = m1.m12*s;
this.m13 = t1.y;
this.m20 = m1.m20*s;
this.m21 = m1.m21*s;
this.m22 = m1.m22*s;
this.m23 = t1.z;
this.m30 = 0.0f;
this.m31 = 0.0f;
this.m32 = 0.0f;
this.m33 = 1.0f;
}
/**
* Constructs and initializes a Matrix4f to all zeros.
*/
public Matrix4f()
{
this.m00 = (float) 0.0;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = (float) 0.0;
this.m10 = (float) 0.0;
this.m11 = (float) 0.0;
this.m12 = (float) 0.0;
this.m13 = (float) 0.0;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = (float) 0.0;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 0.0;
}
/**
* Returns a string that contains the values of this Matrix4f.
* @return the String representation
*/
public String toString() {
return
this.m00 + ", " + this.m01 + ", " + this.m02 + ", " + this.m03 + "\n" +
this.m10 + ", " + this.m11 + ", " + this.m12 + ", " + this.m13 + "\n" +
this.m20 + ", " + this.m21 + ", " + this.m22 + ", " + this.m23 + "\n" +
this.m30 + ", " + this.m31 + ", " + this.m32 + ", " + this.m33 + "\n";
}
/**
* Sets this Matrix4f to identity.
*/
public final void setIdentity()
{
this.m00 = (float) 1.0;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = (float) 0.0;
this.m10 = (float) 0.0;
this.m11 = (float) 1.0;
this.m12 = (float) 0.0;
this.m13 = (float) 0.0;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = (float) 1.0;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the specified element of this matrix4f to the value provided.
* @param row the row number to be modified (zero indexed)
* @param column the column number to be modified (zero indexed)
* @param value the new value
*/
public final void setElement(int row, int column, float value)
{
switch (row)
{
case 0:
switch(column)
{
case 0:
this.m00 = value;
break;
case 1:
this.m01 = value;
break;
case 2:
this.m02 = value;
break;
case 3:
this.m03 = value;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f0"));
}
break;
case 1:
switch(column)
{
case 0:
this.m10 = value;
break;
case 1:
this.m11 = value;
break;
case 2:
this.m12 = value;
break;
case 3:
this.m13 = value;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f0"));
}
break;
case 2:
switch(column)
{
case 0:
this.m20 = value;
break;
case 1:
this.m21 = value;
break;
case 2:
this.m22 = value;
break;
case 3:
this.m23 = value;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f0"));
}
break;
case 3:
switch(column)
{
case 0:
this.m30 = value;
break;
case 1:
this.m31 = value;
break;
case 2:
this.m32 = value;
break;
case 3:
this.m33 = value;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f0"));
}
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f0"));
}
}
/**
* Retrieves the value at the specified row and column of this matrix.
* @param row the row number to be retrieved (zero indexed)
* @param column the column number to be retrieved (zero indexed)
* @return the value at the indexed element
*/
public final float getElement(int row, int column)
{
switch (row)
{
case 0:
switch(column)
{
case 0:
return(this.m00);
case 1:
return(this.m01);
case 2:
return(this.m02);
case 3:
return(this.m03);
default:
break;
}
break;
case 1:
switch(column)
{
case 0:
return(this.m10);
case 1:
return(this.m11);
case 2:
return(this.m12);
case 3:
return(this.m13);
default:
break;
}
break;
case 2:
switch(column)
{
case 0:
return(this.m20);
case 1:
return(this.m21);
case 2:
return(this.m22);
case 3:
return(this.m23);
default:
break;
}
break;
case 3:
switch(column)
{
case 0:
return(this.m30);
case 1:
return(this.m31);
case 2:
return(this.m32);
case 3:
return(this.m33);
default:
break;
}
break;
default:
break;
}
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f1"));
}
/**
* Copies the matrix values in the specified row into the vector parameter.
* @param row the matrix row
* @param v the vector into which the matrix row values will be copied
*/
public final void getRow(int row, Vector4f v) {
if( row == 0 ) {
v.x = m00;
v.y = m01;
v.z = m02;
v.w = m03;
} else if(row == 1) {
v.x = m10;
v.y = m11;
v.z = m12;
v.w = m13;
} else if(row == 2) {
v.x = m20;
v.y = m21;
v.z = m22;
v.w = m23;
} else if(row == 3) {
v.x = m30;
v.y = m31;
v.z = m32;
v.w = m33;
} else {
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f2"));
}
}
/**
* Copies the matrix values in the specified row into the array parameter.
* @param row the matrix row
* @param v the array into which the matrix row values will be copied
*/
public final void getRow(int row, float v[]) {
if( row == 0 ) {
v[0] = m00;
v[1] = m01;
v[2] = m02;
v[3] = m03;
} else if(row == 1) {
v[0] = m10;
v[1] = m11;
v[2] = m12;
v[3] = m13;
} else if(row == 2) {
v[0] = m20;
v[1] = m21;
v[2] = m22;
v[3] = m23;
} else if(row == 3) {
v[0] = m30;
v[1] = m31;
v[2] = m32;
v[3] = m33;
} else {
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f2"));
}
}
/**
* Copies the matrix values in the specified column into the vector
* parameter.
* @param column the matrix column
* @param v the vector into which the matrix row values will be copied
*/
public final void getColumn(int column, Vector4f v) {
if( column == 0 ) {
v.x = m00;
v.y = m10;
v.z = m20;
v.w = m30;
} else if(column == 1) {
v.x = m01;
v.y = m11;
v.z = m21;
v.w = m31;
} else if(column == 2) {
v.x = m02;
v.y = m12;
v.z = m22;
v.w = m32;
} else if(column == 3) {
v.x = m03;
v.y = m13;
v.z = m23;
v.w = m33;
} else {
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f4"));
}
}
/**
* Copies the matrix values in the specified column into the array
* parameter.
* @param column the matrix column
* @param v the array into which the matrix row values will be copied
*/
public final void getColumn(int column, float v[]) {
if( column == 0 ) {
v[0] = m00;
v[1] = m10;
v[2] = m20;
v[3] = m30;
} else if(column == 1) {
v[0] = m01;
v[1] = m11;
v[2] = m21;
v[3] = m31;
} else if(column == 2) {
v[0] = m02;
v[1] = m12;
v[2] = m22;
v[3] = m32;
} else if(column == 3) {
v[0] = m03;
v[1] = m13;
v[2] = m23;
v[3] = m33;
} else {
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f4"));
}
}
/**
* Sets the scale component of the current matrix by factoring
* out the current scale (by doing an SVD) from the rotational
* component and multiplying by the new scale.
* @param scale the new scale amount
*/
public final void setScale(float scale){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m00 = (float)(tmp_rot[0]*scale);
m01 = (float)(tmp_rot[1]*scale);
m02 = (float)(tmp_rot[2]*scale);
m10 = (float)(tmp_rot[3]*scale);
m11 = (float)(tmp_rot[4]*scale);
m12 = (float)(tmp_rot[5]*scale);
m20 = (float)(tmp_rot[6]*scale);
m21 = (float)(tmp_rot[7]*scale);
m22 = (float)(tmp_rot[8]*scale);
}
/**
* Performs an SVD normalization of this matrix in order to acquire
* the normalized rotational component; the values are placed into
* the Matrix3d parameter.
* @param m1 matrix into which the rotational component is placed
*/
public final void get(Matrix3d m1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m1.m00 = tmp_rot[0];
m1.m01 = tmp_rot[1];
m1.m02 = tmp_rot[2];
m1.m10 = tmp_rot[3];
m1.m11 = tmp_rot[4];
m1.m12 = tmp_rot[5];
m1.m20 = tmp_rot[6];
m1.m21 = tmp_rot[7];
m1.m22 = tmp_rot[8];
}
/**
* Performs an SVD normalization of this matrix in order to acquire
* the normalized rotational component; the values are placed into
* the Matrix3f parameter.
* @param m1 matrix into which the rotational component is placed
*/
public final void get(Matrix3f m1)
{
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m1.m00 = (float)tmp_rot[0];
m1.m01 = (float)tmp_rot[1];
m1.m02 = (float)tmp_rot[2];
m1.m10 = (float)tmp_rot[3];
m1.m11 = (float)tmp_rot[4];
m1.m12 = (float)tmp_rot[5];
m1.m20 = (float)tmp_rot[6];
m1.m21 = (float)tmp_rot[7];
m1.m22 = (float)tmp_rot[8];
}
/**
* Performs an SVD normalization of this matrix to calculate
* the rotation as a 3x3 matrix, the translation, and the scale.
* None of the matrix values are modified.
* @param m1 the normalized matrix representing the rotation
* @param t1 the translation component
* @return the scale component of this transform
*/
public final float get(Matrix3f m1, Vector3f t1)
{
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m1.m00 = (float)tmp_rot[0];
m1.m01 = (float)tmp_rot[1];
m1.m02 = (float)tmp_rot[2];
m1.m10 = (float)tmp_rot[3];
m1.m11 = (float)tmp_rot[4];
m1.m12 = (float)tmp_rot[5];
m1.m20 = (float)tmp_rot[6];
m1.m21 = (float)tmp_rot[7];
m1.m22 = (float)tmp_rot[8];
t1.x = m03;
t1.y = m13;
t1.z = m23;
return( (float)Matrix3d.max3( tmp_scale ));
}
/**
* Performs an SVD normalization of this matrix in order to acquire
* the normalized rotational component; the values are placed into
* the Quat4f parameter.
* @param q1 quaternion into which the rotation component is placed
*/
public final void get(Quat4f q1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
double ww;
ww = 0.25*(1.0 + tmp_rot[0] + tmp_rot[4] + tmp_rot[8]);
if(!((ww<0?-ww:ww) < 1.0e-30)) {
q1.w = (float)Math.sqrt(ww);
ww = 0.25/q1.w;
q1.x = (float)((tmp_rot[7] - tmp_rot[5])*ww);
q1.y = (float)((tmp_rot[2] - tmp_rot[6])*ww);
q1.z = (float)((tmp_rot[3] - tmp_rot[1])*ww);
return;
}
q1.w = 0.0f;
ww = -0.5*(tmp_rot[4] + tmp_rot[8]);
if(!((ww<0?-ww:ww) < 1.0e-30)) {
q1.x = (float)Math.sqrt(ww);
ww = 0.5/q1.x;
q1.y = (float)(tmp_rot[3]*ww);
q1.z = (float)(tmp_rot[6]*ww);
return;
}
q1.x = 0.0f;
ww = 0.5*(1.0 - tmp_rot[8]);
if(!((ww<0?-ww:ww) < 1.0e-30)) {
q1.y = (float)(Math.sqrt(ww));
q1.z = (float)(tmp_rot[7]/(2.0*q1.y));
return;
}
q1.y = 0.0f;
q1.z = 1.0f;
}
/**
* Retrieves the translational components of this matrix.
* @param trans the vector that will receive the translational component
*/
public final void get(Vector3f trans)
{
trans.x = m03;
trans.y = m13;
trans.z = m23;
}
/**
* Gets the upper 3x3 values of this matrix and places them into
* the matrix m1.
* @param m1 the matrix that will hold the values
*/
public final void getRotationScale(Matrix3f m1)
{
m1.m00 = m00; m1.m01 = m01; m1.m02 = m02;
m1.m10 = m10; m1.m11 = m11; m1.m12 = m12;
m1.m20 = m20; m1.m21 = m21; m1.m22 = m22;
}
/**
* Performs an SVD normalization of this matrix to calculate
* and return the uniform scale factor. If the matrix has non-uniform
* scale factors, the largest of the x, y, and z scale factors will
* be returned. This matrix is not modified.
* @return the scale factor of this matrix
*/
public final float getScale()
{
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
return( (float)Matrix3d.max3( tmp_scale ));
}
/**
* Replaces the upper 3x3 matrix values of this matrix with the
* values in the matrix m1.
* @param m1 the matrix that will be the new upper 3x3
*/
public final void setRotationScale(Matrix3f m1)
{
m00 = m1.m00; m01 = m1.m01; m02 = m1.m02;
m10 = m1.m10; m11 = m1.m11; m12 = m1.m12;
m20 = m1.m20; m21 = m1.m21; m22 = m1.m22;
}
/**
* Sets the specified row of this matrix4f to the four values provided.
* @param row the row number to be modified (zero indexed)
* @param x the first column element
* @param y the second column element
* @param z the third column element
* @param w the fourth column element
*/
public final void setRow(int row, float x, float y, float z, float w)
{
switch (row) {
case 0:
this.m00 = x;
this.m01 = y;
this.m02 = z;
this.m03 = w;
break;
case 1:
this.m10 = x;
this.m11 = y;
this.m12 = z;
this.m13 = w;
break;
case 2:
this.m20 = x;
this.m21 = y;
this.m22 = z;
this.m23 = w;
break;
case 3:
this.m30 = x;
this.m31 = y;
this.m32 = z;
this.m33 = w;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f6"));
}
}
/**
* Sets the specified row of this matrix4f to the Vector provided.
* @param row the row number to be modified (zero indexed)
* @param v the replacement row
*/
public final void setRow(int row, Vector4f v)
{
switch (row) {
case 0:
this.m00 = v.x;
this.m01 = v.y;
this.m02 = v.z;
this.m03 = v.w;
break;
case 1:
this.m10 = v.x;
this.m11 = v.y;
this.m12 = v.z;
this.m13 = v.w;
break;
case 2:
this.m20 = v.x;
this.m21 = v.y;
this.m22 = v.z;
this.m23 = v.w;
break;
case 3:
this.m30 = v.x;
this.m31 = v.y;
this.m32 = v.z;
this.m33 = v.w;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f6"));
}
}
/**
* Sets the specified row of this matrix4f to the four values provided
* in the passed array.
* @param row the row number to be modified (zero indexed)
* @param v the replacement row
*/
public final void setRow(int row, float v[])
{
switch (row) {
case 0:
this.m00 = v[0];
this.m01 = v[1];
this.m02 = v[2];
this.m03 = v[3];
break;
case 1:
this.m10 = v[0];
this.m11 = v[1];
this.m12 = v[2];
this.m13 = v[3];
break;
case 2:
this.m20 = v[0];
this.m21 = v[1];
this.m22 = v[2];
this.m23 = v[3];
break;
case 3:
this.m30 = v[0];
this.m31 = v[1];
this.m32 = v[2];
this.m33 = v[3];
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f6"));
}
}
/**
* Sets the specified column of this matrix4f to the four values provided.
* @param column the column number to be modified (zero indexed)
* @param x the first row element
* @param y the second row element
* @param z the third row element
* @param w the fourth row element
*/
public final void setColumn(int column, float x, float y, float z, float w)
{
switch (column) {
case 0:
this.m00 = x;
this.m10 = y;
this.m20 = z;
this.m30 = w;
break;
case 1:
this.m01 = x;
this.m11 = y;
this.m21 = z;
this.m31 = w;
break;
case 2:
this.m02 = x;
this.m12 = y;
this.m22 = z;
this.m32 = w;
break;
case 3:
this.m03 = x;
this.m13 = y;
this.m23 = z;
this.m33 = w;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f9"));
}
}
/**
* Sets the specified column of this matrix4f to the vector provided.
* @param column the column number to be modified (zero indexed)
* @param v the replacement column
*/
public final void setColumn(int column, Vector4f v)
{
switch (column) {
case 0:
this.m00 = v.x;
this.m10 = v.y;
this.m20 = v.z;
this.m30 = v.w;
break;
case 1:
this.m01 = v.x;
this.m11 = v.y;
this.m21 = v.z;
this.m31 = v.w;
break;
case 2:
this.m02 = v.x;
this.m12 = v.y;
this.m22 = v.z;
this.m32 = v.w;
break;
case 3:
this.m03 = v.x;
this.m13 = v.y;
this.m23 = v.z;
this.m33 = v.w;
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f9"));
}
}
/**
* Sets the specified column of this matrix4f to the four values provided.
* @param column the column number to be modified (zero indexed)
* @param v the replacement column
*/
public final void setColumn(int column, float v[])
{
switch (column) {
case 0:
this.m00 = v[0];
this.m10 = v[1];
this.m20 = v[2];
this.m30 = v[3];
break;
case 1:
this.m01 = v[0];
this.m11 = v[1];
this.m21 = v[2];
this.m31 = v[3];
break;
case 2:
this.m02 = v[0];
this.m12 = v[1];
this.m22 = v[2];
this.m32 = v[3];
break;
case 3:
this.m03 = v[0];
this.m13 = v[1];
this.m23 = v[2];
this.m33 = v[3];
break;
default:
throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4f9"));
}
}
/**
* Adds a scalar to each component of this matrix.
* @param scalar the scalar adder
*/
public final void add(float scalar)
{
m00 += scalar;
m01 += scalar;
m02 += scalar;
m03 += scalar;
m10 += scalar;
m11 += scalar;
m12 += scalar;
m13 += scalar;
m20 += scalar;
m21 += scalar;
m22 += scalar;
m23 += scalar;
m30 += scalar;
m31 += scalar;
m32 += scalar;
m33 += scalar;
}
/**
* Adds a scalar to each component of the matrix m1 and places
* the result into this. Matrix m1 is not modified.
* @param scalar the scalar adder
* @param m1 the original matrix values
*/
public final void add(float scalar, Matrix4f m1)
{
this.m00 = m1.m00 + scalar;
this.m01 = m1.m01 + scalar;
this.m02 = m1.m02 + scalar;
this.m03 = m1.m03 + scalar;
this.m10 = m1.m10 + scalar;
this.m11 = m1.m11 + scalar;
this.m12 = m1.m12 + scalar;
this.m13 = m1.m13 + scalar;
this.m20 = m1.m20 + scalar;
this.m21 = m1.m21 + scalar;
this.m22 = m1.m22 + scalar;
this.m23 = m1.m23 + scalar;
this.m30 = m1.m30 + scalar;
this.m31 = m1.m31 + scalar;
this.m32 = m1.m32 + scalar;
this.m33 = m1.m33 + scalar;
}
/**
* Sets the value of this matrix to the matrix sum of matrices m1 and m2.
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void add(Matrix4f m1, Matrix4f m2)
{
this.m00 = m1.m00 + m2.m00;
this.m01 = m1.m01 + m2.m01;
this.m02 = m1.m02 + m2.m02;
this.m03 = m1.m03 + m2.m03;
this.m10 = m1.m10 + m2.m10;
this.m11 = m1.m11 + m2.m11;
this.m12 = m1.m12 + m2.m12;
this.m13 = m1.m13 + m2.m13;
this.m20 = m1.m20 + m2.m20;
this.m21 = m1.m21 + m2.m21;
this.m22 = m1.m22 + m2.m22;
this.m23 = m1.m23 + m2.m23;
this.m30 = m1.m30 + m2.m30;
this.m31 = m1.m31 + m2.m31;
this.m32 = m1.m32 + m2.m32;
this.m33 = m1.m33 + m2.m33;
}
/**
* Sets the value of this matrix to the sum of itself and matrix m1.
* @param m1 the other matrix
*/
public final void add(Matrix4f m1)
{
this.m00 += m1.m00;
this.m01 += m1.m01;
this.m02 += m1.m02;
this.m03 += m1.m03;
this.m10 += m1.m10;
this.m11 += m1.m11;
this.m12 += m1.m12;
this.m13 += m1.m13;
this.m20 += m1.m20;
this.m21 += m1.m21;
this.m22 += m1.m22;
this.m23 += m1.m23;
this.m30 += m1.m30;
this.m31 += m1.m31;
this.m32 += m1.m32;
this.m33 += m1.m33;
}
/**
* Performs an element-by-element subtraction of matrix m2 from
* matrix m1 and places the result into matrix this (this =
* m2 - m1).
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void sub(Matrix4f m1, Matrix4f m2)
{
this.m00 = m1.m00 - m2.m00;
this.m01 = m1.m01 - m2.m01;
this.m02 = m1.m02 - m2.m02;
this.m03 = m1.m03 - m2.m03;
this.m10 = m1.m10 - m2.m10;
this.m11 = m1.m11 - m2.m11;
this.m12 = m1.m12 - m2.m12;
this.m13 = m1.m13 - m2.m13;
this.m20 = m1.m20 - m2.m20;
this.m21 = m1.m21 - m2.m21;
this.m22 = m1.m22 - m2.m22;
this.m23 = m1.m23 - m2.m23;
this.m30 = m1.m30 - m2.m30;
this.m31 = m1.m31 - m2.m31;
this.m32 = m1.m32 - m2.m32;
this.m33 = m1.m33 - m2.m33;
}
/**
* Sets this matrix to the matrix difference of itself and
* matrix m1 (this = this - m1).
* @param m1 the other matrix
*/
public final void sub(Matrix4f m1)
{
this.m00 -= m1.m00;
this.m01 -= m1.m01;
this.m02 -= m1.m02;
this.m03 -= m1.m03;
this.m10 -= m1.m10;
this.m11 -= m1.m11;
this.m12 -= m1.m12;
this.m13 -= m1.m13;
this.m20 -= m1.m20;
this.m21 -= m1.m21;
this.m22 -= m1.m22;
this.m23 -= m1.m23;
this.m30 -= m1.m30;
this.m31 -= m1.m31;
this.m32 -= m1.m32;
this.m33 -= m1.m33;
}
/**
* Sets the value of this matrix to its transpose in place.
*/
public final void transpose()
{
float temp;
temp = this.m10;
this.m10 = this.m01;
this.m01 = temp;
temp = this.m20;
this.m20 = this.m02;
this.m02 = temp;
temp = this.m30;
this.m30 = this.m03;
this.m03 = temp;
temp = this.m21;
this.m21 = this.m12;
this.m12 = temp;
temp = this.m31;
this.m31 = this.m13;
this.m13 = temp;
temp = this.m32;
this.m32 = this.m23;
this.m23 = temp;
}
/**
* Sets the value of this matrix to the transpose of the argument matrix.
* @param m1 the matrix to be transposed
*/
public final void transpose(Matrix4f m1)
{
if (this != m1) {
this.m00 = m1.m00;
this.m01 = m1.m10;
this.m02 = m1.m20;
this.m03 = m1.m30;
this.m10 = m1.m01;
this.m11 = m1.m11;
this.m12 = m1.m21;
this.m13 = m1.m31;
this.m20 = m1.m02;
this.m21 = m1.m12;
this.m22 = m1.m22;
this.m23 = m1.m32;
this.m30 = m1.m03;
this.m31 = m1.m13;
this.m32 = m1.m23;
this.m33 = m1.m33;
} else
this.transpose();
}
/**
* Sets the value of this matrix to the matrix conversion of the
* single precision quaternion argument.
* @param q1 the quaternion to be converted
*/
public final void set(Quat4f q1)
{
this.m00 = (1.0f - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z);
this.m10 = (2.0f*(q1.x*q1.y + q1.w*q1.z));
this.m20 = (2.0f*(q1.x*q1.z - q1.w*q1.y));
this.m01 = (2.0f*(q1.x*q1.y - q1.w*q1.z));
this.m11 = (1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z);
this.m21 = (2.0f*(q1.y*q1.z + q1.w*q1.x));
this.m02 = (2.0f*(q1.x*q1.z + q1.w*q1.y));
this.m12 = (2.0f*(q1.y*q1.z - q1.w*q1.x));
this.m22 = (1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y);
this.m03 = (float) 0.0;
this.m13 = (float) 0.0;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix to the matrix conversion of the
* (single precision) axis and angle argument.
* @param a1 the axis and angle to be converted
*/
public final void set(AxisAngle4f a1)
{
float mag = (float)Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
if( mag < EPS ) {
m00 = 1.0f;
m01 = 0.0f;
m02 = 0.0f;
m10 = 0.0f;
m11 = 1.0f;
m12 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 1.0f;
} else {
mag = 1.0f/mag;
float ax = a1.x*mag;
float ay = a1.y*mag;
float az = a1.z*mag;
float sinTheta = (float)Math.sin((double)a1.angle);
float cosTheta = (float)Math.cos((double)a1.angle);
float t = 1.0f - cosTheta;
float xz = ax * az;
float xy = ax * ay;
float yz = ay * az;
m00 = t * ax * ax + cosTheta;
m01 = t * xy - sinTheta * az;
m02 = t * xz + sinTheta * ay;
m10 = t * xy + sinTheta * az;
m11 = t * ay * ay + cosTheta;
m12 = t * yz - sinTheta * ax;
m20 = t * xz - sinTheta * ay;
m21 = t * yz + sinTheta * ax;
m22 = t * az * az + cosTheta;
}
m03 = 0.0f;
m13 = 0.0f;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
/**
* Sets the value of this matrix to the matrix conversion of the
* double precision quaternion argument.
* @param q1 the quaternion to be converted
*/
public final void set(Quat4d q1)
{
this.m00 = (float) (1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
this.m10 = (float) (2.0*(q1.x*q1.y + q1.w*q1.z));
this.m20 = (float) (2.0*(q1.x*q1.z - q1.w*q1.y));
this.m01 = (float) (2.0*(q1.x*q1.y - q1.w*q1.z));
this.m11 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
this.m21 = (float) (2.0*(q1.y*q1.z + q1.w*q1.x));
this.m02 = (float) (2.0*(q1.x*q1.z + q1.w*q1.y));
this.m12 = (float) (2.0*(q1.y*q1.z - q1.w*q1.x));
this.m22 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
this.m03 = (float) 0.0;
this.m13 = (float) 0.0;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix to the matrix conversion of the
* double precision axis and angle argument.
* @param a1 the axis and angle to be converted
*/
public final void set(AxisAngle4d a1)
{
double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
if( mag < EPS ) {
m00 = 1.0f;
m01 = 0.0f;
m02 = 0.0f;
m10 = 0.0f;
m11 = 1.0f;
m12 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 1.0f;
} else {
mag = 1.0/mag;
double ax = a1.x*mag;
double ay = a1.y*mag;
double az = a1.z*mag;
float sinTheta = (float) Math.sin(a1.angle);
float cosTheta = (float) Math.cos(a1.angle);
float t = 1.0f - cosTheta;
float xz = (float) (ax * az);
float xy = (float) (ax * ay);
float yz = (float) (ay * az);
this.m00 = t * (float)(ax * ax) + cosTheta;
this.m01 = t * xy - sinTheta * (float)az;
this.m02 = t * xz + sinTheta * (float)ay;
this.m10 = t * xy + sinTheta * (float)az;
this.m11 = t * (float)(ay * ay) + cosTheta;
this.m12 = t * yz - sinTheta * (float)ax;
this.m20 = t * xz - sinTheta * (float)ay;
this.m21 = t * yz + sinTheta * (float)ax;
this.m22 = t * (float)(az * az) + cosTheta;
}
this.m03 = 0.0f;
this.m13 = 0.0f;
this.m23 = 0.0f;
this.m30 = 0.0f;
this.m31 = 0.0f;
this.m32 = 0.0f;
this.m33 = 1.0f;
}
/**
* Sets the value of this matrix from the rotation expressed
* by the quaternion q1, the translation t1, and the scale s.
* @param q1 the rotation expressed as a quaternion
* @param t1 the translation
* @param s the scale value
*/
public final void set(Quat4d q1, Vector3d t1, double s)
{
this.m00 = (float) (s*(1.0 - 2.0*q1.y*q1.y -2.0*q1.z*q1.z));
this.m10 = (float) (s*(2.0*(q1.x*q1.y + q1.w*q1.z)));
this.m20 = (float) (s*(2.0*(q1.x*q1.z - q1.w*q1.y)));
this.m01 = (float) (s*(2.0*(q1.x*q1.y - q1.w*q1.z)));
this.m11 = (float) (s*(1.0 - 2.0*q1.x*q1.x -2.0*q1.z*q1.z));
this.m21 = (float) (s*(2.0*(q1.y*q1.z + q1.w*q1.x)));
this.m02 = (float) (s*(2.0*(q1.x*q1.z + q1.w*q1.y)));
this.m12 = (float) (s*(2.0*(q1.y*q1.z - q1.w*q1.x)));
this.m22 = (float) (s*(1.0 - 2.0*q1.x*q1.x -2.0*q1.y*q1.y));
this.m03 = (float) t1.x;
this.m13 = (float) t1.y;
this.m23 = (float) t1.z;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix from the rotation expressed
* by the quaternion q1, the translation t1, and the scale s.
* @param q1 the rotation expressed as a quaternion
* @param t1 the translation
* @param s the scale value
*/
public final void set(Quat4f q1, Vector3f t1, float s)
{
this.m00 = (s*(1.0f - 2.0f*q1.y*q1.y -2.0f*q1.z*q1.z));
this.m10 = (s*(2.0f*(q1.x*q1.y + q1.w*q1.z)));
this.m20 = (s*(2.0f*(q1.x*q1.z - q1.w*q1.y)));
this.m01 = (s*(2.0f*(q1.x*q1.y - q1.w*q1.z)));
this.m11 = (s*(1.0f - 2.0f*q1.x*q1.x -2.0f*q1.z*q1.z));
this.m21 = (s*(2.0f*(q1.y*q1.z + q1.w*q1.x)));
this.m02 = (s*(2.0f*(q1.x*q1.z + q1.w*q1.y)));
this.m12 = (s*(2.0f*(q1.y*q1.z - q1.w*q1.x)));
this.m22 = (s*(1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y));
this.m03 = t1.x;
this.m13 = t1.y;
this.m23 = t1.z;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix to the float value of the
* passed matrix4d m1.
* @param m1 the matrix4d to be converted to float
*/
public final void set(Matrix4d m1)
{
this.m00 = (float) m1.m00;
this.m01 = (float) m1.m01;
this.m02 = (float) m1.m02;
this.m03 = (float) m1.m03;
this.m10 = (float) m1.m10;
this.m11 = (float) m1.m11;
this.m12 = (float) m1.m12;
this.m13 = (float) m1.m13;
this.m20 = (float) m1.m20;
this.m21 = (float) m1.m21;
this.m22 = (float) m1.m22;
this.m23 = (float) m1.m23;
this.m30 = (float) m1.m30;
this.m31 = (float) m1.m31;
this.m32 = (float) m1.m32;
this.m33 = (float) m1.m33;
}
/**
* Sets the value of this matrix to a copy of the
* passed matrix m1.
* @param m1 the matrix to be copied
*/
public final void set(Matrix4f m1)
{
this.m00 = m1.m00;
this.m01 = m1.m01;
this.m02 = m1.m02;
this.m03 = m1.m03;
this.m10 = m1.m10;
this.m11 = m1.m11;
this.m12 = m1.m12;
this.m13 = m1.m13;
this.m20 = m1.m20;
this.m21 = m1.m21;
this.m22 = m1.m22;
this.m23 = m1.m23;
this.m30 = m1.m30;
this.m31 = m1.m31;
this.m32 = m1.m32;
this.m33 = m1.m33;
}
/**
* Sets the value of this matrix to the matrix inverse
* of the passed (user declared) matrix m1.
* @param m1 the matrix to be inverted
*/
public final void invert(Matrix4f m1)
{
invertGeneral( m1);
}
/**
* Inverts this matrix in place.
*/
public final void invert()
{
invertGeneral( this );
}
/**
* General invert routine. Inverts m1 and places the result in "this".
* Note that this routine handles both the "this" version and the
* non-"this" version.
*
* Also note that since this routine is slow anyway, we won't worry
* about allocating a little bit of garbage.
*/
final void invertGeneral(Matrix4f m1) {
double temp[] = new double[16];
double result[] = new double[16];
int row_perm[] = new int[4];
int i, r, c;
// Use LU decomposition and backsubstitution code specifically
// for floating-point 4x4 matrices.
// Copy source matrix to t1tmp
temp[0] = m1.m00;
temp[1] = m1.m01;
temp[2] = m1.m02;
temp[3] = m1.m03;
temp[4] = m1.m10;
temp[5] = m1.m11;
temp[6] = m1.m12;
temp[7] = m1.m13;
temp[8] = m1.m20;
temp[9] = m1.m21;
temp[10] = m1.m22;
temp[11] = m1.m23;
temp[12] = m1.m30;
temp[13] = m1.m31;
temp[14] = m1.m32;
temp[15] = m1.m33;
// Calculate LU decomposition: Is the matrix singular?
if (!luDecomposition(temp, row_perm)) {
// Matrix has no inverse
throw new SingularMatrixException(VecMathI18N.getString("Matrix4f12"));
}
// Perform back substitution on the identity matrix
for(i=0;i<16;i++) result[i] = 0.0;
result[0] = 1.0; result[5] = 1.0; result[10] = 1.0; result[15] = 1.0;
luBacksubstitution(temp, row_perm, result);
this.m00 = (float)result[0];
this.m01 = (float)result[1];
this.m02 = (float)result[2];
this.m03 = (float)result[3];
this.m10 = (float)result[4];
this.m11 = (float)result[5];
this.m12 = (float)result[6];
this.m13 = (float)result[7];
this.m20 = (float)result[8];
this.m21 = (float)result[9];
this.m22 = (float)result[10];
this.m23 = (float)result[11];
this.m30 = (float)result[12];
this.m31 = (float)result[13];
this.m32 = (float)result[14];
this.m33 = (float)result[15];
}
/**
* Given a 4x4 array "matrix0", this function replaces it with the
* LU decomposition of a row-wise permutation of itself. The input
* parameters are "matrix0" and "dimen". The array "matrix0" is also
* an output parameter. The vector "row_perm[4]" is an output
* parameter that contains the row permutations resulting from partial
* pivoting. The output parameter "even_row_xchg" is 1 when the
* number of row exchanges is even, or -1 otherwise. Assumes data
* type is always double.
*
* This function is similar to luDecomposition, except that it
* is tuned specifically for 4x4 matrices.
*
* @return true if the matrix is nonsingular, or false otherwise.
*/
//
// Reference: Press, Flannery, Teukolsky, Vetterling,
// _Numerical_Recipes_in_C_, Cambridge University Press,
// 1988, pp 40-45.
//
static boolean luDecomposition(double[] matrix0,
int[] row_perm) {
double row_scale[] = new double[4];
// Determine implicit scaling information by looping over rows
{
int i, j;
int ptr, rs;
double big, temp;
ptr = 0;
rs = 0;
// For each row ...
i = 4;
while (i-- != 0) {
big = 0.0;
// For each column, find the largest element in the row
j = 4;
while (j-- != 0) {
temp = matrix0[ptr++];
temp = Math.abs(temp);
if (temp > big) {
big = temp;
}
}
// Is the matrix singular?
if (big == 0.0) {
return false;
}
row_scale[rs++] = 1.0 / big;
}
}
{
int j;
int mtx;
mtx = 0;
// For all columns, execute Crout's method
for (j = 0; j < 4; j++) {
int i, imax, k;
int target, p1, p2;
double sum, big, temp;
// Determine elements of upper diagonal matrix U
for (i = 0; i < j; i++) {
target = mtx + (4*i) + j;
sum = matrix0[target];
k = i;
p1 = mtx + (4*i);
p2 = mtx + j;
while (k-- != 0) {
sum -= matrix0[p1] * matrix0[p2];
p1++;
p2 += 4;
}
matrix0[target] = sum;
}
// Search for largest pivot element and calculate
// intermediate elements of lower diagonal matrix L.
big = 0.0;
imax = -1;
for (i = j; i < 4; i++) {
target = mtx + (4*i) + j;
sum = matrix0[target];
k = j;
p1 = mtx + (4*i);
p2 = mtx + j;
while (k-- != 0) {
sum -= matrix0[p1] * matrix0[p2];
p1++;
p2 += 4;
}
matrix0[target] = sum;
// Is this the best pivot so far?
if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
big = temp;
imax = i;
}
}
if (imax < 0) {
throw new RuntimeException(VecMathI18N.getString("Matrix4f13"));
}
// Is a row exchange necessary?
if (j != imax) {
// Yes: exchange rows
k = 4;
p1 = mtx + (4*imax);
p2 = mtx + (4*j);
while (k-- != 0) {
temp = matrix0[p1];
matrix0[p1++] = matrix0[p2];
matrix0[p2++] = temp;
}
// Record change in scale factor
row_scale[imax] = row_scale[j];
}
// Record row permutation
row_perm[j] = imax;
// Is the matrix singular
if (matrix0[(mtx + (4*j) + j)] == 0.0) {
return false;
}
// Divide elements of lower diagonal matrix L by pivot
if (j != (4-1)) {
temp = 1.0 / (matrix0[(mtx + (4*j) + j)]);
target = mtx + (4*(j+1)) + j;
i = 3 - j;
while (i-- != 0) {
matrix0[target] *= temp;
target += 4;
}
}
}
}
return true;
}
/**
* Solves a set of linear equations. The input parameters "matrix1",
* and "row_perm" come from luDecompostionD4x4 and do not change
* here. The parameter "matrix2" is a set of column vectors assembled
* into a 4x4 matrix of floating-point values. The procedure takes each
* column of "matrix2" in turn and treats it as the right-hand side of the
* matrix equation Ax = LUx = b. The solution vector replaces the
* original column of the matrix.
*
* If "matrix2" is the identity matrix, the procedure replaces its contents
* with the inverse of the matrix from which "matrix1" was originally
* derived.
*/
//
// Reference: Press, Flannery, Teukolsky, Vetterling,
// _Numerical_Recipes_in_C_, Cambridge University Press,
// 1988, pp 44-45.
//
static void luBacksubstitution(double[] matrix1,
int[] row_perm,
double[] matrix2) {
int i, ii, ip, j, k;
int rp;
int cv, rv;
// rp = row_perm;
rp = 0;
// For each column vector of matrix2 ...
for (k = 0; k < 4; k++) {
// cv = &(matrix2[0][k]);
cv = k;
ii = -1;
// Forward substitution
for (i = 0; i < 4; i++) {
double sum;
ip = row_perm[rp+i];
sum = matrix2[cv+4*ip];
matrix2[cv+4*ip] = matrix2[cv+4*i];
if (ii >= 0) {
// rv = &(matrix1[i][0]);
rv = i*4;
for (j = ii; j <= i-1; j++) {
sum -= matrix1[rv+j] * matrix2[cv+4*j];
}
}
else if (sum != 0.0) {
ii = i;
}
matrix2[cv+4*i] = sum;
}
// Backsubstitution
// rv = &(matrix1[3][0]);
rv = 3*4;
matrix2[cv+4*3] /= matrix1[rv+3];
rv -= 4;
matrix2[cv+4*2] = (matrix2[cv+4*2] -
matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+2];
rv -= 4;
matrix2[cv+4*1] = (matrix2[cv+4*1] -
matrix1[rv+2] * matrix2[cv+4*2] -
matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+1];
rv -= 4;
matrix2[cv+4*0] = (matrix2[cv+4*0] -
matrix1[rv+1] * matrix2[cv+4*1] -
matrix1[rv+2] * matrix2[cv+4*2] -
matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+0];
}
}
/**
* Computes the determinate of this matrix.
* @return the determinate of the matrix
*/
public final float determinant()
{
float det;
// cofactor exapainsion along first row
det = m00*(m11*m22*m33+ m12*m23*m31 + m13*m21*m32
- m13*m22*m31 -m11*m23*m32 - m12*m21*m33);
det -= m01*(m10*m22*m33+ m12*m23*m30 + m13*m20*m32
- m13*m22*m30 -m10*m23*m32 - m12*m20*m33);
det += m02*(m10*m21*m33+ m11*m23*m30 + m13*m20*m31
- m13*m21*m30 -m10*m23*m31 - m11*m20*m33);
det -= m03*(m10*m21*m32+ m11*m22*m30 + m12*m20*m31
- m12*m21*m30 -m10*m22*m31 - m11*m20*m32);
return( det );
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix values in the single precision Matrix3f argument; the other
* elements of this matrix are initialized as if this were an identity
* matrix (i.e., affine matrix with no translational component).
* @param m1 the single-precision 3x3 matrix
*/
public final void set(Matrix3f m1)
{
m00 = m1.m00; m01 = m1.m01; m02 = m1.m02; m03 = 0.0f;
m10 = m1.m10; m11 = m1.m11; m12 = m1.m12; m13 = 0.0f;
m20 = m1.m20; m21 = m1.m21; m22 = m1.m22; m23 = 0.0f;
m30 = 0.0f; m31 = 0.0f ; m32 = 0.0f ; m33 = 1.0f;
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix values in the double precision Matrix3d argument; the other
* elements of this matrix are initialized as if this were an identity
* matrix (i.e., affine matrix with no translational component).
* @param m1 the double-precision 3x3 matrix
*/
public final void set(Matrix3d m1)
{
m00 = (float)m1.m00; m01 = (float)m1.m01; m02 = (float)m1.m02; m03 = 0.0f;
m10 = (float)m1.m10; m11 = (float)m1.m11; m12 = (float)m1.m12; m13 = 0.0f;
m20 = (float)m1.m20; m21 = (float)m1.m21; m22 = (float)m1.m22; m23 = 0.0f;
m30 = 0.0f; m31 = 0.0f ; m32 = 0.0f ; m33 = 1.0f;
}
/**
* Sets the value of this matrix to a scale matrix with the
* the passed scale amount.
* @param scale the scale factor for the matrix
*/
public final void set(float scale)
{
this.m00 = scale;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = (float) 0.0;
this.m10 = (float) 0.0;
this.m11 = scale;
this.m12 = (float) 0.0;
this.m13 = (float) 0.0;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = scale;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the values in this Matrix4f equal to the row-major
* array parameter (ie, the first four elements of the
* array will be copied into the first row of this matrix, etc.).
* @param m the single precision array of length 16
*/
public final void set(float[] m)
{
m00 = m[0];
m01 = m[1];
m02 = m[2];
m03 = m[3];
m10 = m[4];
m11 = m[5];
m12 = m[6];
m13 = m[7];
m20 = m[8];
m21 = m[9];
m22 = m[10];
m23 = m[11];
m30 = m[12];
m31 = m[13];
m32 = m[14];
m33 = m[15];
}
/**
* Sets the value of this matrix to a translate matrix with
* the passed translation value.
* @param v1 the translation amount
*/
public final void set(Vector3f v1)
{
this.m00 = (float) 1.0;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = v1.x;
this.m10 = (float) 0.0;
this.m11 = (float) 1.0;
this.m12 = (float) 0.0;
this.m13 = v1.y;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = (float) 1.0;
this.m23 = v1.z;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this transform to a scale and translation matrix;
* the scale is not applied to the translation and all of the matrix
* values are modified.
* @param scale the scale factor for the matrix
* @param t1 the translation amount
*/
public final void set(float scale, Vector3f t1)
{
this.m00 = scale;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = t1.x;
this.m10 = (float) 0.0;
this.m11 = scale;
this.m12 = (float) 0.0;
this.m13 = t1.y;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = scale;
this.m23 = t1.z;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this transform to a scale and translation matrix;
* the translation is scaled by the scale factor and all of the matrix
* values are modified.
* @param t1 the translation amount
* @param scale the scale factor for the matrix
*/
public final void set(Vector3f t1, float scale)
{
this.m00 = scale;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = scale*t1.x;
this.m10 = (float) 0.0;
this.m11 = scale;
this.m12 = (float) 0.0;
this.m13 = scale*t1.y;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = scale;
this.m23 = scale*t1.z;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix from the rotation expressed by
* the rotation matrix m1, the translation t1, and the scale factor.
* The translation is not modified by the scale.
* @param m1 the rotation component
* @param t1 the translation component
* @param scale the scale component
*/
public final void set(Matrix3f m1, Vector3f t1, float scale)
{
this.m00 = m1.m00*scale;
this.m01 = m1.m01*scale;
this.m02 = m1.m02*scale;
this.m03 = t1.x;
this.m10 = m1.m10*scale;
this.m11 = m1.m11*scale;
this.m12 = m1.m12*scale;
this.m13 = t1.y;
this.m20 = m1.m20*scale;
this.m21 = m1.m21*scale;
this.m22 = m1.m22*scale;
this.m23 = t1.z;
this.m30 = 0.0f;
this.m31 = 0.0f;
this.m32 = 0.0f;
this.m33 = 1.0f;
}
/**
* Sets the value of this matrix from the rotation expressed by
* the rotation matrix m1, the translation t1, and the scale factor.
* The translation is not modified by the scale.
* @param m1 the rotation component
* @param t1 the translation component
* @param scale the scale factor
*/
public final void set(Matrix3d m1, Vector3d t1, double scale)
{
this.m00 = (float)(m1.m00*scale);
this.m01 = (float)(m1.m01*scale);
this.m02 = (float)(m1.m02*scale);
this.m03 = (float)t1.x;
this.m10 = (float)(m1.m10*scale);
this.m11 = (float)(m1.m11*scale);
this.m12 = (float)(m1.m12*scale);
this.m13 = (float)t1.y;
this.m20 = (float)(m1.m20*scale);
this.m21 = (float)(m1.m21*scale);
this.m22 = (float)(m1.m22*scale);
this.m23 = (float)t1.z;
this.m30 = 0.0f;
this.m31 = 0.0f;
this.m32 = 0.0f;
this.m33 = 1.0f;
}
/**
* Modifies the translational components of this matrix to the values
* of the Vector3f argument; the other values of this matrix are not
* modified.
* @param trans the translational component
*/
public final void setTranslation(Vector3f trans)
{
m03 = trans.x;
m13 = trans.y;
m23 = trans.z;
}
/**
* Sets the value of this matrix to a counter clockwise rotation
* about the x axis.
* @param angle the angle to rotate about the X axis in radians
*/
public final void rotX(float angle)
{
float sinAngle, cosAngle;
sinAngle = (float) Math.sin((double) angle);
cosAngle = (float) Math.cos((double) angle);
this.m00 = (float) 1.0;
this.m01 = (float) 0.0;
this.m02 = (float) 0.0;
this.m03 = (float) 0.0;
this.m10 = (float) 0.0;
this.m11 = cosAngle;
this.m12 = -sinAngle;
this.m13 = (float) 0.0;
this.m20 = (float) 0.0;
this.m21 = sinAngle;
this.m22 = cosAngle;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix to a counter clockwise rotation
* about the y axis.
* @param angle the angle to rotate about the Y axis in radians
*/
public final void rotY(float angle)
{
float sinAngle, cosAngle;
sinAngle = (float) Math.sin((double) angle);
cosAngle = (float) Math.cos((double) angle);
this.m00 = cosAngle;
this.m01 = (float) 0.0;
this.m02 = sinAngle;
this.m03 = (float) 0.0;
this.m10 = (float) 0.0;
this.m11 = (float) 1.0;
this.m12 = (float) 0.0;
this.m13 = (float) 0.0;
this.m20 = -sinAngle;
this.m21 = (float) 0.0;
this.m22 = cosAngle;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Sets the value of this matrix to a counter clockwise rotation
* about the z axis.
* @param angle the angle to rotate about the Z axis in radians
*/
public final void rotZ(float angle)
{
float sinAngle, cosAngle;
sinAngle = (float) Math.sin((double) angle);
cosAngle = (float) Math.cos((double) angle);
this.m00 = cosAngle;
this.m01 = -sinAngle;
this.m02 = (float) 0.0;
this.m03 = (float) 0.0;
this.m10 = sinAngle;
this.m11 = cosAngle;
this.m12 = (float) 0.0;
this.m13 = (float) 0.0;
this.m20 = (float) 0.0;
this.m21 = (float) 0.0;
this.m22 = (float) 1.0;
this.m23 = (float) 0.0;
this.m30 = (float) 0.0;
this.m31 = (float) 0.0;
this.m32 = (float) 0.0;
this.m33 = (float) 1.0;
}
/**
* Multiplies each element of this matrix by a scalar.
* @param scalar the scalar multiplier.
*/
public final void mul(float scalar)
{
m00 *= scalar;
m01 *= scalar;
m02 *= scalar;
m03 *= scalar;
m10 *= scalar;
m11 *= scalar;
m12 *= scalar;
m13 *= scalar;
m20 *= scalar;
m21 *= scalar;
m22 *= scalar;
m23 *= scalar;
m30 *= scalar;
m31 *= scalar;
m32 *= scalar;
m33 *= scalar;
}
/**
* Multiplies each element of matrix m1 by a scalar and places
* the result into this. Matrix m1 is not modified.
* @param scalar the scalar multiplier.
* @param m1 the original matrix.
*/
public final void mul(float scalar, Matrix4f m1)
{
this.m00 = m1.m00 * scalar;
this.m01 = m1.m01 * scalar;
this.m02 = m1.m02 * scalar;
this.m03 = m1.m03 * scalar;
this.m10 = m1.m10 * scalar;
this.m11 = m1.m11 * scalar;
this.m12 = m1.m12 * scalar;
this.m13 = m1.m13 * scalar;
this.m20 = m1.m20 * scalar;
this.m21 = m1.m21 * scalar;
this.m22 = m1.m22 * scalar;
this.m23 = m1.m23 * scalar;
this.m30 = m1.m30 * scalar;
this.m31 = m1.m31 * scalar;
this.m32 = m1.m32 * scalar;
this.m33 = m1.m33 * scalar;
}
/**
* Sets the value of this matrix to the result of multiplying itself
* with matrix m1.
* @param m1 the other matrix
*/
public final void mul(Matrix4f m1)
{
float m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33; // vars for temp result matrix
m00 = this.m00*m1.m00 + this.m01*m1.m10 +
this.m02*m1.m20 + this.m03*m1.m30;
m01 = this.m00*m1.m01 + this.m01*m1.m11 +
this.m02*m1.m21 + this.m03*m1.m31;
m02 = this.m00*m1.m02 + this.m01*m1.m12 +
this.m02*m1.m22 + this.m03*m1.m32;
m03 = this.m00*m1.m03 + this.m01*m1.m13 +
this.m02*m1.m23 + this.m03*m1.m33;
m10 = this.m10*m1.m00 + this.m11*m1.m10 +
this.m12*m1.m20 + this.m13*m1.m30;
m11 = this.m10*m1.m01 + this.m11*m1.m11 +
this.m12*m1.m21 + this.m13*m1.m31;
m12 = this.m10*m1.m02 + this.m11*m1.m12 +
this.m12*m1.m22 + this.m13*m1.m32;
m13 = this.m10*m1.m03 + this.m11*m1.m13 +
this.m12*m1.m23 + this.m13*m1.m33;
m20 = this.m20*m1.m00 + this.m21*m1.m10 +
this.m22*m1.m20 + this.m23*m1.m30;
m21 = this.m20*m1.m01 + this.m21*m1.m11 +
this.m22*m1.m21 + this.m23*m1.m31;
m22 = this.m20*m1.m02 + this.m21*m1.m12 +
this.m22*m1.m22 + this.m23*m1.m32;
m23 = this.m20*m1.m03 + this.m21*m1.m13 +
this.m22*m1.m23 + this.m23*m1.m33;
m30 = this.m30*m1.m00 + this.m31*m1.m10 +
this.m32*m1.m20 + this.m33*m1.m30;
m31 = this.m30*m1.m01 + this.m31*m1.m11 +
this.m32*m1.m21 + this.m33*m1.m31;
m32 = this.m30*m1.m02 + this.m31*m1.m12 +
this.m32*m1.m22 + this.m33*m1.m32;
m33 = this.m30*m1.m03 + this.m31*m1.m13 +
this.m32*m1.m23 + this.m33*m1.m33;
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
/**
* Sets the value of this matrix to the result of multiplying
* the two argument matrices together.
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void mul(Matrix4f m1, Matrix4f m2)
{
if (this != m1 && this != m2) {
this.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 +
m1.m02*m2.m20 + m1.m03*m2.m30;
this.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 +
m1.m02*m2.m21 + m1.m03*m2.m31;
this.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 +
m1.m02*m2.m22 + m1.m03*m2.m32;
this.m03 = m1.m00*m2.m03 + m1.m01*m2.m13 +
m1.m02*m2.m23 + m1.m03*m2.m33;
this.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 +
m1.m12*m2.m20 + m1.m13*m2.m30;
this.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 +
m1.m12*m2.m21 + m1.m13*m2.m31;
this.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 +
m1.m12*m2.m22 + m1.m13*m2.m32;
this.m13 = m1.m10*m2.m03 + m1.m11*m2.m13 +
m1.m12*m2.m23 + m1.m13*m2.m33;
this.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 +
m1.m22*m2.m20 + m1.m23*m2.m30;
this.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 +
m1.m22*m2.m21 + m1.m23*m2.m31;
this.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 +
m1.m22*m2.m22 + m1.m23*m2.m32;
this.m23 = m1.m20*m2.m03 + m1.m21*m2.m13 +
m1.m22*m2.m23 + m1.m23*m2.m33;
this.m30 = m1.m30*m2.m00 + m1.m31*m2.m10 +
m1.m32*m2.m20 + m1.m33*m2.m30;
this.m31 = m1.m30*m2.m01 + m1.m31*m2.m11 +
m1.m32*m2.m21 + m1.m33*m2.m31;
this.m32 = m1.m30*m2.m02 + m1.m31*m2.m12 +
m1.m32*m2.m22 + m1.m33*m2.m32;
this.m33 = m1.m30*m2.m03 + m1.m31*m2.m13 +
m1.m32*m2.m23 + m1.m33*m2.m33;
} else {
float m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33; // vars for temp result matrix
m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20 + m1.m03*m2.m30;
m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21 + m1.m03*m2.m31;
m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22 + m1.m03*m2.m32;
m03 = m1.m00*m2.m03 + m1.m01*m2.m13 + m1.m02*m2.m23 + m1.m03*m2.m33;
m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20 + m1.m13*m2.m30;
m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21 + m1.m13*m2.m31;
m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22 + m1.m13*m2.m32;
m13 = m1.m10*m2.m03 + m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13*m2.m33;
m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20 + m1.m23*m2.m30;
m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21 + m1.m23*m2.m31;
m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22 + m1.m23*m2.m32;
m23 = m1.m20*m2.m03 + m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23*m2.m33;
m30 = m1.m30*m2.m00 + m1.m31*m2.m10 + m1.m32*m2.m20 + m1.m33*m2.m30;
m31 = m1.m30*m2.m01 + m1.m31*m2.m11 + m1.m32*m2.m21 + m1.m33*m2.m31;
m32 = m1.m30*m2.m02 + m1.m31*m2.m12 + m1.m32*m2.m22 + m1.m33*m2.m32;
m33 = m1.m30*m2.m03 + m1.m31*m2.m13 + m1.m32*m2.m23 + m1.m33*m2.m33;
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
}
/**
* Multiplies the transpose of matrix m1 times the transpose of matrix
* m2, and places the result into this.
* @param m1 the matrix on the left hand side of the multiplication
* @param m2 the matrix on the right hand side of the multiplication
*/
public final void mulTransposeBoth(Matrix4f m1, Matrix4f m2)
{
if (this != m1 && this != m2) {
this.m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02 + m1.m30*m2.m03;
this.m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12 + m1.m30*m2.m13;
this.m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22 + m1.m30*m2.m23;
this.m03 = m1.m00*m2.m30 + m1.m10*m2.m31 + m1.m20*m2.m32 + m1.m30*m2.m33;
this.m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02 + m1.m31*m2.m03;
this.m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12 + m1.m31*m2.m13;
this.m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22 + m1.m31*m2.m23;
this.m13 = m1.m01*m2.m30 + m1.m11*m2.m31 + m1.m21*m2.m32 + m1.m31*m2.m33;
this.m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02 + m1.m32*m2.m03;
this.m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12 + m1.m32*m2.m13;
this.m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22 + m1.m32*m2.m23;
this.m23 = m1.m02*m2.m30 + m1.m12*m2.m31 + m1.m22*m2.m32 + m1.m32*m2.m33;
this.m30 = m1.m03*m2.m00 + m1.m13*m2.m01 + m1.m23*m2.m02 + m1.m33*m2.m03;
this.m31 = m1.m03*m2.m10 + m1.m13*m2.m11 + m1.m23*m2.m12 + m1.m33*m2.m13;
this.m32 = m1.m03*m2.m20 + m1.m13*m2.m21 + m1.m23*m2.m22 + m1.m33*m2.m23;
this.m33 = m1.m03*m2.m30 + m1.m13*m2.m31 + m1.m23*m2.m32 + m1.m33*m2.m33;
} else {
float m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23, // vars for temp result matrix
m30, m31, m32, m33;
m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02 + m1.m30*m2.m03;
m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12 + m1.m30*m2.m13;
m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22 + m1.m30*m2.m23;
m03 = m1.m00*m2.m30 + m1.m10*m2.m31 + m1.m20*m2.m32 + m1.m30*m2.m33;
m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02 + m1.m31*m2.m03;
m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12 + m1.m31*m2.m13;
m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22 + m1.m31*m2.m23;
m13 = m1.m01*m2.m30 + m1.m11*m2.m31 + m1.m21*m2.m32 + m1.m31*m2.m33;
m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02 + m1.m32*m2.m03;
m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12 + m1.m32*m2.m13;
m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22 + m1.m32*m2.m23;
m23 = m1.m02*m2.m30 + m1.m12*m2.m31 + m1.m22*m2.m32 + m1.m32*m2.m33;
m30 = m1.m03*m2.m00 + m1.m13*m2.m01 + m1.m23*m2.m02 + m1.m33*m2.m03;
m31 = m1.m03*m2.m10 + m1.m13*m2.m11 + m1.m23*m2.m12 + m1.m33*m2.m13;
m32 = m1.m03*m2.m20 + m1.m13*m2.m21 + m1.m23*m2.m22 + m1.m33*m2.m23;
m33 = m1.m03*m2.m30 + m1.m13*m2.m31 + m1.m23*m2.m32 + m1.m33*m2.m33;
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
}
/**
* Multiplies matrix m1 times the transpose of matrix m2, and
* places the result into this.
* @param m1 the matrix on the left hand side of the multiplication
* @param m2 the matrix on the right hand side of the multiplication
*/
public final void mulTransposeRight(Matrix4f m1, Matrix4f m2)
{
if (this != m1 && this != m2) {
this.m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02 + m1.m03*m2.m03;
this.m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12 + m1.m03*m2.m13;
this.m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22 + m1.m03*m2.m23;
this.m03 = m1.m00*m2.m30 + m1.m01*m2.m31 + m1.m02*m2.m32 + m1.m03*m2.m33;
this.m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02 + m1.m13*m2.m03;
this.m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12 + m1.m13*m2.m13;
this.m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22 + m1.m13*m2.m23;
this.m13 = m1.m10*m2.m30 + m1.m11*m2.m31 + m1.m12*m2.m32 + m1.m13*m2.m33;
this.m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02 + m1.m23*m2.m03;
this.m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12 + m1.m23*m2.m13;
this.m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22 + m1.m23*m2.m23;
this.m23 = m1.m20*m2.m30 + m1.m21*m2.m31 + m1.m22*m2.m32 + m1.m23*m2.m33;
this.m30 = m1.m30*m2.m00 + m1.m31*m2.m01 + m1.m32*m2.m02 + m1.m33*m2.m03;
this.m31 = m1.m30*m2.m10 + m1.m31*m2.m11 + m1.m32*m2.m12 + m1.m33*m2.m13;
this.m32 = m1.m30*m2.m20 + m1.m31*m2.m21 + m1.m32*m2.m22 + m1.m33*m2.m23;
this.m33 = m1.m30*m2.m30 + m1.m31*m2.m31 + m1.m32*m2.m32 + m1.m33*m2.m33;
} else {
float m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23, // vars for temp result matrix
m30, m31, m32, m33;
m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02 + m1.m03*m2.m03;
m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12 + m1.m03*m2.m13;
m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22 + m1.m03*m2.m23;
m03 = m1.m00*m2.m30 + m1.m01*m2.m31 + m1.m02*m2.m32 + m1.m03*m2.m33;
m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02 + m1.m13*m2.m03;
m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12 + m1.m13*m2.m13;
m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22 + m1.m13*m2.m23;
m13 = m1.m10*m2.m30 + m1.m11*m2.m31 + m1.m12*m2.m32 + m1.m13*m2.m33;
m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02 + m1.m23*m2.m03;
m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12 + m1.m23*m2.m13;
m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22 + m1.m23*m2.m23;
m23 = m1.m20*m2.m30 + m1.m21*m2.m31 + m1.m22*m2.m32 + m1.m23*m2.m33;
m30 = m1.m30*m2.m00 + m1.m31*m2.m01 + m1.m32*m2.m02 + m1.m33*m2.m03;
m31 = m1.m30*m2.m10 + m1.m31*m2.m11 + m1.m32*m2.m12 + m1.m33*m2.m13;
m32 = m1.m30*m2.m20 + m1.m31*m2.m21 + m1.m32*m2.m22 + m1.m33*m2.m23;
m33 = m1.m30*m2.m30 + m1.m31*m2.m31 + m1.m32*m2.m32 + m1.m33*m2.m33;
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
}
/**
* Multiplies the transpose of matrix m1 times matrix m2, and
* places the result into this.
* @param m1 the matrix on the left hand side of the multiplication
* @param m2 the matrix on the right hand side of the multiplication
*/
public final void mulTransposeLeft(Matrix4f m1, Matrix4f m2)
{
if (this != m1 && this != m2) {
this.m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20 + m1.m30*m2.m30;
this.m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21 + m1.m30*m2.m31;
this.m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22 + m1.m30*m2.m32;
this.m03 = m1.m00*m2.m03 + m1.m10*m2.m13 + m1.m20*m2.m23 + m1.m30*m2.m33;
this.m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20 + m1.m31*m2.m30;
this.m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21 + m1.m31*m2.m31;
this.m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22 + m1.m31*m2.m32;
this.m13 = m1.m01*m2.m03 + m1.m11*m2.m13 + m1.m21*m2.m23 + m1.m31*m2.m33;
this.m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20 + m1.m32*m2.m30;
this.m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21 + m1.m32*m2.m31;
this.m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22 + m1.m32*m2.m32;
this.m23 = m1.m02*m2.m03 + m1.m12*m2.m13 + m1.m22*m2.m23 + m1.m32*m2.m33;
this.m30 = m1.m03*m2.m00 + m1.m13*m2.m10 + m1.m23*m2.m20 + m1.m33*m2.m30;
this.m31 = m1.m03*m2.m01 + m1.m13*m2.m11 + m1.m23*m2.m21 + m1.m33*m2.m31;
this.m32 = m1.m03*m2.m02 + m1.m13*m2.m12 + m1.m23*m2.m22 + m1.m33*m2.m32;
this.m33 = m1.m03*m2.m03 + m1.m13*m2.m13 + m1.m23*m2.m23 + m1.m33*m2.m33;
} else {
float m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23, // vars for temp result matrix
m30, m31, m32, m33;
m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20 + m1.m30*m2.m30;
m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21 + m1.m30*m2.m31;
m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22 + m1.m30*m2.m32;
m03 = m1.m00*m2.m03 + m1.m10*m2.m13 + m1.m20*m2.m23 + m1.m30*m2.m33;
m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20 + m1.m31*m2.m30;
m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21 + m1.m31*m2.m31;
m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22 + m1.m31*m2.m32;
m13 = m1.m01*m2.m03 + m1.m11*m2.m13 + m1.m21*m2.m23 + m1.m31*m2.m33;
m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20 + m1.m32*m2.m30;
m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21 + m1.m32*m2.m31;
m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22 + m1.m32*m2.m32;
m23 = m1.m02*m2.m03 + m1.m12*m2.m13 + m1.m22*m2.m23 + m1.m32*m2.m33;
m30 = m1.m03*m2.m00 + m1.m13*m2.m10 + m1.m23*m2.m20 + m1.m33*m2.m30;
m31 = m1.m03*m2.m01 + m1.m13*m2.m11 + m1.m23*m2.m21 + m1.m33*m2.m31;
m32 = m1.m03*m2.m02 + m1.m13*m2.m12 + m1.m23*m2.m22 + m1.m33*m2.m32;
m33 = m1.m03*m2.m03 + m1.m13*m2.m13 + m1.m23*m2.m23 + m1.m33*m2.m33;
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
}
/**
* Returns true if all of the data members of Matrix4f m1 are
* equal to the corresponding data members in this Matrix4f.
* @param m1 the matrix with which the comparison is made.
* @return true or false
*/
public boolean equals(Matrix4f m1)
{
try {
return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
&& this.m03 == m1.m03 && this.m10 == m1.m10 && this.m11 == m1.m11
&& this.m12 == m1.m12 && this.m13 == m1.m13 && this.m20 == m1.m20
&& this.m21 == m1.m21 && this.m22 == m1.m22 && this.m23 == m1.m23
&& this.m30 == m1.m30 && this.m31 == m1.m31 && this.m32 == m1.m32
&& this.m33 == m1.m33);
}
catch (NullPointerException e2) { return false; }
}
/**
* Returns true if the Object t1 is of type Matrix4f and all of the
* data members of t1 are equal to the corresponding data members in
* this Matrix4f.
* @param t1 the matrix with which the comparison is made.
* @return true or false
*/
public boolean equals(Object t1)
{
try {
Matrix4f m2 = (Matrix4f) t1;
return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
&& this.m03 == m2.m03 && this.m10 == m2.m10 && this.m11 == m2.m11
&& this.m12 == m2.m12 && this.m13 == m2.m13 && this.m20 == m2.m20
&& this.m21 == m2.m21 && this.m22 == m2.m22 && this.m23 == m2.m23
&& this.m30 == m2.m30 && this.m31 == m2.m31 && this.m32 == m2.m32
&& this.m33 == m2.m33);
}
catch (ClassCastException e1) { return false; }
catch (NullPointerException e2) { return false; }
}
/**
* Returns true if the L-infinite distance between this matrix
* and matrix m1 is less than or equal to the epsilon parameter,
* otherwise returns false. The L-infinite
* distance is equal to
* MAX[i=0,1,2,3 ; j=0,1,2,3 ; abs(this.m(i,j) - m1.m(i,j)]
* @param m1 the matrix to be compared to this matrix
* @param epsilon the threshold value
*/
public boolean epsilonEquals(Matrix4f m1, float epsilon)
{
boolean status = true;
if( Math.abs( this.m00 - m1.m00) > epsilon) status = false;
if( Math.abs( this.m01 - m1.m01) > epsilon) status = false;
if( Math.abs( this.m02 - m1.m02) > epsilon) status = false;
if( Math.abs( this.m03 - m1.m03) > epsilon) status = false;
if( Math.abs( this.m10 - m1.m10) > epsilon) status = false;
if( Math.abs( this.m11 - m1.m11) > epsilon) status = false;
if( Math.abs( this.m12 - m1.m12) > epsilon) status = false;
if( Math.abs( this.m13 - m1.m13) > epsilon) status = false;
if( Math.abs( this.m20 - m1.m20) > epsilon) status = false;
if( Math.abs( this.m21 - m1.m21) > epsilon) status = false;
if( Math.abs( this.m22 - m1.m22) > epsilon) status = false;
if( Math.abs( this.m23 - m1.m23) > epsilon) status = false;
if( Math.abs( this.m30 - m1.m30) > epsilon) status = false;
if( Math.abs( this.m31 - m1.m31) > epsilon) status = false;
if( Math.abs( this.m32 - m1.m32) > epsilon) status = false;
if( Math.abs( this.m33 - m1.m33) > epsilon) status = false;
return( status );
}
/**
* Returns a hash code value based on the data values in this
* object. Two different Matrix4f objects with identical data values
* (i.e., Matrix4f.equals returns true) will return the same hash
* code value. Two objects with different data members may return the
* same hash value, although this is not likely.
* @return the integer hash code value
*/
public int hashCode() {
long bits = 1L;
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m00);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m01);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m02);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m03);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m10);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m11);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m12);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m13);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m20);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m21);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m22);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m23);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m30);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m31);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m32);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m33);
return (int) (bits ^ (bits >> 32));
}
/**
* Transform the vector vec using this Matrix4f and place the
* result into vecOut.
* @param vec the single precision vector to be transformed
* @param vecOut the vector into which the transformed values are placed
*/
public final void transform(Tuple4f vec, Tuple4f vecOut)
{
float x,y,z;
x = m00*vec.x + m01*vec.y
+ m02*vec.z + m03*vec.w;
y = m10*vec.x + m11*vec.y
+ m12*vec.z + m13*vec.w;
z = m20*vec.x + m21*vec.y
+ m22*vec.z + m23*vec.w;
vecOut.w = m30*vec.x + m31*vec.y
+ m32*vec.z + m33*vec.w;
vecOut.x = x;
vecOut.y = y;
vecOut.z = z;
}
/**
* Transform the vector vec using this Transform and place the
* result back into vec.
* @param vec the single precision vector to be transformed
*/
public final void transform(Tuple4f vec)
{
float x,y,z;
x = m00*vec.x + m01*vec.y
+ m02*vec.z + m03*vec.w;
y = m10*vec.x + m11*vec.y
+ m12*vec.z + m13*vec.w;
z = m20*vec.x + m21*vec.y
+ m22*vec.z + m23*vec.w;
vec.w = m30*vec.x + m31*vec.y
+ m32*vec.z + m33*vec.w;
vec.x = x;
vec.y = y;
vec.z = z;
}
/**
* Transforms the point parameter with this Matrix4f and
* places the result into pointOut. The fourth element of the
* point input paramter is assumed to be one.
* @param point the input point to be transformed.
* @param pointOut the transformed point
*/
public final void transform(Point3f point, Point3f pointOut)
{
float x,y;
x = m00*point.x + m01*point.y + m02*point.z + m03;
y = m10*point.x + m11*point.y + m12*point.z + m13;
pointOut.z = m20*point.x + m21*point.y + m22*point.z + m23;
pointOut.x = x;
pointOut.y = y;
}
/**
* Transforms the point parameter with this Matrix4f and
* places the result back into point. The fourth element of the
* point input paramter is assumed to be one.
* @param point the input point to be transformed.
*/
public final void transform(Point3f point)
{
float x, y;
x = m00*point.x + m01*point.y + m02*point.z + m03;
y = m10*point.x + m11*point.y + m12*point.z + m13;
point.z = m20*point.x + m21*point.y + m22*point.z + m23;
point.x = x;
point.y = y;
}
/**
* Transforms the normal parameter by this Matrix4f and places the value
* into normalOut. The fourth element of the normal is assumed to be zero.
* @param normal the input normal to be transformed.
* @param normalOut the transformed normal
*/
public final void transform(Vector3f normal, Vector3f normalOut)
{
float x,y;
x = m00*normal.x + m01*normal.y + m02*normal.z;
y = m10*normal.x + m11*normal.y + m12*normal.z;
normalOut.z = m20*normal.x + m21*normal.y + m22*normal.z;
normalOut.x = x;
normalOut.y = y;
}
/**
* Transforms the normal parameter by this transform and places the value
* back into normal. The fourth element of the normal is assumed to be zero.
* @param normal the input normal to be transformed.
*/
public final void transform(Vector3f normal)
{
float x, y;
x = m00*normal.x + m01*normal.y + m02*normal.z;
y = m10*normal.x + m11*normal.y + m12*normal.z;
normal.z = m20*normal.x + m21*normal.y + m22*normal.z;
normal.x = x;
normal.y = y;
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix values in the double precision Matrix3d argument; the other
* elements of this matrix are unchanged; a singular value
* decomposition is performed on this object's upper 3x3 matrix to
* factor out the scale, then this object's upper 3x3 matrix components
* are replaced by the passed rotation components,
* and then the scale is reapplied to the rotational components.
* @param m1 double precision 3x3 matrix
*/
public final void setRotation( Matrix3d m1)
{
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m00 = (float)(m1.m00*tmp_scale[0]);
m01 = (float)(m1.m01*tmp_scale[1]);
m02 = (float)(m1.m02*tmp_scale[2]);
m10 = (float)(m1.m10*tmp_scale[0]);
m11 = (float)(m1.m11*tmp_scale[1]);
m12 = (float)(m1.m12*tmp_scale[2]);
m20 = (float)(m1.m20*tmp_scale[0]);
m21 = (float)(m1.m21*tmp_scale[1]);
m22 = (float)(m1.m22*tmp_scale[2]);
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix values in the single precision Matrix3f argument; the other
* elements of this matrix are unchanged; a singular value
* decomposition is performed on this object's upper 3x3 matrix to
* factor out the scale, then this object's upper 3x3 matrix components
* are replaced by the passed rotation components,
* and then the scale is reapplied to the rotational components.
* @param m1 single precision 3x3 matrix
*/
public final void setRotation( Matrix3f m1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m00 = (float)(m1.m00*tmp_scale[0]);
m01 = (float)(m1.m01*tmp_scale[1]);
m02 = (float)(m1.m02*tmp_scale[2]);
m10 = (float)(m1.m10*tmp_scale[0]);
m11 = (float)(m1.m11*tmp_scale[1]);
m12 = (float)(m1.m12*tmp_scale[2]);
m20 = (float)(m1.m20*tmp_scale[0]);
m21 = (float)(m1.m21*tmp_scale[1]);
m22 = (float)(m1.m22*tmp_scale[2]);
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix equivalent values of the quaternion argument; the other
* elements of this matrix are unchanged; a singular value
* decomposition is performed on this object's upper 3x3 matrix to
* factor out the scale, then this object's upper 3x3 matrix components
* are replaced by the matrix equivalent of the quaternion,
* and then the scale is reapplied to the rotational components.
* @param q1 the quaternion that specifies the rotation
*/
public final void setRotation(Quat4f q1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m00 = (float)((1.0f - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z)*tmp_scale[0]);
m10 = (float)((2.0f*(q1.x*q1.y + q1.w*q1.z))*tmp_scale[0]);
m20 = (float)((2.0f*(q1.x*q1.z - q1.w*q1.y))*tmp_scale[0]);
m01 = (float)((2.0f*(q1.x*q1.y - q1.w*q1.z))*tmp_scale[1]);
m11 = (float)((1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z)*tmp_scale[1]);
m21 = (float)((2.0f*(q1.y*q1.z + q1.w*q1.x))*tmp_scale[1]);
m02 = (float)((2.0f*(q1.x*q1.z + q1.w*q1.y))*tmp_scale[2]);
m12 = (float)((2.0f*(q1.y*q1.z - q1.w*q1.x))*tmp_scale[2]);
m22 = (float)((1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y)*tmp_scale[2]);
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix equivalent values of the quaternion argument; the other
* elements of this matrix are unchanged; a singular value
* decomposition is performed on this object's upper 3x3 matrix to
* factor out the scale, then this object's upper 3x3 matrix components
* are replaced by the matrix equivalent of the quaternion,
* and then the scale is reapplied to the rotational components.
* @param q1 the quaternion that specifies the rotation
*/
public final void setRotation(Quat4d q1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
m00 = (float)((1.0f - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z)*tmp_scale[0]);
m10 = (float)((2.0f*(q1.x*q1.y + q1.w*q1.z))*tmp_scale[0]);
m20 = (float)((2.0f*(q1.x*q1.z - q1.w*q1.y))*tmp_scale[0]);
m01 = (float)((2.0f*(q1.x*q1.y - q1.w*q1.z))*tmp_scale[1]);
m11 = (float)((1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z)*tmp_scale[1]);
m21 = (float)((2.0f*(q1.y*q1.z + q1.w*q1.x))*tmp_scale[1]);
m02 = (float)((2.0f*(q1.x*q1.z + q1.w*q1.y))*tmp_scale[2]);
m12 = (float)((2.0f*(q1.y*q1.z - q1.w*q1.x))*tmp_scale[2]);
m22 = (float)((1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y)*tmp_scale[2]);
}
/**
* Sets the rotational component (upper 3x3) of this matrix to the
* matrix equivalent values of the axis-angle argument; the other
* elements of this matrix are unchanged; a singular value
* decomposition is performed on this object's upper 3x3 matrix to
* factor out the scale, then this object's upper 3x3 matrix components
* are replaced by the matrix equivalent of the axis-angle,
* and then the scale is reapplied to the rotational components.
* @param a1 the axis-angle to be converted (x, y, z, angle)
*/
public final void setRotation(AxisAngle4f a1){
double[] tmp_rot = new double[9]; // scratch matrix
double[] tmp_scale = new double[3]; // scratch matrix
getScaleRotate( tmp_scale, tmp_rot );
double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
if( mag < EPS ) {
m00 = 1.0f;
m01 = 0.0f;
m02 = 0.0f;
m10 = 0.0f;
m11 = 1.0f;
m12 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 1.0f;
} else {
mag = 1.0/mag;
double ax = a1.x*mag;
double ay = a1.y*mag;
double az = a1.z*mag;
double sinTheta = Math.sin(a1.angle);
double cosTheta = Math.cos(a1.angle);
double t = 1.0 - cosTheta;
double xz = a1.x * a1.z;
double xy = a1.x * a1.y;
double yz = a1.y * a1.z;
m00 = (float)((t * ax * ax + cosTheta)*tmp_scale[0]);
m01 = (float)((t * xy - sinTheta * az)*tmp_scale[1]);
m02 = (float)((t * xz + sinTheta * ay)*tmp_scale[2]);
m10 = (float)((t * xy + sinTheta * az)*tmp_scale[0]);
m11 = (float)((t * ay * ay + cosTheta)*tmp_scale[1]);
m12 = (float)((t * yz - sinTheta * ax)*tmp_scale[2]);
m20 = (float)((t * xz - sinTheta * ay)*tmp_scale[0]);
m21 = (float)((t * yz + sinTheta * ax)*tmp_scale[1]);
m22 = (float)((t * az * az + cosTheta)*tmp_scale[2]);
}
}
/**
* Sets this matrix to all zeros.
*/
public final void setZero()
{
m00 = 0.0f;
m01 = 0.0f;
m02 = 0.0f;
m03 = 0.0f;
m10 = 0.0f;
m11 = 0.0f;
m12 = 0.0f;
m13 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 0.0f;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 0.0f;
}
/**
* Negates the value of this matrix: this = -this.
*/
public final void negate()
{
m00 = -m00;
m01 = -m01;
m02 = -m02;
m03 = -m03;
m10 = -m10;
m11 = -m11;
m12 = -m12;
m13 = -m13;
m20 = -m20;
m21 = -m21;
m22 = -m22;
m23 = -m23;
m30 = -m30;
m31 = -m31;
m32 = -m32;
m33 = -m33;
}
/**
* Sets the value of this matrix equal to the negation of
* of the Matrix4f parameter.
* @param m1 the source matrix
*/
public final void negate(Matrix4f m1)
{
this.m00 = -m1.m00;
this.m01 = -m1.m01;
this.m02 = -m1.m02;
this.m03 = -m1.m03;
this.m10 = -m1.m10;
this.m11 = -m1.m11;
this.m12 = -m1.m12;
this.m13 = -m1.m13;
this.m20 = -m1.m20;
this.m21 = -m1.m21;
this.m22 = -m1.m22;
this.m23 = -m1.m23;
this.m30 = -m1.m30;
this.m31 = -m1.m31;
this.m32 = -m1.m32;
this.m33 = -m1.m33;
}
private final void getScaleRotate(double scales[], double rots[]) {
double[] tmp = new double[9]; // scratch matrix
tmp[0] = m00;
tmp[1] = m01;
tmp[2] = m02;
tmp[3] = m10;
tmp[4] = m11;
tmp[5] = m12;
tmp[6] = m20;
tmp[7] = m21;
tmp[8] = m22;
Matrix3d.compute_svd( tmp, scales, rots);
return;
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError if there is not enough memory.
* @see java.lang.Cloneable
* @since vecmath 1.3
*/
public Object clone() {
Matrix4f m1 = null;
try {
m1 = (Matrix4f)super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
return m1;
}
/**
* Get the first matrix element in the first row.
*
* @return Returns the m00.
*
* @since vecmath 1.5
*/
public final float getM00() {
return m00;
}
/**
* Set the first matrix element in the first row.
*
* @param m00 The m00 to set.
*
* @since vecmath 1.5
*/
public final void setM00(float m00) {
this.m00 = m00;
}
/**
* Get the second matrix element in the first row.
*
* @return Returns the m01.
*
* @since vecmath 1.5
*/
public final float getM01() {
return m01;
}
/**
* Set the second matrix element in the first row.
*
* @param m01 The m01 to set.
*
* @since vecmath 1.5
*/
public final void setM01(float m01) {
this.m01 = m01;
}
/**
* Get the third matrix element in the first row.
*
* @return Returns the m02.
*
* @since vecmath 1.5
*/
public final float getM02() {
return m02;
}
/**
* Set the third matrix element in the first row.
*
* @param m02 The m02 to set.
*
* @since vecmath 1.5
*/
public final void setM02(float m02) {
this.m02 = m02;
}
/**
* Get first matrix element in the second row.
*
* @return Returns the m10.
*
* @since vecmath 1.5
*/
public final float getM10() {
return m10;
}
/**
* Set first matrix element in the second row.
*
* @param m10 The m10 to set.
*
* @since vecmath 1.5
*/
public final void setM10(float m10) {
this.m10 = m10;
}
/**
* Get second matrix element in the second row.
*
* @return Returns the m11.
*
* @since vecmath 1.5
*/
public final float getM11() {
return m11;
}
/**
* Set the second matrix element in the second row.
*
* @param m11 The m11 to set.
*
* @since vecmath 1.5
*/
public final void setM11(float m11) {
this.m11 = m11;
}
/**
* Get the third matrix element in the second row.
*
* @return Returns the m12.
*
* @since vecmath 1.5
*/
public final float getM12() {
return m12;
}
/**
* Set the third matrix element in the second row.
*
* @param m12 The m12 to set.
*
* @since vecmath 1.5
*/
public final void setM12(float m12) {
this.m12 = m12;
}
/**
* Get the first matrix element in the third row.
*
* @return Returns the m20.
*
* @since vecmath 1.5
*/
public final float getM20() {
return m20;
}
/**
* Set the first matrix element in the third row.
*
* @param m20 The m20 to set.
*
* @since vecmath 1.5
*/
public final void setM20(float m20) {
this.m20 = m20;
}
/**
* Get the second matrix element in the third row.
*
* @return Returns the m21.
*
* @since vecmath 1.5
*/
public final float getM21() {
return m21;
}
/**
* Set the second matrix element in the third row.
*
* @param m21 The m21 to set.
*
* @since vecmath 1.5
*/
public final void setM21(float m21) {
this.m21 = m21;
}
/**
* Get the third matrix element in the third row.
*
* @return Returns the m22.
*
* @since vecmath 1.5
*/
public final float getM22() {
return m22;
}
/**
* Set the third matrix element in the third row.
*
* @param m22 The m22 to set.
*
* @since vecmath 1.5
*/
public final void setM22(float m22) {
this.m22 = m22;
}
/**
* Get the fourth element of the first row.
*
* @return Returns the m03.
*
* @since vecmath 1.5
*/
public final float getM03() {
return m03;
}
/**
* Set the fourth element of the first row.
*
* @param m03 The m03 to set.
*
* @since vecmath 1.5
*/
public final void setM03(float m03) {
this.m03 = m03;
}
/**
* Get the fourth element of the second row.
*
* @return Returns the m13.
*
* @since vecmath 1.5
*/
public final float getM13() {
return m13;
}
/**
* Set the fourth element of the second row.
*
* @param m13 The m13 to set.
*
* @since vecmath 1.5
*/
public final void setM13(float m13) {
this.m13 = m13;
}
/**
* Get the fourth element of the third row.
*
* @return Returns the m23.
*
* @since vecmath 1.5
*/
public final float getM23() {
return m23;
}
/**
* Set the fourth element of the third row.
*
* @param m23 The m23 to set.
*
* @since vecmath 1.5
*/
public final void setM23(float m23) {
this.m23 = m23;
}
/**
* Get the first element of the fourth row.
*
* @return Returns the m30.
*
* @since vecmath 1.5
*/
public final float getM30() {
return m30;
}
/**
* Set the first element of the fourth row.
*
* @param m30 The m30 to set.
*
*
* @since vecmath 1.5
*/
public final void setM30(float m30) {
this.m30 = m30;
}
/**
* Get the second element of the fourth row.
*
* @return Returns the m31.
*
* @since vecmath 1.5
*/
public final float getM31() {
return m31;
}
/**
* Set the second element of the fourth row.
*
* @param m31 The m31 to set.
*
* @since vecmath 1.5
*/
public final void setM31(float m31) {
this.m31 = m31;
}
/**
* Get the third element of the fourth row.
*
* @return Returns the m32.
*
* @since vecmath 1.5
*/
public final float getM32() {
return m32;
}
/**
* Set the third element of the fourth row.
*
* @param m32 The m32 to set.
*
*
* @since vecmath 1.5
*/
public final void setM32(float m32) {
this.m32 = m32;
}
/**
* Get the fourth element of the fourth row.
*
* @return Returns the m33.
*
* @since vecmath 1.5
*/
public final float getM33() {
return m33;
}
/**
* Set the fourth element of the fourth row.
*
* @param m33 The m33 to set.
*
* @since vecmath 1.5
*/
public final void setM33(float m33) {
this.m33 = m33;
}
}
source-cvs/vecmath/src/javax/vecmath/SingularMatrixException.java 0000644 0001750 0001750 00000003342 10761613452 024703 0 ustar jonny jonny /*
* $RCSfile: SingularMatrixException.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.5 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
/**
* Indicates that inverse of a matrix can not be computed.
*/
public class SingularMatrixException extends RuntimeException{
/**
* Create the exception object with default values.
*/
public SingularMatrixException(){
}
/**
* Create the exception object that outputs message.
* @param str the message string to be output.
*/
public SingularMatrixException(String str){
super(str);
}
}
source-cvs/vecmath/src/javax/vecmath/Point4d.java 0000644 0001750 0001750 00000014005 10761613452 021372 0 ustar jonny jonny /*
* $RCSfile: Point4d.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.6 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 4 element vector represented by double precision floating point
* x,y,z,w coordinates.
*
*/
public class Point4d extends Tuple4d implements java.io.Serializable {
// Compatible with 1.1
static final long serialVersionUID = 1733471895962736949L;
/**
* Constructs and initializes a Point4d from the specified xyzw coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @param w the w coordinate
*/
public Point4d(double x, double y, double z, double w)
{
super(x,y,z,w);
}
/**
* Constructs and initializes a Point4d from the coordinates contained
* in the array.
* @param p the array of length 4 containing xyzw in order
*/
public Point4d(double[] p)
{
super(p);
}
/**
* Constructs and initializes a Point4d from the specified Point4d.
* @param p1 the Point4d containing the initialization x y z w data
*/
public Point4d(Point4d p1)
{
super(p1);
}
/**
* Constructs and initializes a Point4d from the specified Point4f.
* @param p1 the Point4f containing the initialization x y z w data
*/
public Point4d(Point4f p1)
{
super(p1);
}
/**
* Constructs and initializes a Point4d from the specified Tuple4f.
* @param t1 the Tuple4f containing the initialization x y z w data
*/
public Point4d(Tuple4f t1)
{
super(t1);
}
/**
* Constructs and initializes a Point4d from the specified Tuple4d.
* @param t1 the Tuple4d containing the initialization x y z w data
*/
public Point4d(Tuple4d t1)
{
super(t1);
}
/**
* Constructs and initializes a Point4d from the specified Tuple3d.
* The x,y,z components of this point are set to the corresponding
* components of tuple t1. The w component of this point
* is set to 1.
* @param t1 the tuple to be copied
*
* @since vecmath 1.2
*/
public Point4d(Tuple3d t1) {
super(t1.x, t1.y, t1.z, 1.0);
}
/**
* Constructs and initializes a Point4d to (0,0,0,0).
*/
public Point4d()
{
super();
}
/**
* Sets the x,y,z components of this point to the corresponding
* components of tuple t1. The w component of this point
* is set to 1.
* @param t1 the tuple to be copied
*
* @since vecmath 1.2
*/
public final void set(Tuple3d t1) {
this.x = t1.x;
this.y = t1.y;
this.z = t1.z;
this.w = 1.0;
}
/**
* Returns the square of the distance between this point and point p1.
* @param p1 the first point
* @return the square of distance between this point and point p1
*/
public final double distanceSquared(Point4d p1)
{
double dx, dy, dz, dw;
dx = this.x-p1.x;
dy = this.y-p1.y;
dz = this.z-p1.z;
dw = this.w-p1.w;
return (dx*dx+dy*dy+dz*dz+dw*dw);
}
/**
* Returns the distance between this point and point p1.
* @param p1 the first point
* @return the distance between these this point and point p1.
*/
public final double distance(Point4d p1)
{
double dx, dy, dz, dw;
dx = this.x-p1.x;
dy = this.y-p1.y;
dz = this.z-p1.z;
dw = this.w-p1.w;
return Math.sqrt(dx*dx+dy*dy+dz*dz+dw*dw);
}
/**
* Computes the L-1 (Manhattan) distance between this point and
* point p1. The L-1 distance is equal to:
* abs(x1-x2) + abs(y1-y2) + abs(z1-z2) + abs(w1-w2).
* @param p1 the other point
* @return the L-1 distance
*/
public final double distanceL1(Point4d p1) {
return Math.abs(this.x-p1.x) + Math.abs(this.y-p1.y) +
Math.abs(this.z-p1.z) + Math.abs(this.w-p1.w);
}
/**
* Computes the L-infinite distance between this point and
* point p1. The L-infinite distance is equal to
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(w1-w2)].
* @param p1 the other point
* @return the L-infinite distance
*/
public final double distanceLinf(Point4d p1) {
double t1, t2;
t1 = Math.max( Math.abs(this.x-p1.x), Math.abs(this.y-p1.y));
t2 = Math.max( Math.abs(this.z-p1.z), Math.abs(this.w-p1.w));
return Math.max(t1,t2);
}
/**
* Multiplies each of the x,y,z components of the Point4d parameter
* by 1/w, places the projected values into this point, and places
* a 1 as the w parameter of this point.
* @param p1 the source Point4d, which is not modified
*/
public final void project(Point4d p1)
{
double oneOw;
oneOw = 1/p1.w;
x = p1.x*oneOw;
y = p1.y*oneOw;
z = p1.z*oneOw;
w = 1.0;
}
}
source-cvs/vecmath/src/javax/vecmath/Tuple3f.java 0000644 0001750 0001750 00000040306 10761613453 021377 0 ustar jonny jonny /*
* $RCSfile: Tuple3f.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.8 $
* $Date: 2008/02/28 20:18:51 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A generic 3-element tuple that is represented by single precision-floating
* point x,y,z coordinates.
*
*/
public abstract class Tuple3f implements java.io.Serializable, Cloneable {
static final long serialVersionUID=5019834619484343712L;
/**
* The x coordinate.
*/
public float x;
/**
* The y coordinate.
*/
public float y;
/**
* The z coordinate.
*/
public float z;
/**
* Constructs and initializes a Tuple3f from the specified xyz coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
*/
public Tuple3f(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
/**
* Constructs and initializes a Tuple3f from the array of length 3.
* @param t the array of length 3 containing xyz in order
*/
public Tuple3f(float[] t)
{
this.x = t[0];
this.y = t[1];
this.z = t[2];
}
/**
* Constructs and initializes a Tuple3f from the specified Tuple3f.
* @param t1 the Tuple3f containing the initialization x y z data
*/
public Tuple3f(Tuple3f t1)
{
this.x = t1.x;
this.y = t1.y;
this.z = t1.z;
}
/**
* Constructs and initializes a Tuple3f from the specified Tuple3d.
* @param t1 the Tuple3d containing the initialization x y z data
*/
public Tuple3f(Tuple3d t1)
{
this.x = (float) t1.x;
this.y = (float) t1.y;
this.z = (float) t1.z;
}
/**
* Constructs and initializes a Tuple3f to (0,0,0).
*/
public Tuple3f()
{
this.x = 0.0f;
this.y = 0.0f;
this.z = 0.0f;
}
/**
* Returns a string that contains the values of this Tuple3f.
* The form is (x,y,z).
* @return the String representation
*/
public String toString() {
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
}
/**
* Sets the value of this tuple to the specified xyz coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
*/
public final void set(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
/**
* Sets the value of this tuple to the xyz coordinates specified in
* the array of length 3.
* @param t the array of length 3 containing xyz in order
*/
public final void set(float[] t)
{
this.x = t[0];
this.y = t[1];
this.z = t[2];
}
/**
* Sets the value of this tuple to the value of tuple t1.
* @param t1 the tuple to be copied
*/
public final void set(Tuple3f t1)
{
this.x = t1.x;
this.y = t1.y;
this.z = t1.z;
}
/**
* Sets the value of this tuple to the value of tuple t1.
* @param t1 the tuple to be copied
*/
public final void set(Tuple3d t1)
{
this.x = (float) t1.x;
this.y = (float) t1.y;
this.z = (float) t1.z;
}
/**
* Gets the value of this tuple and copies the values into t.
* @param t the array of length 3 into which the values are copied
*/
public final void get(float[] t)
{
t[0] = this.x;
t[1] = this.y;
t[2] = this.z;
}
/**
* Gets the value of this tuple and copies the values into t.
* @param t the Tuple3f object into which the values of this object are copied
*/
public final void get(Tuple3f t)
{
t.x = this.x;
t.y = this.y;
t.z = this.z;
}
/**
* Sets the value of this tuple to the vector sum of tuples t1 and t2.
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void add(Tuple3f t1, Tuple3f t2)
{
this.x = t1.x + t2.x;
this.y = t1.y + t2.y;
this.z = t1.z + t2.z;
}
/**
* Sets the value of this tuple to the vector sum of itself and tuple t1.
* @param t1 the other tuple
*/
public final void add(Tuple3f t1)
{
this.x += t1.x;
this.y += t1.y;
this.z += t1.z;
}
/**
* Sets the value of this tuple to the vector difference
* of tuples t1 and t2 (this = t1 - t2).
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void sub(Tuple3f t1, Tuple3f t2)
{
this.x = t1.x - t2.x;
this.y = t1.y - t2.y;
this.z = t1.z - t2.z;
}
/**
* Sets the value of this tuple to the vector difference of
* itself and tuple t1 (this = this - t1) .
* @param t1 the other tuple
*/
public final void sub(Tuple3f t1)
{
this.x -= t1.x;
this.y -= t1.y;
this.z -= t1.z;
}
/**
* Sets the value of this tuple to the negation of tuple t1.
* @param t1 the source tuple
*/
public final void negate(Tuple3f t1)
{
this.x = -t1.x;
this.y = -t1.y;
this.z = -t1.z;
}
/**
* Negates the value of this tuple in place.
*/
public final void negate()
{
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
}
/**
* Sets the value of this vector to the scalar multiplication
* of tuple t1.
* @param s the scalar value
* @param t1 the source tuple
*/
public final void scale(float s, Tuple3f t1)
{
this.x = s*t1.x;
this.y = s*t1.y;
this.z = s*t1.z;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of the scale factor with this.
* @param s the scalar value
*/
public final void scale(float s)
{
this.x *= s;
this.y *= s;
this.z *= s;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of tuple t1 and then adds tuple t2 (this = s*t1 + t2).
* @param s the scalar value
* @param t1 the tuple to be scaled and added
* @param t2 the tuple to be added without a scale
*/
public final void scaleAdd(float s, Tuple3f t1, Tuple3f t2)
{
this.x = s*t1.x + t2.x;
this.y = s*t1.y + t2.y;
this.z = s*t1.z + t2.z;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of itself and then adds tuple t1 (this = s*this + t1).
* @param s the scalar value
* @param t1 the tuple to be added
*/
public final void scaleAdd(float s, Tuple3f t1)
{
this.x = s*this.x + t1.x;
this.y = s*this.y + t1.y;
this.z = s*this.z + t1.z;
}
/**
* Returns true if the Object t1 is of type Tuple3f and all of the
* data members of t1 are equal to the corresponding data members in
* this Tuple3f.
* @param t1 the vector with which the comparison is made
* @return true or false
*/
public boolean equals(Tuple3f t1)
{
try {
return(this.x == t1.x && this.y == t1.y && this.z == t1.z);
}
catch (NullPointerException e2) {return false;}
}
/**
* Returns true if the Object t1 is of type Tuple3f and all of the
* data members of t1 are equal to the corresponding data members in
* this Tuple3f.
* @param t1 the Object with which the comparison is made
* @return true or false
*/
public boolean equals(Object t1)
{
try {
Tuple3f t2 = (Tuple3f) t1;
return(this.x == t2.x && this.y == t2.y && this.z == t2.z);
}
catch (NullPointerException e2) {return false;}
catch (ClassCastException e1) {return false;}
}
/**
* Returns true if the L-infinite distance between this tuple
* and tuple t1 is less than or equal to the epsilon parameter,
* otherwise returns false. The L-infinite
* distance is equal to MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2)].
* @param t1 the tuple to be compared to this tuple
* @param epsilon the threshold value
* @return true or false
*/
public boolean epsilonEquals(Tuple3f t1, float epsilon)
{
float diff;
diff = x - t1.x;
if(Float.isNaN(diff)) return false;
if((diff<0?-diff:diff) > epsilon) return false;
diff = y - t1.y;
if(Float.isNaN(diff)) return false;
if((diff<0?-diff:diff) > epsilon) return false;
diff = z - t1.z;
if(Float.isNaN(diff)) return false;
if((diff<0?-diff:diff) > epsilon) return false;
return true;
}
/**
* Returns a hash code value based on the data values in this
* object. Two different Tuple3f objects with identical data values
* (i.e., Tuple3f.equals returns true) will return the same hash
* code value. Two objects with different data members may return the
* same hash value, although this is not likely.
* @return the integer hash code value
*/
public int hashCode() {
long bits = 1L;
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(x);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(y);
bits = 31L * bits + (long)VecMathUtil.floatToIntBits(z);
return (int) (bits ^ (bits >> 32));
}
/**
* Clamps the tuple parameter to the range [low, high] and
* places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clamp(float min, float max, Tuple3f t)
{
if( t.x > max ) {
x = max;
} else if( t.x < min ){
x = min;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else if( t.y < min ){
y = min;
} else {
y = t.y;
}
if( t.z > max ) {
z = max;
} else if( t.z < min ){
z = min;
} else {
z = t.z;
}
}
/**
* Clamps the minimum value of the tuple parameter to the min
* parameter and places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMin(float min, Tuple3f t)
{
if( t.x < min ) {
x = min;
} else {
x = t.x;
}
if( t.y < min ) {
y = min;
} else {
y = t.y;
}
if( t.z < min ) {
z = min;
} else {
z = t.z;
}
}
/**
* Clamps the maximum value of the tuple parameter to the max
* parameter and places the values into this tuple.
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMax(float max, Tuple3f t)
{
if( t.x > max ) {
x = max;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else {
y = t.y;
}
if( t.z > max ) {
z = max;
} else {
z = t.z;
}
}
/**
* Sets each component of the tuple parameter to its absolute
* value and places the modified values into this tuple.
* @param t the source tuple, which will not be modified
*/
public final void absolute(Tuple3f t)
{
x = Math.abs(t.x);
y = Math.abs(t.y);
z = Math.abs(t.z);
}
/**
* Clamps this tuple to the range [low, high].
* @param min the lowest value in this tuple after clamping
* @param max the highest value in this tuple after clamping
*/
public final void clamp(float min, float max)
{
if( x > max ) {
x = max;
} else if( x < min ){
x = min;
}
if( y > max ) {
y = max;
} else if( y < min ){
y = min;
}
if( z > max ) {
z = max;
} else if( z < min ){
z = min;
}
}
/**
* Clamps the minimum value of this tuple to the min parameter.
* @param min the lowest value in this tuple after clamping
*/
public final void clampMin(float min)
{
if( x < min ) x=min;
if( y < min ) y=min;
if( z < min ) z=min;
}
/**
* Clamps the maximum value of this tuple to the max parameter.
* @param max the highest value in the tuple after clamping
*/
public final void clampMax(float max)
{
if( x > max ) x=max;
if( y > max ) y=max;
if( z > max ) z=max;
}
/**
* Sets each component of this tuple to its absolute value.
*/
public final void absolute()
{
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
}
/**
* Linearly interpolates between tuples t1 and t2 and places the
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
* @param t1 the first tuple
* @param t2 the second tuple
* @param alpha the alpha interpolation parameter
*/
public final void interpolate(Tuple3f t1, Tuple3f t2, float alpha)
{
this.x = (1-alpha)*t1.x + alpha*t2.x;
this.y = (1-alpha)*t1.y + alpha*t2.y;
this.z = (1-alpha)*t1.z + alpha*t2.z;
}
/**
* Linearly interpolates between this tuple and tuple t1 and
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
* @param t1 the first tuple
* @param alpha the alpha interpolation parameter
*/
public final void interpolate(Tuple3f t1, float alpha)
{
this.x = (1-alpha)*this.x + alpha*t1.x;
this.y = (1-alpha)*this.y + alpha*t1.y;
this.z = (1-alpha)*this.z + alpha*t1.z;
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError if there is not enough memory.
* @see java.lang.Cloneable
* @since vecmath 1.3
*/
public Object clone() {
// Since there are no arrays we can just use Object.clone()
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* Get the x coordinate.
*
* @return the x coordinate.
*
* @since vecmath 1.5
*/
public final float getX() {
return x;
}
/**
* Set the x coordinate.
*
* @param x value to x coordinate.
*
* @since vecmath 1.5
*/
public final void setX(float x) {
this.x = x;
}
/**
* Get the y coordinate.
*
* @return the y coordinate.
*
* @since vecmath 1.5
*/
public final float getY() {
return y;
}
/**
* Set the y coordinate.
*
* @param y value to y coordinate.
*
* @since vecmath 1.5
*/
public final void setY(float y) {
this.y = y;
}
/**
* Get the z coordinate.
*
* @return the z coordinate
*
* @since vecmath 1.5
*/
public final float getZ() {
return z;
}
/**
* Set the Z coordinate.
*
* @param z value to z coordinate.
*
* @since vecmath 1.5
*/
public final void setZ(float z) {
this.z = z;
}
}
source-cvs/vecmath/src/javax/vecmath/Point2d.java 0000644 0001750 0001750 00000010251 10761613452 021367 0 ustar jonny jonny /*
* $RCSfile: Point2d.java,v $
*
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.5 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 2 element point that is represented by double precision floating
* point x,y coordinates.
*
*/
public class Point2d extends Tuple2d implements java.io.Serializable {
// Compatible with 1.1
static final long serialVersionUID = 1133748791492571954L;
/**
* Constructs and initializes a Point2d from the specified xy coordinates.
* @param x the x coordinate
* @param y the y coordinate
*/
public Point2d(double x, double y)
{
super(x,y);
}
/**
* Constructs and initializes a Point2d from the specified array.
* @param p the array of length 2 containing xy in order
*/
public Point2d(double[] p)
{
super(p);
}
/**
* Constructs and initializes a Point2d from the specified Point2d.
* @param p1 the Point2d containing the initialization x y data
*/
public Point2d(Point2d p1)
{
super(p1);
}
/**
* Constructs and initializes a Point2d from the specified Point2f.
* @param p1 the Point2f containing the initialization x y data
*/
public Point2d(Point2f p1)
{
super(p1);
}
/**
* Constructs and initializes a Point2d from the specified Tuple2d.
* @param t1 the Tuple2d containing the initialization x y data
*/
public Point2d(Tuple2d t1)
{
super(t1);
}
/**
* Constructs and initializes a Point2d from the specified Tuple2f.
* @param t1 the Tuple2f containing the initialization x y data
*/
public Point2d(Tuple2f t1)
{
super(t1);
}
/**
* Constructs and initializes a Point2d to (0,0).
*/
public Point2d()
{
super();
}
/**
* Computes the square of the distance between this point and point p1.
* @param p1 the other point
*/
public final double distanceSquared(Point2d p1)
{
double dx, dy;
dx = this.x-p1.x;
dy = this.y-p1.y;
return dx*dx+dy*dy;
}
/**
* Computes the distance between this point and point p1.
* @param p1 the other point
*/
public final double distance(Point2d p1)
{
double dx, dy;
dx = this.x-p1.x;
dy = this.y-p1.y;
return Math.sqrt(dx*dx+dy*dy);
}
/**
* Computes the L-1 (Manhattan) distance between this point and
* point p1. The L-1 distance is equal to abs(x1-x2) + abs(y1-y2).
* @param p1 the other point
*/
public final double distanceL1(Point2d p1)
{
return( Math.abs(this.x-p1.x) + Math.abs(this.y-p1.y));
}
/**
* Computes the L-infinite distance between this point and
* point p1. The L-infinite distance is equal to
* MAX[abs(x1-x2), abs(y1-y2)].
* @param p1 the other point
*/
public final double distanceLinf(Point2d p1)
{
return(Math.max( Math.abs(this.x-p1.x), Math.abs(this.y-p1.y)));
}
}
source-cvs/vecmath/src/javax/vecmath/Color4b.java 0000644 0001750 0001750 00000010670 10761613452 021361 0 ustar jonny jonny /*
* $RCSfile: Color4b.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.6 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.awt.Color;
/**
* A four-byte color value represented by byte x, y, z, and w values.
* The x, y, z, and w values represent the red, green, blue, and alpha
* values, respectively.
*
* Note that Java defines a byte as a signed integer in the range
* [-128, 127]. However, colors are more typically represented by values
* in the range [0, 255]. Java 3D recognizes this and for color
* treats the bytes as if the range were [0, 255]---in other words, as
* if the bytes were unsigned.
*
* Java 3D assumes that a linear (gamma-corrected) visual is used for
* all colors.
*
*/
public class Color4b extends Tuple4b implements java.io.Serializable {
// Compatible with 1.1
static final long serialVersionUID = -105080578052502155L;
/**
* Constructs and initializes a Color4b from the four specified values.
* @param b1 the red color value
* @param b2 the green color value
* @param b3 the blue color value
* @param b4 the alpha value
*/
public Color4b(byte b1, byte b2, byte b3, byte b4) {
super(b1,b2,b3,b4);
}
/**
* Constructs and initializes a Color4b from the array of length 4.
* @param c the array of length 4 containing r, g, b, and alpha in order
*/
public Color4b(byte[] c) {
super(c);
}
/**
* Constructs and initializes a Color4b from the specified Color4b.
* @param c1 the Color4b containing the initialization r,g,b,a
* data
*/
public Color4b(Color4b c1) {
super(c1);
}
/**
* Constructs and initializes a Color4b from the specified Tuple4b.
* @param t1 the Tuple4b containing the initialization r,g,b,a
* data
*/
public Color4b(Tuple4b t1) {
super(t1);
}
/**
* Constructs and initializes a Color4b from the specified AWT
* Color object.
* No conversion is done on the color to compensate for
* gamma correction.
*
* @param color the AWT color with which to initialize this
* Color4b object
*
* @since vecmath 1.2
*/
public Color4b(Color color) {
super((byte)color.getRed(),
(byte)color.getGreen(),
(byte)color.getBlue(),
(byte)color.getAlpha());
}
/**
* Constructs and initializes a Color4b to (0,0,0,0).
*/
public Color4b() {
super();
}
/**
* Sets the r,g,b,a values of this Color4b object to those of the
* specified AWT Color object.
* No conversion is done on the color to compensate for
* gamma correction.
*
* @param color the AWT color to copy into this Color4b object
*
* @since vecmath 1.2
*/
public final void set(Color color) {
x = (byte)color.getRed();
y = (byte)color.getGreen();
z = (byte)color.getBlue();
w = (byte)color.getAlpha();
}
/**
* Returns a new AWT color object initialized with the r,g,b,a
* values of this Color4b object.
*
* @return a new AWT Color object
*
* @since vecmath 1.2
*/
public final Color get() {
int r = (int)x & 0xff;
int g = (int)y & 0xff;
int b = (int)z & 0xff;
int a = (int)w & 0xff;
return new Color(r, g, b, a);
}
}
source-cvs/vecmath/src/javax/vecmath/Tuple3i.java 0000644 0001750 0001750 00000031351 10761613453 021402 0 ustar jonny jonny /*
* $RCSfile: Tuple3i.java,v $
*
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.7 $
* $Date: 2008/02/28 20:18:51 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 3-element tuple represented by signed integer x,y,z
* coordinates.
*
* @since vecmath 1.2
*/
public abstract class Tuple3i implements java.io.Serializable, Cloneable {
static final long serialVersionUID = -732740491767276200L;
/**
* The x coordinate.
*/
public int x;
/**
* The y coordinate.
*/
public int y;
/**
* The z coordinate.
*/
public int z;
/**
* Constructs and initializes a Tuple3i from the specified
* x, y, and z coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
*/
public Tuple3i(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Constructs and initializes a Tuple3i from the array of length 3.
* @param t the array of length 3 containing x, y, and z in order.
*/
public Tuple3i(int[] t) {
this.x = t[0];
this.y = t[1];
this.z = t[2];
}
/**
* Constructs and initializes a Tuple3i from the specified Tuple3i.
* @param t1 the Tuple3i containing the initialization x, y, and z
* data.
*/
public Tuple3i(Tuple3i t1) {
this.x = t1.x;
this.y = t1.y;
this.z = t1.z;
}
/**
* Constructs and initializes a Tuple3i to (0,0,0).
*/
public Tuple3i() {
this.x = 0;
this.y = 0;
this.z = 0;
}
/**
* Sets the value of this tuple to the specified x, y, and z
* coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
*/
public final void set(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Sets the value of this tuple to the specified coordinates in the
* array of length 3.
* @param t the array of length 3 containing x, y, and z in order.
*/
public final void set(int[] t) {
this.x = t[0];
this.y = t[1];
this.z = t[2];
}
/**
* Sets the value of this tuple to the value of tuple t1.
* @param t1 the tuple to be copied
*/
public final void set(Tuple3i t1) {
this.x = t1.x;
this.y = t1.y;
this.z = t1.z;
}
/**
* Copies the values of this tuple into the array t.
* @param t is the array
*/
public final void get(int[] t) {
t[0] = this.x;
t[1] = this.y;
t[2] = this.z;
}
/**
* Copies the values of this tuple into the tuple t.
* @param t is the target tuple
*/
public final void get(Tuple3i t) {
t.x = this.x;
t.y = this.y;
t.z = this.z;
}
/**
* Sets the value of this tuple to the sum of tuples t1 and t2.
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void add(Tuple3i t1, Tuple3i t2) {
this.x = t1.x + t2.x;
this.y = t1.y + t2.y;
this.z = t1.z + t2.z;
}
/**
* Sets the value of this tuple to the sum of itself and t1.
* @param t1 the other tuple
*/
public final void add(Tuple3i t1) {
this.x += t1.x;
this.y += t1.y;
this.z += t1.z;
}
/**
* Sets the value of this tuple to the difference
* of tuples t1 and t2 (this = t1 - t2).
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void sub(Tuple3i t1, Tuple3i t2) {
this.x = t1.x - t2.x;
this.y = t1.y - t2.y;
this.z = t1.z - t2.z;
}
/**
* Sets the value of this tuple to the difference
* of itself and t1 (this = this - t1).
* @param t1 the other tuple
*/
public final void sub(Tuple3i t1) {
this.x -= t1.x;
this.y -= t1.y;
this.z -= t1.z;
}
/**
* Sets the value of this tuple to the negation of tuple t1.
* @param t1 the source tuple
*/
public final void negate(Tuple3i t1) {
this.x = -t1.x;
this.y = -t1.y;
this.z = -t1.z;
}
/**
* Negates the value of this tuple in place.
*/
public final void negate() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of tuple t1.
* @param s the scalar value
* @param t1 the source tuple
*/
public final void scale(int s, Tuple3i t1) {
this.x = s*t1.x;
this.y = s*t1.y;
this.z = s*t1.z;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of the scale factor with this.
* @param s the scalar value
*/
public final void scale(int s) {
this.x *= s;
this.y *= s;
this.z *= s;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of tuple t1 plus tuple t2 (this = s*t1 + t2).
* @param s the scalar value
* @param t1 the tuple to be multipled
* @param t2 the tuple to be added
*/
public final void scaleAdd(int s, Tuple3i t1, Tuple3i t2) {
this.x = s*t1.x + t2.x;
this.y = s*t1.y + t2.y;
this.z = s*t1.z + t2.z;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of itself and then adds tuple t1 (this = s*this + t1).
* @param s the scalar value
* @param t1 the tuple to be added
*/
public final void scaleAdd(int s, Tuple3i t1) {
this.x = s*this.x + t1.x;
this.y = s*this.y + t1.y;
this.z = s*this.z + t1.z;
}
/**
* Returns a string that contains the values of this Tuple3i.
* The form is (x,y,z).
* @return the String representation
*/
public String toString() {
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
}
/**
* Returns true if the Object t1 is of type Tuple3i and all of the
* data members of t1 are equal to the corresponding data members in
* this Tuple3i.
* @param t1 the object with which the comparison is made
*/
public boolean equals(Object t1) {
try {
Tuple3i t2 = (Tuple3i) t1;
return(this.x == t2.x && this.y == t2.y && this.z == t2.z);
}
catch (NullPointerException e2) {
return false;
}
catch (ClassCastException e1) {
return false;
}
}
/**
* Returns a hash code value based on the data values in this
* object. Two different Tuple3i objects with identical data values
* (i.e., Tuple3i.equals returns true) will return the same hash
* code value. Two objects with different data members may return the
* same hash value, although this is not likely.
* @return the integer hash code value
*/
public int hashCode() {
long bits = 1L;
bits = 31L * bits + (long)x;
bits = 31L * bits + (long)y;
bits = 31L * bits + (long)z;
return (int) (bits ^ (bits >> 32));
}
/**
* Clamps the tuple parameter to the range [low, high] and
* places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clamp(int min, int max, Tuple3i t) {
if( t.x > max ) {
x = max;
} else if( t.x < min ) {
x = min;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else if( t.y < min ) {
y = min;
} else {
y = t.y;
}
if( t.z > max ) {
z = max;
} else if( t.z < min ) {
z = min;
} else {
z = t.z;
}
}
/**
* Clamps the minimum value of the tuple parameter to the min
* parameter and places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMin(int min, Tuple3i t) {
if( t.x < min ) {
x = min;
} else {
x = t.x;
}
if( t.y < min ) {
y = min;
} else {
y = t.y;
}
if( t.z < min ) {
z = min;
} else {
z = t.z;
}
}
/**
* Clamps the maximum value of the tuple parameter to the max
* parameter and places the values into this tuple.
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMax(int max, Tuple3i t) {
if( t.x > max ) {
x = max;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else {
y = t.y;
}
if( t.z > max ) {
z = max;
} else {
z = t.z;
}
}
/**
* Sets each component of the tuple parameter to its absolute
* value and places the modified values into this tuple.
* @param t the source tuple, which will not be modified
*/
public final void absolute(Tuple3i t) {
x = Math.abs(t.x);
y = Math.abs(t.y);
z = Math.abs(t.z);
}
/**
* Clamps this tuple to the range [low, high].
* @param min the lowest value in this tuple after clamping
* @param max the highest value in this tuple after clamping
*/
public final void clamp(int min, int max) {
if( x > max ) {
x = max;
} else if( x < min ) {
x = min;
}
if( y > max ) {
y = max;
} else if( y < min ) {
y = min;
}
if( z > max ) {
z = max;
} else if( z < min ) {
z = min;
}
}
/**
* Clamps the minimum value of this tuple to the min parameter.
* @param min the lowest value in this tuple after clamping
*/
public final void clampMin(int min) {
if (x < min)
x=min;
if (y < min)
y = min;
if (z < min)
z = min;
}
/**
* Clamps the maximum value of this tuple to the max parameter.
* @param max the highest value in the tuple after clamping
*/
public final void clampMax(int max) {
if (x > max)
x = max;
if (y > max)
y = max;
if (z > max)
z = max;
}
/**
* Sets each component of this tuple to its absolute value.
*/
public final void absolute() {
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError if there is not enough memory.
* @see java.lang.Cloneable
* @since vecmath 1.3
*/
public Object clone() {
// Since there are no arrays we can just use Object.clone()
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* Get the x coordinate.
*
* @return the x coordinate.
*
* @since vecmath 1.5
*/
public final int getX() {
return x;
}
/**
* Set the x coordinate.
*
* @param x value to x coordinate.
*
* @since vecmath 1.5
*/
public final void setX(int x) {
this.x = x;
}
/**
* Get the y coordinate.
*
* @return the y coordinate.
*
* @since vecmath 1.5
*/
public final int getY() {
return y;
}
/**
* Set the y coordinate.
*
* @param y value to y coordinate.
*
* @since vecmath 1.5
*/
public final void setY(int y) {
this.y = y;
}
/**
* Get the z coordinate.
*
* @return the z coordinate.
* @since vecmath 1.5
*/
public final int getZ() {
return z;
}
/**
* Set the z coordinate.
*
* @param z value to z coordinate.
*
* @since vecmath 1.5
*/
public final void setZ(int z) {
this.z = z;
}
}
source-cvs/vecmath/src/javax/vecmath/Tuple2i.java 0000644 0001750 0001750 00000026550 10761613453 021406 0 ustar jonny jonny /*
* $RCSfile: Tuple2i.java,v $
*
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.6 $
* $Date: 2008/02/28 20:18:51 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 2-element tuple represented by signed integer x,y
* coordinates.
*
* @since vecmath 1.4
*/
public abstract class Tuple2i implements java.io.Serializable, Cloneable {
static final long serialVersionUID = -3555701650170169638L;
/**
* The x coordinate.
*/
public int x;
/**
* The y coordinate.
*/
public int y;
/**
* Constructs and initializes a Tuple2i from the specified
* x and y coordinates.
* @param x the x coordinate
* @param y the y coordinate
*/
public Tuple2i(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Constructs and initializes a Tuple2i from the array of length 2.
* @param t the array of length 2 containing x and y in order.
*/
public Tuple2i(int[] t) {
this.x = t[0];
this.y = t[1];
}
/**
* Constructs and initializes a Tuple2i from the specified Tuple2i.
* @param t1 the Tuple2i containing the initialization x and y
* data.
*/
public Tuple2i(Tuple2i t1) {
this.x = t1.x;
this.y = t1.y;
}
/**
* Constructs and initializes a Tuple2i to (0,0).
*/
public Tuple2i() {
this.x = 0;
this.y = 0;
}
/**
* Sets the value of this tuple to the specified x and y
* coordinates.
* @param x the x coordinate
* @param y the y coordinate
*/
public final void set(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Sets the value of this tuple to the specified coordinates in the
* array of length 2.
* @param t the array of length 2 containing x and y in order.
*/
public final void set(int[] t) {
this.x = t[0];
this.y = t[1];
}
/**
* Sets the value of this tuple to the value of tuple t1.
* @param t1 the tuple to be copied
*/
public final void set(Tuple2i t1) {
this.x = t1.x;
this.y = t1.y;
}
/**
* Copies the values of this tuple into the array t.
* @param t is the array
*/
public final void get(int[] t) {
t[0] = this.x;
t[1] = this.y;
}
/**
* Copies the values of this tuple into the tuple t.
* @param t is the target tuple
*/
public final void get(Tuple2i t) {
t.x = this.x;
t.y = this.y;
}
/**
* Sets the value of this tuple to the sum of tuples t1 and t2.
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void add(Tuple2i t1, Tuple2i t2) {
this.x = t1.x + t2.x;
this.y = t1.y + t2.y;
}
/**
* Sets the value of this tuple to the sum of itself and t1.
* @param t1 the other tuple
*/
public final void add(Tuple2i t1) {
this.x += t1.x;
this.y += t1.y;
}
/**
* Sets the value of this tuple to the difference
* of tuples t1 and t2 (this = t1 - t2).
* @param t1 the first tuple
* @param t2 the second tuple
*/
public final void sub(Tuple2i t1, Tuple2i t2) {
this.x = t1.x - t2.x;
this.y = t1.y - t2.y;
}
/**
* Sets the value of this tuple to the difference
* of itself and t1 (this = this - t1).
* @param t1 the other tuple
*/
public final void sub(Tuple2i t1) {
this.x -= t1.x;
this.y -= t1.y;
}
/**
* Sets the value of this tuple to the negation of tuple t1.
* @param t1 the source tuple
*/
public final void negate(Tuple2i t1) {
this.x = -t1.x;
this.y = -t1.y;
}
/**
* Negates the value of this tuple in place.
*/
public final void negate() {
this.x = -this.x;
this.y = -this.y;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of tuple t1.
* @param s the scalar value
* @param t1 the source tuple
*/
public final void scale(int s, Tuple2i t1) {
this.x = s*t1.x;
this.y = s*t1.y;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of the scale factor with this.
* @param s the scalar value
*/
public final void scale(int s) {
this.x *= s;
this.y *= s;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of tuple t1 plus tuple t2 (this = s*t1 + t2).
* @param s the scalar value
* @param t1 the tuple to be multipled
* @param t2 the tuple to be added
*/
public final void scaleAdd(int s, Tuple2i t1, Tuple2i t2) {
this.x = s*t1.x + t2.x;
this.y = s*t1.y + t2.y;
}
/**
* Sets the value of this tuple to the scalar multiplication
* of itself and then adds tuple t1 (this = s*this + t1).
* @param s the scalar value
* @param t1 the tuple to be added
*/
public final void scaleAdd(int s, Tuple2i t1) {
this.x = s*this.x + t1.x;
this.y = s*this.y + t1.y;
}
/**
* Returns a string that contains the values of this Tuple2i.
* The form is (x,y).
* @return the String representation
*/
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}
/**
* Returns true if the Object t1 is of type Tuple2i and all of the
* data members of t1 are equal to the corresponding data members in
* this Tuple2i.
* @param t1 the object with which the comparison is made
*/
public boolean equals(Object t1) {
try {
Tuple2i t2 = (Tuple2i) t1;
return(this.x == t2.x && this.y == t2.y);
}
catch (NullPointerException e2) {
return false;
}
catch (ClassCastException e1) {
return false;
}
}
/**
* Returns a hash code value based on the data values in this
* object. Two different Tuple2i objects with identical data values
* (i.e., Tuple2i.equals returns true) will return the same hash
* code value. Two objects with different data members may return the
* same hash value, although this is not likely.
* @return the integer hash code value
*/
public int hashCode() {
long bits = 1L;
bits = 31L * bits + (long)x;
bits = 31L * bits + (long)y;
return (int) (bits ^ (bits >> 32));
}
/**
* Clamps the tuple parameter to the range [low, high] and
* places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clamp(int min, int max, Tuple2i t) {
if( t.x > max ) {
x = max;
} else if( t.x < min ) {
x = min;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else if( t.y < min ) {
y = min;
} else {
y = t.y;
}
}
/**
* Clamps the minimum value of the tuple parameter to the min
* parameter and places the values into this tuple.
* @param min the lowest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMin(int min, Tuple2i t) {
if( t.x < min ) {
x = min;
} else {
x = t.x;
}
if( t.y < min ) {
y = min;
} else {
y = t.y;
}
}
/**
* Clamps the maximum value of the tuple parameter to the max
* parameter and places the values into this tuple.
* @param max the highest value in the tuple after clamping
* @param t the source tuple, which will not be modified
*/
public final void clampMax(int max, Tuple2i t) {
if( t.x > max ) {
x = max;
} else {
x = t.x;
}
if( t.y > max ) {
y = max;
} else {
y = t.y;
}
}
/**
* Sets each component of the tuple parameter to its absolute
* value and places the modified values into this tuple.
* @param t the source tuple, which will not be modified
*/
public final void absolute(Tuple2i t) {
x = Math.abs(t.x);
y = Math.abs(t.y);
}
/**
* Clamps this tuple to the range [low, high].
* @param min the lowest value in this tuple after clamping
* @param max the highest value in this tuple after clamping
*/
public final void clamp(int min, int max) {
if( x > max ) {
x = max;
} else if( x < min ) {
x = min;
}
if( y > max ) {
y = max;
} else if( y < min ) {
y = min;
}
}
/**
* Clamps the minimum value of this tuple to the min parameter.
* @param min the lowest value in this tuple after clamping
*/
public final void clampMin(int min) {
if (x < min)
x=min;
if (y < min)
y = min;
}
/**
* Clamps the maximum value of this tuple to the max parameter.
* @param max the highest value in the tuple after clamping
*/
public final void clampMax(int max) {
if (x > max)
x = max;
if (y > max)
y = max;
}
/**
* Sets each component of this tuple to its absolute value.
*/
public final void absolute() {
x = Math.abs(x);
y = Math.abs(y);
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError if there is not enough memory.
* @see java.lang.Cloneable
*/
public Object clone() {
// Since there are no arrays we can just use Object.clone()
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* Get the x coordinate.
*
* @return the x coordinate.
*
* @since vecmath 1.5
*/
public final int getX() {
return x;
}
/**
* Set the x coordinate.
*
* @param x value to x coordinate.
*
* @since vecmath 1.5
*/
public final void setX(int x) {
this.x = x;
}
/**
* Get the y coordinate.
*
* @return the y coordinate.
*
* @since vecmath 1.5
*/
public final int getY() {
return y;
}
/**
* Set the y coordinate.
*
* @param y value to y coordinate.
*
* @since vecmath 1.5
*/
public final void setY(int y) {
this.y = y;
}
}
source-cvs/vecmath/src/javax/vecmath/TexCoord2f.java 0000644 0001750 0001750 00000005174 10761613452 022037 0 ustar jonny jonny /*
* $RCSfile: TexCoord2f.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.5 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 2-element vector that is represented by single-precision floating
* point x,y coordinates.
*
*/
public class TexCoord2f extends Tuple2f implements java.io.Serializable {
// Combatible with 1.1
static final long serialVersionUID = 7998248474800032487L;
/**
* Constructs and initializes a TexCoord2f from the specified xy coordinates.
* @param x the x coordinate
* @param y the y coordinate
*/
public TexCoord2f(float x, float y)
{
super(x,y);
}
/**
* Constructs and initializes a TexCoord2f from the specified array.
* @param v the array of length 2 containing xy in order
*/
public TexCoord2f(float[] v)
{
super(v);
}
/**
* Constructs and initializes a TexCoord2f from the specified TexCoord2f.
* @param v1 the TexCoord2f containing the initialization x y data
*/
public TexCoord2f(TexCoord2f v1)
{
super(v1);
}
/**
* Constructs and initializes a TexCoord2f from the specified Tuple2f.
* @param t1 the Tuple2f containing the initialization x y data
*/
public TexCoord2f(Tuple2f t1)
{
super(t1);
}
/**
* Constructs and initializes a TexCoord2f to (0,0).
*/
public TexCoord2f()
{
super();
}
}
source-cvs/vecmath/src/javax/vecmath/GMatrix.java 0000644 0001750 0001750 00000214400 10761613452 021425 0 ustar jonny jonny /*
* $RCSfile: GMatrix.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.7 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A double precision, general, dynamically-resizable,
* two-dimensional matrix class. Row and column numbering begins with
* zero. The representation is row major.
*/
public class GMatrix implements java.io.Serializable, Cloneable {
// Compatible with 1.1
static final long serialVersionUID = 2777097312029690941L;
private static final boolean debug = false;
int nRow;
int nCol;
// double dereference is slow
double[][] values;
private static final double EPS = 1.0E-10;
/**
* Constructs an nRow by NCol identity matrix.
* Note that because row and column numbering begins with
* zero, nRow and nCol will be one larger than the maximum
* possible matrix index values.
* @param nRow number of rows in this matrix.
* @param nCol number of columns in this matrix.
*/
public GMatrix(int nRow, int nCol)
{
values = new double[nRow][nCol];
this.nRow = nRow;
this.nCol = nCol;
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
}
}
int l;
if (nRow < nCol)
l = nRow;
else
l = nCol;
for (i = 0; i < l; i++) {
values[i][i] = 1.0;
}
}
/**
* Constructs an nRow by nCol matrix initialized to the values
* in the matrix array. The array values are copied in one row at
* a time in row major fashion. The array should be at least
* nRow*nCol in length.
* Note that because row and column numbering begins with
* zero, nRow and nCol will be one larger than the maximum
* possible matrix index values.
* @param nRow number of rows in this matrix.
* @param nCol number of columns in this matrix.
* @param matrix a 1D array that specifies a matrix in row major fashion
*/
public GMatrix(int nRow, int nCol, double[] matrix)
{
values = new double[nRow][nCol];
this.nRow = nRow;
this.nCol = nCol;
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = matrix[i*nCol+j];
}
}
}
/**
* Constructs a new GMatrix and copies the initial values
* from the parameter matrix.
* @param matrix the source of the initial values of the new GMatrix
*/
public GMatrix(GMatrix matrix)
{
nRow = matrix.nRow;
nCol = matrix.nCol;
values = new double[nRow][nCol];
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = matrix.values[i][j];
}
}
}
/**
* Sets the value of this matrix to the result of multiplying itself
* with matrix m1 (this = this * m1).
* @param m1 the other matrix
*/
public final void mul(GMatrix m1)
{
int i, j, k;
if (nCol != m1.nRow || nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix0"));
double [][] tmp = new double[nRow][nCol];
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
tmp[i][j] = 0.0;
for (k = 0; k < nCol; k++) {
tmp[i][j] += values[i][k]*m1.values[k][j];
}
}
}
values = tmp;
}
/**
* Sets the value of this matrix to the result of multiplying
* the two argument matrices together (this = m1 * m2).
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void mul(GMatrix m1, GMatrix m2)
{
int i, j, k;
if (m1.nCol != m2.nRow || nRow != m1.nRow || nCol != m2.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix1"));
double[][] tmp = new double[nRow][nCol];
for (i = 0; i < m1.nRow; i++) {
for (j = 0; j < m2.nCol; j++) {
tmp[i][j] = 0.0;
for (k = 0; k < m1.nCol; k++) {
tmp[i][j] += m1.values[i][k]*m2.values[k][j];
}
}
}
values = tmp;
}
/**
* Computes the outer product of the two vectors; multiplies the
* the first vector by the transpose of the second vector and places
* the matrix result into this matrix. This matrix must be
* be as big or bigger than getSize(v1)xgetSize(v2).
* @param v1 the first vector, treated as a row vector
* @param v2 the second vector, treated as a column vector
*/
public final void mul(GVector v1, GVector v2)
{
int i, j;
if (nRow < v1.getSize())
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix2"));
if (nCol < v2.getSize())
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix3"));
for (i = 0; i < v1.getSize(); i++ ) {
for (j = 0; j < v2.getSize(); j++ ) {
values[i][j] = v1.values[i]*v2.values[j];
}
}
}
/**
* Sets the value of this matrix to sum of itself and matrix m1.
* @param m1 the other matrix
*/
public final void add(GMatrix m1)
{
int i, j;
if (nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix4"));
if (nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix5"));
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = values[i][j] + m1.values[i][j];
}
}
}
/**
* Sets the value of this matrix to the matrix sum of matrices m1 and m2.
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void add(GMatrix m1, GMatrix m2)
{
int i, j;
if (m2.nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix6"));
if (m2.nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix7"));
if (nCol != m1.nCol || nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix8"));
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = m1.values[i][j] + m2.values[i][j];
}
}
}
/**
* Sets the value of this matrix to the matrix difference of itself
* and matrix m1 (this = this - m1).
* @param m1 the other matrix
*/
public final void sub(GMatrix m1)
{
int i, j;
if (nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix9"));
if (nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix28"));
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = values[i][j] - m1.values[i][j];
}
}
}
/**
* Sets the value of this matrix to the matrix difference
* of matrices m1 and m2 (this = m1 - m2).
* @param m1 the first matrix
* @param m2 the second matrix
*/
public final void sub(GMatrix m1, GMatrix m2)
{
int i, j;
if (m2.nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix10"));
if (m2.nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix11"));
if (nRow != m1.nRow || nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix12"));
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = m1.values[i][j] - m2.values[i][j];
}
}
}
/**
* Negates the value of this matrix: this = -this.
*/
public final void negate()
{
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0;j < nCol; j++) {
values[i][j] = -values[i][j];
}
}
}
/**
* Sets the value of this matrix equal to the negation of
* of the GMatrix parameter.
* @param m1 The source matrix
*/
public final void negate(GMatrix m1)
{
int i, j;
if (nRow != m1.nRow || nCol != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix13"));
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = -m1.values[i][j];
}
}
}
/**
* Sets this GMatrix to the identity matrix.
*/
public final void setIdentity()
{
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
}
}
int l;
if (nRow < nCol)
l = nRow;
else
l = nCol;
for (i = 0; i < l; i++) {
values[i][i] = 1.0;
}
}
/**
* Sets all the values in this matrix to zero.
*/
public final void setZero()
{
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Subtracts this matrix from the identity matrix and puts the values
* back into this (this = I - this).
*/
public final void identityMinus()
{
int i, j;
for(i = 0; i < nRow; i++) {
for(j = 0; j < nCol; j++) {
values[i][j] = -values[i][j];
}
}
int l;
if( nRow < nCol)
l = nRow;
else
l = nCol;
for(i = 0; i < l; i++) {
values[i][i] += 1.0;
}
}
/**
* Inverts this matrix in place.
*/
public final void invert()
{
invertGeneral(this);
}
/**
* Inverts matrix m1 and places the new values into this matrix. Matrix
* m1 is not modified.
* @param m1 the matrix to be inverted
*/
public final void invert(GMatrix m1)
{
invertGeneral(m1);
}
/**
* Copies a sub-matrix derived from this matrix into the target matrix.
* The upper left of the sub-matrix is located at (rowSource, colSource);
* the lower right of the sub-matrix is located at
* (lastRowSource,lastColSource). The sub-matrix is copied into the
* the target matrix starting at (rowDest, colDest).
* @param rowSource the top-most row of the sub-matrix
* @param colSource the left-most column of the sub-matrix
* @param numRow the number of rows in the sub-matrix
* @param numCol the number of columns in the sub-matrix
* @param rowDest the top-most row of the position of the copied
* sub-matrix within the target matrix
* @param colDest the left-most column of the position of the copied
* sub-matrix within the target matrix
* @param target the matrix into which the sub-matrix will be copied
*/
public final void copySubMatrix(int rowSource, int colSource,
int numRow, int numCol, int rowDest,
int colDest, GMatrix target)
{
int i, j;
if (this != target) {
for (i = 0; i < numRow; i++) {
for (j = 0; j < numCol; j++) {
target.values[rowDest+i][colDest+j] =
values[rowSource+i][colSource+j];
}
}
} else {
double[][] tmp = new double[numRow][numCol];
for (i = 0; i < numRow; i++) {
for (j = 0; j < numCol; j++) {
tmp[i][j] = values[rowSource+i][colSource+j];
}
}
for (i = 0; i < numRow; i++) {
for (j = 0; j < numCol; j++) {
target.values[rowDest+i][colDest+j] = tmp[i][j];
}
}
}
}
/**
* Changes the size of this matrix dynamically. If the size is increased
* no data values will be lost. If the size is decreased, only those data
* values whose matrix positions were eliminated will be lost.
* @param nRow number of desired rows in this matrix
* @param nCol number of desired columns in this matrix
*/
public final void setSize(int nRow, int nCol)
{
double[][] tmp = new double[nRow][nCol];
int i, j, maxRow, maxCol;
if (this.nRow < nRow)
maxRow = this.nRow;
else
maxRow = nRow;
if (this.nCol < nCol)
maxCol = this.nCol;
else
maxCol = nCol;
for (i = 0; i < maxRow; i++) {
for (j = 0; j < maxCol; j++) {
tmp[i][j] = values[i][j];
}
}
this.nRow = nRow;
this.nCol = nCol;
values = tmp;
}
/**
* Sets the value of this matrix to the values found in the array parameter.
* The values are copied in one row at a time, in row major
* fashion. The array should be at least equal in length to
* the number of matrix rows times the number of matrix columns
* in this matrix.
* @param matrix the row major source array
*/
public final void set(double[] matrix)
{
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = matrix[nCol*i+j];
}
}
}
/**
* Sets the value of this matrix to that of the Matrix3f provided.
* @param m1 the matrix
*/
public final void set(Matrix3f m1)
{
int i, j;
if (nCol < 3 || nRow < 3) { // expand matrix if too small
nCol = 3;
nRow = 3;
values = new double[nRow][nCol];
}
values[0][0] = m1.m00;
values[0][1] = m1.m01;
values[0][2] = m1.m02;
values[1][0] = m1.m10;
values[1][1] = m1.m11;
values[1][2] = m1.m12;
values[2][0] = m1.m20;
values[2][1] = m1.m21;
values[2][2] = m1.m22;
for (i = 3; i < nRow; i++) { // pad rest or matrix with zeros
for (j = 3; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Sets the value of this matrix to that of the Matrix3d provided.
* @param m1 the matrix
*/
public final void set(Matrix3d m1)
{
if (nRow < 3 || nCol < 3) {
values = new double[3][3];
nRow = 3;
nCol = 3;
}
values[0][0] = m1.m00;
values[0][1] = m1.m01;
values[0][2] = m1.m02;
values[1][0] = m1.m10;
values[1][1] = m1.m11;
values[1][2] = m1.m12;
values[2][0] = m1.m20;
values[2][1] = m1.m21;
values[2][2] = m1.m22;
for (int i = 3; i < nRow; i++) { // pad rest or matrix with zeros
for(int j = 3; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Sets the value of this matrix to that of the Matrix4f provided.
* @param m1 the matrix
*/
public final void set(Matrix4f m1)
{
if (nRow < 4 || nCol < 4) {
values = new double[4][4];
nRow = 4;
nCol = 4;
}
values[0][0] = m1.m00;
values[0][1] = m1.m01;
values[0][2] = m1.m02;
values[0][3] = m1.m03;
values[1][0] = m1.m10;
values[1][1] = m1.m11;
values[1][2] = m1.m12;
values[1][3] = m1.m13;
values[2][0] = m1.m20;
values[2][1] = m1.m21;
values[2][2] = m1.m22;
values[2][3] = m1.m23;
values[3][0] = m1.m30;
values[3][1] = m1.m31;
values[3][2] = m1.m32;
values[3][3] = m1.m33;
for (int i = 4 ; i < nRow; i++) { // pad rest or matrix with zeros
for (int j = 4; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Sets the value of this matrix to that of the Matrix4d provided.
* @param m1 the matrix
*/
public final void set(Matrix4d m1)
{
if (nRow < 4 || nCol < 4) {
values = new double[4][4];
nRow = 4;
nCol = 4;
}
values[0][0] = m1.m00;
values[0][1] = m1.m01;
values[0][2] = m1.m02;
values[0][3] = m1.m03;
values[1][0] = m1.m10;
values[1][1] = m1.m11;
values[1][2] = m1.m12;
values[1][3] = m1.m13;
values[2][0] = m1.m20;
values[2][1] = m1.m21;
values[2][2] = m1.m22;
values[2][3] = m1.m23;
values[3][0] = m1.m30;
values[3][1] = m1.m31;
values[3][2] = m1.m32;
values[3][3] = m1.m33;
for (int i = 4; i < nRow; i++) { // pad rest or matrix with zeros
for (int j = 4; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Sets the value of this matrix to the values found in matrix m1.
* @param m1 the source matrix
*/
public final void set(GMatrix m1)
{
int i, j;
if (nRow < m1.nRow || nCol < m1.nCol) {
nRow = m1.nRow;
nCol = m1.nCol;
values = new double[nRow][nCol];
}
for (i = 0; i < Math.min(nRow, m1.nRow); i++) {
for (j = 0; j < Math.min(nCol, m1.nCol); j++) {
values[i][j] = m1.values[i][j];
}
}
for (i = m1.nRow; i < nRow; i++) { // pad rest or matrix with zeros
for (j = m1.nCol; j < nCol; j++) {
values[i][j] = 0.0;
}
}
}
/**
* Returns the number of rows in this matrix.
* @return number of rows in this matrix
*/
public final int getNumRow()
{
return(nRow);
}
/**
* Returns the number of colmuns in this matrix.
* @return number of columns in this matrix
*/
public final int getNumCol()
{
return(nCol);
}
/**
* Retrieves the value at the specified row and column of this matrix.
* @param row the row number to be retrieved (zero indexed)
* @param column the column number to be retrieved (zero indexed)
* @return the value at the indexed element
*/
public final double getElement(int row, int column)
{
return(values[row][column]);
}
/**
* Modifies the value at the specified row and column of this matrix.
* @param row the row number to be modified (zero indexed)
* @param column the column number to be modified (zero indexed)
* @param value the new matrix element value
*/
public final void setElement(int row, int column, double value)
{
values[row][column] = value;
}
/**
* Places the values of the specified row into the array parameter.
* @param row the target row number
* @param array the array into which the row values will be placed
*/
public final void getRow(int row, double[] array)
{
for (int i = 0; i < nCol; i++) {
array[i] = values[row][i];
}
}
/**
* Places the values of the specified row into the vector parameter.
* @param row the target row number
* @param vector the vector into which the row values will be placed
*/
public final void getRow(int row, GVector vector)
{
if (vector.getSize() < nCol)
vector.setSize(nCol);
for (int i = 0; i < nCol; i++) {
vector.values[i] = values[row][i];
}
}
/**
* Places the values of the specified column into the array parameter.
* @param col the target column number
* @param array the array into which the column values will be placed
*/
public final void getColumn(int col, double[] array)
{
for (int i = 0; i < nRow; i++) {
array[i] = values[i][col];
}
}
/**
* Places the values of the specified column into the vector parameter.
* @param col the target column number
* @param vector the vector into which the column values will be placed
*/
public final void getColumn(int col, GVector vector)
{
if (vector.getSize() < nRow)
vector.setSize(nRow);
for (int i = 0; i < nRow; i++) {
vector.values[i] = values[i][col];
}
}
/**
* Places the values in the upper 3x3 of this GMatrix into
* the matrix m1.
* @param m1 The matrix that will hold the new values
*/
public final void get(Matrix3d m1)
{
if (nRow < 3 || nCol < 3) {
m1.setZero();
if (nCol > 0) {
if (nRow > 0){
m1.m00 = values[0][0];
if (nRow > 1){
m1.m10 = values[1][0];
if( nRow > 2 ){
m1.m20= values[2][0];
}
}
}
if (nCol > 1) {
if (nRow > 0) {
m1.m01 = values[0][1];
if (nRow > 1){
m1.m11 = values[1][1];
if (nRow > 2){
m1.m21 = values[2][1];
}
}
}
if (nCol > 2) {
if (nRow > 0) {
m1.m02 = values[0][2];
if (nRow > 1) {
m1.m12 = values[1][2];
if (nRow > 2) {
m1.m22 = values[2][2];
}
}
}
}
}
}
} else {
m1.m00 = values[0][0];
m1.m01 = values[0][1];
m1.m02 = values[0][2];
m1.m10 = values[1][0];
m1.m11 = values[1][1];
m1.m12 = values[1][2];
m1.m20 = values[2][0];
m1.m21 = values[2][1];
m1.m22 = values[2][2];
}
}
/**
* Places the values in the upper 3x3 of this GMatrix into
* the matrix m1.
* @param m1 The matrix that will hold the new values
*/
public final void get(Matrix3f m1)
{
if (nRow < 3 || nCol < 3) {
m1.setZero();
if (nCol > 0) {
if (nRow > 0) {
m1.m00 = (float)values[0][0];
if (nRow > 1) {
m1.m10 = (float)values[1][0];
if (nRow > 2) {
m1.m20 = (float)values[2][0];
}
}
}
if (nCol > 1) {
if (nRow > 0) {
m1.m01 = (float)values[0][1];
if (nRow > 1){
m1.m11 = (float)values[1][1];
if (nRow > 2){
m1.m21 = (float)values[2][1];
}
}
}
if (nCol > 2) {
if (nRow > 0) {
m1.m02 = (float)values[0][2];
if (nRow > 1) {
m1.m12 = (float)values[1][2];
if (nRow > 2) {
m1.m22 = (float)values[2][2];
}
}
}
}
}
}
} else {
m1.m00 = (float)values[0][0];
m1.m01 = (float)values[0][1];
m1.m02 = (float)values[0][2];
m1.m10 = (float)values[1][0];
m1.m11 = (float)values[1][1];
m1.m12 = (float)values[1][2];
m1.m20 = (float)values[2][0];
m1.m21 = (float)values[2][1];
m1.m22 = (float)values[2][2];
}
}
/**
* Places the values in the upper 4x4 of this GMatrix into
* the matrix m1.
* @param m1 The matrix that will hold the new values
*/
public final void get(Matrix4d m1)
{
if (nRow < 4 || nCol < 4) {
m1.setZero();
if (nCol > 0) {
if (nRow > 0) {
m1.m00 = values[0][0];
if (nRow > 1) {
m1.m10 = values[1][0];
if (nRow > 2) {
m1.m20 = values[2][0];
if (nRow > 3) {
m1.m30 = values[3][0];
}
}
}
}
if (nCol > 1) {
if (nRow > 0) {
m1.m01 = values[0][1];
if (nRow > 1) {
m1.m11 = values[1][1];
if (nRow > 2) {
m1.m21 = values[2][1];
if (nRow > 3) {
m1.m31 = values[3][1];
}
}
}
}
if (nCol > 2) {
if (nRow > 0) {
m1.m02 = values[0][2];
if (nRow > 1) {
m1.m12 = values[1][2];
if (nRow > 2) {
m1.m22 = values[2][2];
if (nRow > 3) {
m1.m32 = values[3][2];
}
}
}
}
if (nCol > 3) {
if (nRow > 0) {
m1.m03 = values[0][3];
if (nRow > 1) {
m1.m13 = values[1][3];
if (nRow > 2) {
m1.m23 = values[2][3];
if (nRow > 3) {
m1.m33 = values[3][3];
}
}
}
}
}
}
}
}
} else {
m1.m00 = values[0][0];
m1.m01 = values[0][1];
m1.m02 = values[0][2];
m1.m03 = values[0][3];
m1.m10 = values[1][0];
m1.m11 = values[1][1];
m1.m12 = values[1][2];
m1.m13 = values[1][3];
m1.m20 = values[2][0];
m1.m21 = values[2][1];
m1.m22 = values[2][2];
m1.m23 = values[2][3];
m1.m30 = values[3][0];
m1.m31 = values[3][1];
m1.m32 = values[3][2];
m1.m33 = values[3][3];
}
}
/**
* Places the values in the upper 4x4 of this GMatrix into
* the matrix m1.
* @param m1 The matrix that will hold the new values
*/
public final void get(Matrix4f m1)
{
if (nRow < 4 || nCol < 4) {
m1.setZero();
if (nCol > 0) {
if (nRow > 0) {
m1.m00 = (float)values[0][0];
if (nRow > 1) {
m1.m10 = (float)values[1][0];
if (nRow > 2) {
m1.m20 = (float)values[2][0];
if (nRow > 3) {
m1.m30 = (float)values[3][0];
}
}
}
}
if (nCol > 1) {
if (nRow > 0) {
m1.m01 = (float)values[0][1];
if (nRow > 1) {
m1.m11 = (float)values[1][1];
if (nRow > 2) {
m1.m21 = (float)values[2][1];
if (nRow > 3) {
m1.m31 = (float)values[3][1];
}
}
}
}
if (nCol > 2) {
if (nRow > 0) {
m1.m02 = (float)values[0][2];
if (nRow > 1) {
m1.m12 = (float)values[1][2];
if (nRow > 2) {
m1.m22 = (float)values[2][2];
if (nRow > 3) {
m1.m32 = (float)values[3][2];
}
}
}
}
if (nCol > 3) {
if (nRow > 0) {
m1.m03 = (float)values[0][3];
if (nRow > 1) {
m1.m13 = (float)values[1][3];
if (nRow > 2) {
m1.m23 = (float)values[2][3];
if (nRow > 3) {
m1.m33 = (float)values[3][3];
}
}
}
}
}
}
}
}
} else {
m1.m00 = (float)values[0][0];
m1.m01 = (float)values[0][1];
m1.m02 = (float)values[0][2];
m1.m03 = (float)values[0][3];
m1.m10 = (float)values[1][0];
m1.m11 = (float)values[1][1];
m1.m12 = (float)values[1][2];
m1.m13 = (float)values[1][3];
m1.m20 = (float)values[2][0];
m1.m21 = (float)values[2][1];
m1.m22 = (float)values[2][2];
m1.m23 = (float)values[2][3];
m1.m30 = (float)values[3][0];
m1.m31 = (float)values[3][1];
m1.m32 = (float)values[3][2];
m1.m33 = (float)values[3][3];
}
}
/**
* Places the values in the this GMatrix into the matrix m1;
* m1 should be at least as large as this GMatrix.
* @param m1 The matrix that will hold the new values
*/
public final void get(GMatrix m1)
{
int i, j, nc, nr;
if (nCol < m1.nCol)
nc = nCol;
else
nc = m1.nCol;
if (nRow < m1.nRow)
nr = nRow;
else
nr = m1.nRow;
for (i = 0; i < nr; i++) {
for (j = 0; j < nc; j++) {
m1.values[i][j] = values[i][j];
}
}
for (i = nr; i < m1.nRow; i++) {
for (j = 0; j < m1.nCol; j++) {
m1.values[i][j] = 0.0;
}
}
for (j = nc; j < m1.nCol; j++) {
for (i = 0; i < nr; i++) {
m1.values[i][j] = 0.0;
}
}
}
/**
* Copy the values from the array into the specified row of this
* matrix.
* @param row the row of this matrix into which the array values
* will be copied.
* @param array the source array
*/
public final void setRow(int row, double[] array)
{
for (int i = 0; i < nCol; i++) {
values[row][i] = array[i];
}
}
/**
* Copy the values from the vector into the specified row of this
* matrix.
* @param row the row of this matrix into which the array values
* will be copied
* @param vector the source vector
*/
public final void setRow(int row, GVector vector)
{
for(int i = 0; i < nCol; i++) {
values[row][i] = vector.values[i];
}
}
/**
* Copy the values from the array into the specified column of this
* matrix.
* @param col the column of this matrix into which the array values
* will be copied
* @param array the source array
*/
public final void setColumn(int col, double[] array)
{
for(int i = 0; i < nRow; i++) {
values[i][col] = array[i];
}
}
/**
* Copy the values from the vector into the specified column of this
* matrix.
* @param col the column of this matrix into which the array values
* will be copied
* @param vector the source vector
*/
public final void setColumn(int col, GVector vector)
{
for(int i = 0; i < nRow; i++) {
values[i][col] = vector.values[i];
}
}
/**
* Multiplies the transpose of matrix m1 times the transpose of matrix
* m2, and places the result into this.
* @param m1 The matrix on the left hand side of the multiplication
* @param m2 The matrix on the right hand side of the multiplication
*/
public final void mulTransposeBoth(GMatrix m1, GMatrix m2)
{
int i, j, k;
if (m1.nRow != m2.nCol || nRow != m1.nCol || nCol != m2.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix14"));
if (m1 == this || m2 == this) {
double[][] tmp = new double[nRow][nCol];
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
tmp[i][j] = 0.0;
for (k = 0; k < m1.nRow; k++) {
tmp[i][j] += m1.values[k][i]*m2.values[j][k];
}
}
}
values = tmp;
} else {
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
for (k = 0; k < m1.nRow; k++) {
values[i][j] += m1.values[k][i]*m2.values[j][k];
}
}
}
}
}
/**
* Multiplies matrix m1 times the transpose of matrix m2, and
* places the result into this.
* @param m1 The matrix on the left hand side of the multiplication
* @param m2 The matrix on the right hand side of the multiplication
*/
public final void mulTransposeRight(GMatrix m1, GMatrix m2)
{
int i, j, k;
if (m1.nCol != m2.nCol || nCol != m2.nRow || nRow != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix15"));
if (m1 == this || m2 == this) {
double[][] tmp = new double[nRow][nCol];
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
tmp[i][j] = 0.0;
for (k = 0; k < m1.nCol; k++) {
tmp[i][j] += m1.values[i][k]*m2.values[j][k];
}
}
}
values = tmp;
} else {
for (i = 0; i < nRow; i++) {
for (j = 0;j < nCol; j++) {
values[i][j] = 0.0;
for (k = 0; k < m1.nCol; k++) {
values[i][j] += m1.values[i][k]*m2.values[j][k];
}
}
}
}
}
/**
* Multiplies the transpose of matrix m1 times matrix m2, and
* places the result into this.
* @param m1 The matrix on the left hand side of the multiplication
* @param m2 The matrix on the right hand side of the multiplication
*/
public final void mulTransposeLeft(GMatrix m1, GMatrix m2)
{
int i, j, k;
if (m1.nRow != m2.nRow || nCol != m2.nCol || nRow != m1.nCol)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix16"));
if (m1 == this || m2 == this) {
double[][] tmp = new double[nRow][nCol];
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
tmp[i][j] = 0.0;
for (k = 0; k < m1.nRow; k++) {
tmp[i][j] += m1.values[k][i]*m2.values[k][j];
}
}
}
values = tmp;
} else {
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
for (k = 0; k < m1.nRow; k++) {
values[i][j] += m1.values[k][i]*m2.values[k][j];
}
}
}
}
}
/**
* Transposes this matrix in place.
*/
public final void transpose()
{
int i, j;
if (nRow != nCol) {
double[][] tmp;
i=nRow;
nRow = nCol;
nCol = i;
tmp = new double[nRow][nCol];
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
tmp[i][j] = values[j][i];
}
}
values = tmp;
} else {
double swap;
for (i = 0; i < nRow; i++) {
for (j = 0; j < i; j++) {
swap = values[i][j];
values[i][j] = values[j][i];
values[j][i] = swap;
}
}
}
}
/**
* Places the matrix values of the transpose of matrix m1 into this matrix.
* @param m1 the matrix to be transposed (but not modified)
*/
public final void transpose(GMatrix m1)
{
int i, j;
if (nRow != m1.nCol || nCol != m1.nRow)
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix17"));
if (m1 != this) {
for (i = 0; i < nRow; i++) {
for (j = 0;j < nCol; j++) {
values[i][j] = m1.values[j][i];
}
}
} else {
transpose();
}
}
/**
* Returns a string that contains the values of this GMatrix.
* @return the String representation
*/
public String toString()
{
StringBuffer buffer = new StringBuffer(nRow*nCol*8);
int i, j;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
buffer.append(values[i][j]).append(" ");
}
buffer.append("\n");
}
return buffer.toString();
}
private static void checkMatrix( GMatrix m)
{
int i, j;
for (i = 0; i < m.nRow; i++) {
for (j = 0; j < m.nCol; j++) {
if (Math.abs(m.values[i][j]) < 0.0000000001) {
System.out.print(" 0.0 ");
} else {
System.out.print(" " + m.values[i][j]);
}
}
System.out.print("\n");
}
}
/**
* Returns a hash code value based on the data values in this
* object. Two different GMatrix objects with identical data
* values (i.e., GMatrix.equals returns true) will return the
* same hash number. Two GMatrix objects with different data
* members may return the same hash value, although this is not
* likely.
* @return the integer hash code value
*/
public int hashCode() {
long bits = 1L;
bits = 31L * bits + (long)nRow;
bits = 31L * bits + (long)nCol;
for (int i = 0; i < nRow; i++) {
for (int j = 0; j < nCol; j++) {
bits = 31L * bits + VecMathUtil.doubleToLongBits(values[i][j]);
}
}
return (int) (bits ^ (bits >> 32));
}
/**
* Returns true if all of the data members of GMatrix m1 are
* equal to the corresponding data members in this GMatrix.
* @param m1 The matrix with which the comparison is made.
* @return true or false
*/
public boolean equals(GMatrix m1)
{
try {
int i, j;
if (nRow != m1.nRow || nCol != m1.nCol)
return false;
for (i = 0;i < nRow; i++) {
for (j = 0; j < nCol; j++) {
if (values[i][j] != m1.values[i][j])
return false;
}
}
return true;
}
catch (NullPointerException e2) {
return false;
}
}
/**
* Returns true if the Object o1 is of type GMatrix and all of the
* data members of o1 are equal to the corresponding data members in
* this GMatrix.
* @param o1 The object with which the comparison is made.
* @return true or false
*/
public boolean equals(Object o1)
{
try {
GMatrix m2 = (GMatrix) o1;
int i, j;
if (nRow != m2.nRow || nCol != m2.nCol)
return false;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
if (values[i][j] != m2.values[i][j])
return false;
}
}
return true;
}
catch (ClassCastException e1) {
return false;
}
catch (NullPointerException e2) {
return false;
}
}
/**
* @deprecated Use epsilonEquals(GMatrix, double) instead
*/
public boolean epsilonEquals(GMatrix m1, float epsilon) {
return epsilonEquals(m1, (double)epsilon);
}
/**
* Returns true if the L-infinite distance between this matrix
* and matrix m1 is less than or equal to the epsilon parameter,
* otherwise returns false. The L-infinite
* distance is equal to
* MAX[i=0,1,2, . . .n ; j=0,1,2, . . .n ; abs(this.m(i,j) - m1.m(i,j)]
* @param m1 The matrix to be compared to this matrix
* @param epsilon the threshold value
*/
public boolean epsilonEquals(GMatrix m1, double epsilon)
{
int i, j;
double diff;
if (nRow != m1.nRow || nCol != m1.nCol)
return false;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
diff = values[i][j] - m1.values[i][j];
if ((diff < 0 ? -diff : diff) > epsilon)
return false;
}
}
return true;
}
/**
* Returns the trace of this matrix.
* @return the trace of this matrix
*/
public final double trace()
{
int i, l;
double t;
if (nRow < nCol)
l = nRow;
else
l = nCol;
t = 0.0;
for (i = 0; i < l; i++) {
t += values[i][i];
}
return t;
}
/**
* Finds the singular value decomposition (SVD) of this matrix
* such that this = U*W*transpose(V); and returns the rank of
* this matrix; the values of U,W,V are all overwritten. Note
* that the matrix V is output as V, and
* not transpose(V). If this matrix is mxn, then U is mxm, W
* is a diagonal matrix that is mxn, and V is nxn. Using the
* notation W = diag(w), then the inverse of this matrix is:
* inverse(this) = V*diag(1/w)*tranpose(U), where diag(1/w)
* is the same matrix as W except that the reciprocal of each
* of the diagonal components is used.
* @param U The computed U matrix in the equation this = U*W*transpose(V)
* @param W The computed W matrix in the equation this = U*W*transpose(V)
* @param V The computed V matrix in the equation this = U*W*transpose(V)
* @return The rank of this matrix.
*/
public final int SVD(GMatrix U, GMatrix W, GMatrix V)
{
// check for consistancy in dimensions
if (nCol != V.nCol || nCol != V.nRow) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix18"));
}
if (nRow != U.nRow || nRow != U.nCol) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix25"));
}
if (nRow != W.nRow || nCol != W.nCol) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix26"));
}
// Fix ArrayIndexOutOfBounds for 2x2 matrices, which partially
// addresses bug 4348562 for J3D 1.2.1.
//
// Does *not* fix the following problems reported in 4348562,
// which will wait for J3D 1.3:
//
// 1) no output of W
// 2) wrong transposition of U
// 3) wrong results for 4x4 matrices
// 4) slow performance
if (nRow == 2 && nCol == 2) {
if (values[1][0] == 0.0) {
U.setIdentity();
V.setIdentity();
if (values[0][1] == 0.0) {
return 2;
}
double[] sinl = new double[1];
double[] sinr = new double[1];
double[] cosl = new double[1];
double[] cosr = new double[1];
double[] single_values = new double[2];
single_values[0] = values[0][0];
single_values[1] = values[1][1];
compute_2X2(values[0][0], values[0][1], values[1][1],
single_values, sinl, cosl, sinr, cosr, 0);
update_u(0, U, cosl, sinl);
update_v(0, V, cosr, sinr);
return 2;
}
// else call computeSVD() and check for 2x2 there
}
return computeSVD(this, U, W, V);
}
/**
* LU Decomposition: this matrix must be a square matrix and the
* LU GMatrix parameter must be the same size as this matrix.
* The matrix LU will be overwritten as the combination of a
* lower diagonal and upper diagonal matrix decompostion of this
* matrix; the diagonal
* elements of L (unity) are not stored. The GVector parameter
* records the row permutation effected by the partial pivoting,
* and is used as a parameter to the GVector method LUDBackSolve
* to solve sets of linear equations.
* This method returns +/- 1 depending on whether the number
* of row interchanges was even or odd, respectively.
* @param LU The matrix into which the lower and upper decompositions
* will be placed.
* @param permutation The row permutation effected by the partial
* pivoting
* @return +-1 depending on whether the number of row interchanges
* was even or odd respectively
*/
public final int LUD(GMatrix LU, GVector permutation)
{
int size = LU.nRow*LU.nCol;
double[] temp = new double[size];
int[] even_row_exchange = new int[1];
int[] row_perm = new int[LU.nRow];
int i, j;
if (nRow != nCol) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix19"));
}
if (nRow != LU.nRow) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix27"));
}
if (nCol != LU.nCol) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix27"));
}
if (LU.nRow != permutation.getSize()) {
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix20"));
}
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
temp[i*nCol+j] = values[i][j];
}
}
// Calculate LU decomposition: Is the matrix singular?
if (!luDecomposition(LU.nRow, temp, row_perm, even_row_exchange)) {
// Matrix has no inverse
throw new SingularMatrixException
(VecMathI18N.getString("GMatrix21"));
}
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
LU.values[i][j] = temp[i*nCol+j];
}
}
for (i = 0; i < LU.nRow; i++){
permutation.values[i] = (double)row_perm[i];
}
return even_row_exchange[0];
}
/**
* Sets this matrix to a uniform scale matrix; all of the
* values are reset.
* @param scale The new scale value
*/
public final void setScale(double scale)
{
int i, j, l;
if (nRow < nCol)
l = nRow;
else
l = nCol;
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = 0.0;
}
}
for (i = 0; i < l; i++) {
values[i][i] = scale;
}
}
/**
* General invert routine. Inverts m1 and places the result in "this".
* Note that this routine handles both the "this" version and the
* non-"this" version.
*
* Also note that since this routine is slow anyway, we won't worry
* about allocating a little bit of garbage.
*/
final void invertGeneral(GMatrix m1) {
int size = m1.nRow*m1.nCol;
double temp[] = new double[size];
double result[] = new double[size];
int row_perm[] = new int[m1.nRow];
int[] even_row_exchange = new int[1];
int i, j;
// Use LU decomposition and backsubstitution code specifically
// for floating-point nxn matrices.
if (m1.nRow != m1.nCol) {
// Matrix is either under or over determined
throw new MismatchedSizeException
(VecMathI18N.getString("GMatrix22"));
}
// Copy source matrix to temp
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
temp[i*nCol+j] = m1.values[i][j];
}
}
// Calculate LU decomposition: Is the matrix singular?
if (!luDecomposition(m1.nRow, temp, row_perm, even_row_exchange)) {
// Matrix has no inverse
throw new SingularMatrixException
(VecMathI18N.getString("GMatrix21"));
}
// Perform back substitution on the identity matrix
for (i = 0; i < size; i++)
result[i] = 0.0;
for (i = 0; i < nCol; i++)
result[i+i*nCol] = 1.0;
luBacksubstitution(m1.nRow, temp, row_perm, result);
for (i = 0; i < nRow; i++) {
for (j = 0; j < nCol; j++) {
values[i][j] = result[i*nCol+j];
}
}
}
/**
* Given a nxn array "matrix0", this function replaces it with the
* LU decomposition of a row-wise permutation of itself. The input
* parameters are "matrix0" and "dim". The array "matrix0" is also
* an output parameter. The vector "row_perm[]" is an output
* parameter that contains the row permutations resulting from partial
* pivoting. The output parameter "even_row_xchg" is 1 when the
* number of row exchanges is even, or -1 otherwise. Assumes data
* type is always double.
*
* @return true if the matrix is nonsingular, or false otherwise.
*/
//
// Reference: Press, Flannery, Teukolsky, Vetterling,
// _Numerical_Recipes_in_C_, Cambridge University Press,
// 1988, pp 40-45.
//
static boolean luDecomposition(int dim, double[] matrix0,
int[] row_perm, int[] even_row_xchg) {
double row_scale[] = new double[dim];
// Determine implicit scaling information by looping over rows
int i, j;
int ptr, rs, mtx;
double big, temp;
ptr = 0;
rs = 0;
even_row_xchg[0] = 1;
// For each row ...
i = dim;
while (i-- != 0) {
big = 0.0;
// For each column, find the largest element in the row
j = dim;
while (j-- != 0) {
temp = matrix0[ptr++];
temp = Math.abs(temp);
if (temp > big) {
big = temp;
}
}
// Is the matrix singular?
if (big == 0.0) {
return false;
}
row_scale[rs++] = 1.0 / big;
}
// For all columns, execute Crout's method
mtx = 0;
for (j = 0; j < dim; j++) {
int imax, k;
int target, p1, p2;
double sum;
// Determine elements of upper diagonal matrix U
for (i = 0; i < j; i++) {
target = mtx + (dim*i) + j;
sum = matrix0[target];
k = i;
p1 = mtx + (dim*i);
p2 = mtx + j;
while (k-- != 0) {
sum -= matrix0[p1] * matrix0[p2];
p1++;
p2 += dim;
}
matrix0[target] = sum;
}
// Search for largest pivot element and calculate
// intermediate elements of lower diagonal matrix L.
big = 0.0;
imax = -1;
for (i = j; i < dim; i++) {
target = mtx + (dim*i) + j;
sum = matrix0[target];
k = j;
p1 = mtx + (dim*i);
p2 = mtx + j;
while (k-- != 0) {
sum -= matrix0[p1] * matrix0[p2];
p1++;
p2 += dim;
}
matrix0[target] = sum;
// Is this the best pivot so far?
if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
big = temp;
imax = i;
}
}
if (imax < 0) {
throw new RuntimeException(VecMathI18N.getString("GMatrix24"));
}
// Is a row exchange necessary?
if (j != imax) {
// Yes: exchange rows
k = dim;
p1 = mtx + (dim*imax);
p2 = mtx + (dim*j);
while (k-- != 0) {
temp = matrix0[p1];
matrix0[p1++] = matrix0[p2];
matrix0[p2++] = temp;
}
// Record change in scale factor
row_scale[imax] = row_scale[j];
even_row_xchg[0] = -even_row_xchg[0]; // change exchange parity
}
// Record row permutation
row_perm[j] = imax;
// Is the matrix singular
if (matrix0[(mtx + (dim*j) + j)] == 0.0) {
return false;
}
// Divide elements of lower diagonal matrix L by pivot
if (j != (dim-1)) {
temp = 1.0 / (matrix0[(mtx + (dim*j) + j)]);
target = mtx + (dim*(j+1)) + j;
i = (dim-1) - j;
while (i-- != 0) {
matrix0[target] *= temp;
target += dim;
}
}
}
return true;
}
/**
* Solves a set of linear equations. The input parameters "matrix1",
* and "row_perm" come from luDecompostion and do not change
* here. The parameter "matrix2" is a set of column vectors assembled
* into a nxn matrix of floating-point values. The procedure takes each
* column of "matrix2" in turn and treats it as the right-hand side of the
* matrix equation Ax = LUx = b. The solution vector replaces the
* original column of the matrix.
*
* If "matrix2" is the identity matrix, the procedure replaces its contents
* with the inverse of the matrix from which "matrix1" was originally
* derived.
*/
//
// Reference: Press, Flannery, Teukolsky, Vetterling,
// _Numerical_Recipes_in_C_, Cambridge University Press,
// 1988, pp 44-45.
//
static void luBacksubstitution(int dim, double[] matrix1,
int[] row_perm,
double[] matrix2) {
int i, ii, ip, j, k;
int rp;
int cv, rv, ri;
double tt;
// rp = row_perm;
rp = 0;
// For each column vector of matrix2 ...
for (k = 0; k < dim; k++) {
// cv = &(matrix2[0][k]);
cv = k;
ii = -1;
// Forward substitution
for (i = 0; i < dim; i++) {
double sum;
ip = row_perm[rp+i];
sum = matrix2[cv+dim*ip];
matrix2[cv+dim*ip] = matrix2[cv+dim*i];
if (ii >= 0) {
// rv = &(matrix1[i][0]);
rv = i*dim;
for (j = ii; j <= i-1; j++) {
sum -= matrix1[rv+j] * matrix2[cv+dim*j];
}
}
else if (sum != 0.0) {
ii = i;
}
matrix2[cv+dim*i] = sum;
}
// Backsubstitution
for (i = 0; i < dim; i++) {
ri = (dim-1-i);
rv = dim*(ri);
tt = 0.0;
for(j=1;j<=i;j++) {
tt += matrix1[rv+dim-j] * matrix2[cv+dim*(dim-j)];
}
matrix2[cv+dim*ri]= (matrix2[cv+dim*ri] - tt) / matrix1[rv+ri];
}
}
}
static int computeSVD(GMatrix mat, GMatrix U, GMatrix W, GMatrix V) {
int i, j, k;
int nr, nc, si;
int converged, rank;
double cs, sn, r, mag,scale, t;
int eLength, sLength, vecLength;
GMatrix tmp = new GMatrix(mat.nRow, mat.nCol);
GMatrix u = new GMatrix(mat.nRow, mat.nCol);
GMatrix v = new GMatrix(mat.nRow, mat.nCol);
GMatrix m = new GMatrix(mat);
// compute the number of singular values
if (m.nRow >= m.nCol) {
sLength = m.nCol;
eLength = m.nCol-1;
}else {
sLength = m.nRow;
eLength = m.nRow;
}
if (m.nRow > m.nCol)
vecLength = m.nRow;
else
vecLength = m.nCol;
double[] vec = new double[vecLength];
double[] single_values = new double[sLength];
double[] e = new double[eLength];
if(debug) {
System.out.println("input to compute_svd = \n"+m.toString());
}
rank = 0;
U.setIdentity();
V.setIdentity();
nr = m.nRow;
nc = m.nCol;
// householder reduction
for (si = 0; si < sLength; si++) {
// for each singular value
if (nr > 1) {
// zero out column
if (debug)
System.out.println
("*********************** U ***********************\n");
// compute reflector
mag = 0.0;
for (i = 0; i < nr; i++) {
mag += m.values[i+si][si] * m.values[i+si][si];
if (debug)
System.out.println
("mag = " + mag + " matrix.dot = " +
m.values[i+si][si] * m.values[i+si][si]);
}
mag = Math.sqrt(mag);
if (m.values[si][si] == 0.0) {
vec[0] = mag;
} else {
vec[0] = m.values[si][si] + d_sign(mag, m.values[si][si]);
}
for (i = 1; i < nr; i++) {
vec[i] = m.values[si+i][si];
}
scale = 0.0;
for (i = 0; i < nr; i++) {
if (debug)
System.out.println("vec["+i+"]="+vec[i]);
scale += vec[i]*vec[i];
}
scale = 2.0/scale;
if (debug)
System.out.println("scale = "+scale);
for (j = si; j < m.nRow; j++) {
for (k = si; k < m.nRow; k++) {
u.values[j][k] = -scale * vec[j-si]*vec[k-si];
}
}
for (i = si; i < m.nRow; i++){
u.values[i][i] += 1.0;
}
// compute s
t = 0.0;
for (i = si; i < m.nRow; i++){
t += u.values[si][i] * m.values[i][si];
}
m.values[si][si] = t;
// apply reflector
for (j = si; j < m.nRow; j++) {
for (k = si+1; k < m.nCol; k++) {
tmp.values[j][k] = 0.0;
for (i = si; i < m.nCol; i++) {
tmp.values[j][k] += u.values[j][i] * m.values[i][k];
}
}
}
for (j = si; j < m.nRow; j++) {
for (k = si+1; k < m.nCol; k++) {
m.values[j][k] = tmp.values[j][k];
}
}
if (debug) {
System.out.println("U =\n" + U.toString());
System.out.println("u =\n" + u.toString());
}
// update U matrix
for (j = si; j < m.nRow; j++) {
for (k = 0; k < m.nCol; k++) {
tmp.values[j][k] = 0.0;
for (i = si; i < m.nCol; i++) {
tmp.values[j][k] += u.values[j][i] * U.values[i][k];
}
}
}
for (j = si; j < m.nRow; j++) {
for (k = 0; k < m.nCol; k++) {
U.values[j][k] = tmp.values[j][k];
}
}
if (debug) {
System.out.println("single_values["+si+"] =\n" +
single_values[si]);
System.out.println("m =\n" + m.toString());
System.out.println("U =\n" + U.toString());
}
nr--;
}
if( nc > 2 ) {
// zero out row
if (debug)
System.out.println
("*********************** V ***********************\n");
mag = 0.0;
for (i = 1; i < nc; i++){
mag += m.values[si][si+i] * m.values[si][si+i];
}
if (debug)
System.out.println("mag = " + mag);
// generate the reflection vector, compute the first entry and
// copy the rest from the row to be zeroed
mag = Math.sqrt(mag);
if (m.values[si][si+1] == 0.0) {
vec[0] = mag;
} else {
vec[0] = m.values[si][si+1] +
d_sign(mag, m.values[si][si+1]);
}
for (i = 1; i < nc - 1; i++){
vec[i] = m.values[si][si+i+1];
}
// use reflection vector to compute v matrix
scale = 0.0;
for (i = 0; i < nc - 1; i++){
if( debug )System.out.println("vec["+i+"]="+vec[i]);
scale += vec[i]*vec[i];
}
scale = 2.0/scale;
if (debug)
System.out.println("scale = "+scale);
for (j = si + 1; j < nc; j++) {
for (k = si+1; k < m.nCol; k++) {
v.values[j][k] = -scale * vec[j-si-1]*vec[k-si-1];
}
}
for (i = si + 1; i < m.nCol; i++){
v.values[i][i] += 1.0;
}
t=0.0;
for (i = si; i < m.nCol; i++){
t += v.values[i][si+1] * m.values[si][i];
}
m.values[si][si+1]=t;
// apply reflector
for (j = si + 1; j < m.nRow; j++) {
for (k = si + 1; k < m.nCol; k++) {
tmp.values[j][k] = 0.0;
for (i = si + 1; i < m.nCol; i++) {
tmp.values[j][k] += v.values[i][k] * m.values[j][i];
}
}
}
for (j = si + 1; j < m.nRow; j++) {
for (k = si + 1; k < m.nCol; k++) {
m.values[j][k] = tmp.values[j][k];
}
}
if (debug) {
System.out.println("V =\n" + V.toString());
System.out.println("v =\n" + v.toString());
System.out.println("tmp =\n" + tmp.toString());
}
// update V matrix
for (j = 0; j < m.nRow; j++) {
for (k = si + 1; k < m.nCol; k++) {
tmp.values[j][k] = 0.0;
for (i = si + 1; i < m.nCol; i++) {
tmp.values[j][k] += v.values[i][k] * V.values[j][i];
}
}
}
if (debug)
System.out.println("tmp =\n" + tmp.toString());
for (j = 0;j < m.nRow; j++) {
for (k = si + 1; k < m.nCol; k++) {
V.values[j][k] = tmp.values[j][k];
}
}
if (debug) {
System.out.println("m =\n" + m.toString());
System.out.println("V =\n" + V.toString());
}
nc--;
}
}
for (i = 0; i < sLength; i++){
single_values[i] = m.values[i][i];
}
for (i = 0; i < eLength; i++){
e[i] = m.values[i][i+1];
}
// Fix ArrayIndexOutOfBounds for 2x2 matrices, which partially
// addresses bug 4348562 for J3D 1.2.1.
//
// Does *not* fix the following problems reported in 4348562,
// which will wait for J3D 1.3:
//
// 1) no output of W
// 2) wrong transposition of U
// 3) wrong results for 4x4 matrices
// 4) slow performance
if (m.nRow == 2 && m.nCol == 2) {
double[] cosl = new double[1];
double[] cosr = new double[1];
double[] sinl = new double[1];
double[] sinr = new double[1];
compute_2X2(single_values[0], e[0], single_values[1],
single_values, sinl, cosl, sinr, cosr, 0);
update_u(0, U, cosl, sinl);
update_v(0, V, cosr, sinr);
return 2;
}
// compute_qr causes ArrayIndexOutOfBounds for 2x2 matrices
compute_qr (0, e.length-1, single_values, e, U, V);
// compute rank = number of non zero singular values
rank = single_values.length;
// sort by order of size of single values
// and check for zero's
return rank;
}
static void compute_qr(int start, int end, double[] s, double[] e,
GMatrix u, GMatrix v) {
int i, j, k, n, sl;
boolean converged;
double shift, r, utemp, vtemp, f, g;
double[] cosl = new double[1];
double[] cosr = new double[1];
double[] sinl = new double[1];
double[] sinr = new double[1];
GMatrix m = new GMatrix(u.nCol, v.nRow);
final int MAX_INTERATIONS = 2;
final double CONVERGE_TOL = 4.89E-15;
if (debug) {
System.out.println("start =" + start);
System.out.println("s =\n");
for(i=0;i 1) && (Math.abs(e[end]) < CONVERGE_TOL)) {
end--;
}
// check if need to split
for (n = end - 2; n > start; n--) {
if (Math.abs(e[n]) < CONVERGE_TOL) { // split
compute_qr(n + 1, end, s, e, u, v); // do lower matrix
end = n - 1; // do upper matrix
// check for convergence on off diagonals and reduce
while ((end - start > 1) &&
(Math.abs(e[end]) < CONVERGE_TOL)) {
end--;
}
}
}
if (debug)
System.out.println("start = " + start);
if ((end - start <= 1) && (Math.abs(e[start+1]) < CONVERGE_TOL)) {
converged = true;
} else {
// check if zero on the diagonal
}
}
if (debug)
System.out.println("\n****call compute_2X2 ********************\n");
if (Math.abs(e[1]) < CONVERGE_TOL) {
compute_2X2(s[start], e[start], s[start+1], s,
sinl, cosl, sinr, cosr, 0);
e[start] = 0.0;
e[start+1] = 0.0;
} else {
}
i = start;
update_u(i, u, cosl, sinl);
update_v(i, v, cosr, sinr);
if(debug) {
System.out.println
("\n*******after call compute_2X2 **********************\n");
print_svd(s, e, u, v);
}
return;
}
private static void print_se(double[] s, double[] e) {
System.out.println("\ns =" + s[0] + " " + s[1] + " " + s[2]);
System.out.println("e =" + e[0] + " " + e[1]);
}
private static void update_v(int index, GMatrix v,
double[] cosr, double[] sinr) {
int j;
double vtemp;
for (j = 0; j < v.nRow; j++) {
vtemp = v.values[j][index];
v.values[j][index] =
cosr[0]*vtemp + sinr[0]*v.values[j][index+1];
v.values[j][index+1] =
-sinr[0]*vtemp + cosr[0]*v.values[j][index+1];
}
}
private static void chase_up(double[] s, double[] e, int k, GMatrix v) {
double f, g, r;
double[] cosr = new double[1];
double[] sinr = new double[1];
int i;
GMatrix t = new GMatrix(v.nRow, v.nCol);
GMatrix m = new GMatrix(v.nRow, v.nCol);
if (debug) {
m.setIdentity();
for (i = 0; i < s.length; i++) {
m.values[i][i] = s[i];
}
for (i = 0; i < e.length; i++) {
m.values[i][i+1] = e[i];
}
}
f = e[k];
g = s[k];
for (i = k; i > 0; i--) {
r = compute_rot(f, g, sinr, cosr);
f = -e[i-1] * sinr[0];
g = s[i-1];
s[i] = r;
e[i-1] = e[i-1] * cosr[0];
update_v_split(i, k+1, v, cosr, sinr, t, m);
}
s[i+1] = compute_rot(f, g, sinr, cosr);
update_v_split(i, k+1, v, cosr, sinr, t, m);
}
private static void chase_across(double[] s, double[] e, int k, GMatrix u) {
double f, g, r;
double[] cosl = new double[1];
double[] sinl = new double[1];
int i;
GMatrix t = new GMatrix(u.nRow, u.nCol);
GMatrix m = new GMatrix(u.nRow, u.nCol);
if (debug) {
m.setIdentity();
for (i = 0; i < s.length; i++) {
m.values[i][i] = s[i];
}
for (i = 0; i < e.length; i++) {
m.values[i][i+1] = e[i];
}
}
g = e[k];
f = s[k+1];
for (i = k; i < u.nCol-2; i++){
r = compute_rot(f, g, sinl, cosl);
g = -e[i+1] * sinl[0];
f = s[i+2];
s[i+1] = r;
e[i+1] = e[i+1] * cosl[0];
update_u_split(k, i + 1, u, cosl, sinl, t, m);
}
s[i+1] = compute_rot(f, g, sinl, cosl);
update_u_split(k, i + 1, u, cosl, sinl, t, m);
}
private static void update_v_split(int topr, int bottomr, GMatrix v,
double[] cosr, double[] sinr,
GMatrix t, GMatrix m) {
int j;
double vtemp;
for (j = 0; j < v.nRow; j++) {
vtemp = v.values[j][topr];
v.values[j][topr] = cosr[0]*vtemp - sinr[0]*v.values[j][bottomr];
v.values[j][bottomr] = sinr[0]*vtemp + cosr[0]*v.values[j][bottomr];
}
if (debug) {
t.setIdentity();
for (j = 0; j < v.nRow; j++) {
vtemp = t.values[j][topr];
t.values[j][topr] =
cosr[0]*vtemp - sinr[0]*t.values[j][bottomr];
t.values[j][bottomr] =
sinr[0]*vtemp + cosr[0]*t.values[j][bottomr];
}
}
System.out.println("topr =" + topr);
System.out.println("bottomr =" + bottomr);
System.out.println("cosr =" + cosr[0]);
System.out.println("sinr =" + sinr[0]);
System.out.println("\nm =");
checkMatrix(m);
System.out.println("\nv =");
checkMatrix(t);
m.mul(m,t);
System.out.println("\nt*m =");
checkMatrix(m);
}
private static void update_u_split(int topr, int bottomr, GMatrix u,
double[] cosl, double[] sinl,
GMatrix t, GMatrix m) {
int j;
double utemp;
for (j = 0; j < u.nCol; j++) {
utemp = u.values[topr][j];
u.values[topr][j] = cosl[0]*utemp - sinl[0]*u.values[bottomr][j];
u.values[bottomr][j] = sinl[0]*utemp + cosl[0]*u.values[bottomr][j];
}
if(debug) {
t.setIdentity();
for (j = 0;j < u.nCol; j++) {
utemp = t.values[topr][j];
t.values[topr][j] =
cosl[0]*utemp - sinl[0]*t.values[bottomr][j];
t.values[bottomr][j] =
sinl[0]*utemp + cosl[0]*t.values[bottomr][j];
}
}
System.out.println("\nm=");
checkMatrix(m);
System.out.println("\nu=");
checkMatrix(t);
m.mul(t,m);
System.out.println("\nt*m=");
checkMatrix(m);
}
private static void update_u(int index, GMatrix u,
double[] cosl, double[] sinl) {
int j;
double utemp;
for (j = 0; j < u.nCol; j++) {
utemp = u.values[index][j];
u.values[index][j] =
cosl[0]*utemp + sinl[0]*u.values[index+1][j];
u.values[index+1][j] =
-sinl[0]*utemp + cosl[0]*u.values[index+1][j];
}
}
private static void print_m(GMatrix m, GMatrix u, GMatrix v) {
GMatrix mtmp = new GMatrix(m.nCol, m.nRow);
mtmp.mul(u, mtmp);
mtmp.mul(mtmp, v);
System.out.println("\n m = \n" + mtmp.toString(mtmp));
}
private static String toString(GMatrix m)
{
StringBuffer buffer = new StringBuffer(m.nRow * m.nCol * 8);
int i, j;
for (i = 0; i < m.nRow; i++) {
for(j = 0; j < m.nCol; j++) {
if (Math.abs(m.values[i][j]) < .000000001) {
buffer.append("0.0000 ");
} else {
buffer.append(m.values[i][j]).append(" ");
}
}
buffer.append("\n");
}
return buffer.toString();
}
private static void print_svd(double[] s, double[] e,
GMatrix u, GMatrix v) {
int i;
GMatrix mtmp = new GMatrix(u.nCol, v.nRow);
System.out.println(" \ns = ");
for (i = 0; i < s.length; i++) {
System.out.println(" " + s[i]);
}
System.out.println(" \ne = ");
for (i = 0; i < e.length; i++) {
System.out.println(" " + e[i]);
}
System.out.println(" \nu = \n" + u.toString());
System.out.println(" \nv = \n" + v.toString());
mtmp.setIdentity();
for (i = 0; i < s.length; i++) {
mtmp.values[i][i] = s[i];
}
for (i = 0; i < e.length; i++) {
mtmp.values[i][i+1] = e[i];
}
System.out.println(" \nm = \n"+mtmp.toString());
mtmp.mulTransposeLeft(u, mtmp);
mtmp.mulTransposeRight(mtmp, v);
System.out.println(" \n u.transpose*m*v.transpose = \n" +
mtmp.toString());
}
static double max(double a, double b) {
if (a > b)
return a;
else
return b;
}
static double min(double a, double b) {
if (a < b)
return a;
else
return b;
}
static double compute_shift(double f, double g, double h) {
double d__1, d__2;
double fhmn, fhmx, c, fa, ga, ha, as, at, au;
double ssmin;
fa = Math.abs(f);
ga = Math.abs(g);
ha = Math.abs(h);
fhmn = min(fa,ha);
fhmx = max(fa,ha);
if (fhmn == 0.0) {
ssmin = 0.0;
if (fhmx == 0.0) {
} else {
d__1 = min(fhmx,ga) / max(fhmx,ga);
}
} else {
if (ga < fhmx) {
as = fhmn / fhmx + 1.0;
at = (fhmx - fhmn) / fhmx;
d__1 = ga / fhmx;
au = d__1 * d__1;
c = 2.0 / (Math.sqrt(as * as + au) + Math.sqrt(at * at + au));
ssmin = fhmn * c;
} else {
au = fhmx / ga;
if (au == 0.0) {
ssmin = fhmn * fhmx / ga;
} else {
as = fhmn / fhmx + 1.0;
at = (fhmx - fhmn) / fhmx;
d__1 = as * au;
d__2 = at * au;
c = 1.0 / (Math.sqrt(d__1 * d__1 + 1.0) +
Math.sqrt(d__2 * d__2 + 1.0));
ssmin = fhmn * c * au;
ssmin += ssmin;
}
}
}
return ssmin;
}
static int compute_2X2(double f, double g, double h,
double[] single_values, double[] snl, double[] csl,
double[] snr, double[] csr, int index) {
double c_b3 = 2.0;
double c_b4 = 1.0;
double d__1;
int pmax;
double temp;
boolean swap;
double a, d, l, m, r, s, t, tsign, fa, ga, ha;
double ft, gt, ht, mm;
boolean gasmal;
double tt, clt, crt, slt, srt;
double ssmin,ssmax;
ssmax = single_values[0];
ssmin = single_values[1];
clt = 0.0;
crt = 0.0;
slt = 0.0;
srt = 0.0;
tsign = 0.0;
ft = f;
fa = Math.abs(ft);
ht = h;
ha = Math.abs(h);
pmax = 1;
if (ha > fa)
swap = true;
else
swap = false;
if (swap) {
pmax = 3;
temp = ft;
ft = ht;
ht = temp;
temp = fa;
fa = ha;
ha = temp;
}
gt = g;
ga = Math.abs(gt);
if (ga == 0.0) {
single_values[1] = ha;
single_values[0] = fa;
clt = 1.0;
crt = 1.0;
slt = 0.0;
srt = 0.0;
} else {
gasmal = true;
if (ga > fa) {
pmax = 2;
if (fa / ga < EPS) {
gasmal = false;
ssmax = ga;
if (ha > 1.0) {
ssmin = fa / (ga / ha);
} else {
ssmin = fa / ga * ha;
}
clt = 1.0;
slt = ht / gt;
srt = 1.0;
crt = ft / gt;
}
}
if (gasmal) {
d = fa - ha;
if (d == fa) {
l = 1.0;
} else {
l = d / fa;
}
m = gt / ft;
t = 2.0 - l;
mm = m * m;
tt = t * t;
s = Math.sqrt(tt + mm);
if (l == 0.0) {
r = Math.abs(m);
} else {
r = Math.sqrt(l * l + mm);
}
a = (s + r) * 0.5;
if (ga > fa) {
pmax = 2;
if (fa / ga < EPS) {
gasmal = false;
ssmax = ga;
if (ha > 1.0) {
ssmin = fa / (ga / ha);
} else {
ssmin = fa / ga * ha;
}
clt = 1.0;
slt = ht / gt;
srt = 1.0;
crt = ft / gt;
}
}
if (gasmal) {
d = fa - ha;
if (d == fa) {
l = 1.0;
} else {
l = d / fa;
}
m = gt / ft;
t = 2.0 - l;
mm = m * m;
tt = t * t;
s = Math.sqrt(tt + mm);
if (l == 0.) {
r = Math.abs(m);
} else {
r = Math.sqrt(l * l + mm);
}
a = (s + r) * 0.5;
ssmin = ha / a;
ssmax = fa * a;
if (mm == 0.0) {
if (l == 0.0) {
t = d_sign(c_b3, ft) * d_sign(c_b4, gt);
} else {
t = gt / d_sign(d, ft) + m / t;
}
} else {
t = (m / (s + t) + m / (r + l)) * (a + 1.0);
}
l = Math.sqrt(t * t + 4.0);
crt = 2.0 / l;
srt = t / l;
clt = (crt + srt * m) / a;
slt = ht / ft * srt / a;
}
}
if (swap) {
csl[0] = srt;
snl[0] = crt;
csr[0] = slt;
snr[0] = clt;
} else {
csl[0] = clt;
snl[0] = slt;
csr[0] = crt;
snr[0] = srt;
}
if (pmax == 1) {
tsign = d_sign(c_b4, csr[0]) *
d_sign(c_b4, csl[0]) * d_sign(c_b4, f);
}
if (pmax == 2) {
tsign = d_sign(c_b4, snr[0]) *
d_sign(c_b4, csl[0]) * d_sign(c_b4, g);
}
if (pmax == 3) {
tsign = d_sign(c_b4, snr[0]) *
d_sign(c_b4, snl[0]) * d_sign(c_b4, h);
}
single_values[index] = d_sign(ssmax, tsign);
d__1 = tsign * d_sign(c_b4, f) * d_sign(c_b4, h);
single_values[index+1] = d_sign(ssmin, d__1);
}
return 0;
}
static double compute_rot(double f, double g, double[] sin, double[] cos) {
int i__1;
double d__1, d__2;
double cs, sn;
int i;
double scale;
int count;
double f1, g1;
double r;
final double safmn2 = 2.002083095183101E-146;
final double safmx2 = 4.994797680505588E+145;
if (g == 0.0) {
cs = 1.0;
sn = 0.0;
r = f;
} else if (f == 0.0) {
cs = 0.0;
sn = 1.0;
r = g;
} else {
f1 = f;
g1 = g;
scale = max(Math.abs(f1),Math.abs(g1));
if (scale >= safmx2) {
count = 0;
while(scale >= safmx2) {
++count;
f1 *= safmn2;
g1 *= safmn2;
scale = max(Math.abs(f1), Math.abs(g1));
}
r = Math.sqrt(f1*f1 + g1*g1);
cs = f1 / r;
sn = g1 / r;
i__1 = count;
for (i = 1; i <= count; ++i) {
r *= safmx2;
}
} else if (scale <= safmn2) {
count = 0;
while(scale <= safmn2) {
++count;
f1 *= safmx2;
g1 *= safmx2;
scale = max(Math.abs(f1), Math.abs(g1));
}
r = Math.sqrt(f1*f1 + g1*g1);
cs = f1 / r;
sn = g1 / r;
i__1 = count;
for (i = 1; i <= count; ++i) {
r *= safmn2;
}
} else {
r = Math.sqrt(f1*f1 + g1*g1);
cs = f1 / r;
sn = g1 / r;
}
if (Math.abs(f) > Math.abs(g) && cs < 0.0) {
cs = -cs;
sn = -sn;
r = -r;
}
}
sin[0] = sn;
cos[0] = cs;
return r;
}
static double d_sign(double a, double b) {
double x;
x = (a >= 0 ? a : - a);
return (b >= 0 ? x : -x);
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError if there is not enough memory.
* @see java.lang.Cloneable
* @since vecmath 1.3
*/
public Object clone() {
GMatrix m1 = null;
try {
m1 = (GMatrix)super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
// Also need to clone array of values
m1.values = new double[nRow][nCol];
for (int i = 0; i < nRow; i++) {
for(int j = 0; j < nCol; j++) {
m1.values[i][j] = values[i][j];
}
}
return m1;
}
}
source-cvs/vecmath/src/javax/vecmath/Quat4f.java 0000644 0001750 0001750 00000040735 10761613452 021226 0 ustar jonny jonny /*
* $RCSfile: Quat4f.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.6 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A 4 element unit quaternion represented by single precision floating
* point x,y,z,w coordinates. The quaternion is always normalized.
*
*/
public class Quat4f extends Tuple4f implements java.io.Serializable {
// Combatible with 1.1
static final long serialVersionUID = 2675933778405442383L;
final static double EPS = 0.000001;
final static double EPS2 = 1.0e-30;
final static double PIO2 = 1.57079632679;
/**
* Constructs and initializes a Quat4f from the specified xyzw coordinates.
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @param w the w scalar component
*/
public Quat4f(float x, float y, float z, float w)
{
float mag;
mag = (float)(1.0/Math.sqrt( x*x + y*y + z*z + w*w ));
this.x = x*mag;
this.y = y*mag;
this.z = z*mag;
this.w = w*mag;
}
/**
* Constructs and initializes a Quat4f from the array of length 4.
* @param q the array of length 4 containing xyzw in order
*/
public Quat4f(float[] q)
{
float mag;
mag = (float)(1.0/Math.sqrt( q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3] ));
x = q[0]*mag;
y = q[1]*mag;
z = q[2]*mag;
w = q[3]*mag;
}
/**
* Constructs and initializes a Quat4f from the specified Quat4f.
* @param q1 the Quat4f containing the initialization x y z w data
*/
public Quat4f(Quat4f q1)
{
super(q1);
}
/**
* Constructs and initializes a Quat4f from the specified Quat4d.
* @param q1 the Quat4d containing the initialization x y z w data
*/
public Quat4f(Quat4d q1)
{
super(q1);
}
/**
* Constructs and initializes a Quat4f from the specified Tuple4f.
* @param t1 the Tuple4f containing the initialization x y z w data
*/
public Quat4f(Tuple4f t1)
{
float mag;
mag = (float)(1.0/Math.sqrt( t1.x*t1.x + t1.y*t1.y + t1.z*t1.z + t1.w*t1.w ));
x = t1.x*mag;
y = t1.y*mag;
z = t1.z*mag;
w = t1.w*mag;
}
/**
* Constructs and initializes a Quat4f from the specified Tuple4d.
* @param t1 the Tuple4d containing the initialization x y z w data
*/
public Quat4f(Tuple4d t1)
{
double mag;
mag = 1.0/Math.sqrt( t1.x*t1.x + t1.y*t1.y + t1.z*t1.z + t1.w*t1.w );
x = (float)(t1.x*mag);
y = (float)(t1.y*mag);
z = (float)(t1.z*mag);
w = (float)(t1.w*mag);
}
/**
* Constructs and initializes a Quat4f to (0.0,0.0,0.0,0.0).
*/
public Quat4f()
{
super();
}
/**
* Sets the value of this quaternion to the conjugate of quaternion q1.
* @param q1 the source vector
*/
public final void conjugate(Quat4f q1)
{
this.x = -q1.x;
this.y = -q1.y;
this.z = -q1.z;
this.w = q1.w;
}
/**
* Sets the value of this quaternion to the conjugate of itself.
*/
public final void conjugate()
{
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
}
/**
* Sets the value of this quaternion to the quaternion product of
* quaternions q1 and q2 (this = q1 * q2).
* Note that this is safe for aliasing (e.g. this can be q1 or q2).
* @param q1 the first quaternion
* @param q2 the second quaternion
*/
public final void mul(Quat4f q1, Quat4f q2)
{
if (this != q1 && this != q2) {
this.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
this.x = q1.w*q2.x + q2.w*q1.x + q1.y*q2.z - q1.z*q2.y;
this.y = q1.w*q2.y + q2.w*q1.y - q1.x*q2.z + q1.z*q2.x;
this.z = q1.w*q2.z + q2.w*q1.z + q1.x*q2.y - q1.y*q2.x;
} else {
float x, y, w;
w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
x = q1.w*q2.x + q2.w*q1.x + q1.y*q2.z - q1.z*q2.y;
y = q1.w*q2.y + q2.w*q1.y - q1.x*q2.z + q1.z*q2.x;
this.z = q1.w*q2.z + q2.w*q1.z + q1.x*q2.y - q1.y*q2.x;
this.w = w;
this.x = x;
this.y = y;
}
}
/**
* Sets the value of this quaternion to the quaternion product of
* itself and q1 (this = this * q1).
* @param q1 the other quaternion
*/
public final void mul(Quat4f q1)
{
float x, y, w;
w = this.w*q1.w - this.x*q1.x - this.y*q1.y - this.z*q1.z;
x = this.w*q1.x + q1.w*this.x + this.y*q1.z - this.z*q1.y;
y = this.w*q1.y + q1.w*this.y - this.x*q1.z + this.z*q1.x;
this.z = this.w*q1.z + q1.w*this.z + this.x*q1.y - this.y*q1.x;
this.w = w;
this.x = x;
this.y = y;
}
/**
* Multiplies quaternion q1 by the inverse of quaternion q2 and places
* the value into this quaternion. The value of both argument quaternions
* is preservered (this = q1 * q2^-1).
* @param q1 the first quaternion
* @param q2 the second quaternion
*/
public final void mulInverse(Quat4f q1, Quat4f q2)
{
Quat4f tempQuat = new Quat4f(q2);
tempQuat.inverse();
this.mul(q1, tempQuat);
}
/**
* Multiplies this quaternion by the inverse of quaternion q1 and places
* the value into this quaternion. The value of the argument quaternion
* is preserved (this = this * q^-1).
* @param q1 the other quaternion
*/
public final void mulInverse(Quat4f q1)
{
Quat4f tempQuat = new Quat4f(q1);
tempQuat.inverse();
this.mul(tempQuat);
}
/**
* Sets the value of this quaternion to quaternion inverse of quaternion q1.
* @param q1 the quaternion to be inverted
*/
public final void inverse(Quat4f q1)
{
float norm;
norm = 1.0f/(q1.w*q1.w + q1.x*q1.x + q1.y*q1.y + q1.z*q1.z);
this.w = norm*q1.w;
this.x = -norm*q1.x;
this.y = -norm*q1.y;
this.z = -norm*q1.z;
}
/**
* Sets the value of this quaternion to the quaternion inverse of itself.
*/
public final void inverse()
{
float norm;
norm = 1.0f/(this.w*this.w + this.x*this.x + this.y*this.y + this.z*this.z);
this.w *= norm;
this.x *= -norm;
this.y *= -norm;
this.z *= -norm;
}
/**
* Sets the value of this quaternion to the normalized value
* of quaternion q1.
* @param q1 the quaternion to be normalized.
*/
public final void normalize(Quat4f q1)
{
float norm;
norm = (q1.x*q1.x + q1.y*q1.y + q1.z*q1.z + q1.w*q1.w);
if (norm > 0.0f) {
norm = 1.0f/(float)Math.sqrt(norm);
this.x = norm*q1.x;
this.y = norm*q1.y;
this.z = norm*q1.z;
this.w = norm*q1.w;
} else {
this.x = (float) 0.0;
this.y = (float) 0.0;
this.z = (float) 0.0;
this.w = (float) 0.0;
}
}
/**
* Normalizes the value of this quaternion in place.
*/
public final void normalize()
{
float norm;
norm = (this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w);
if (norm > 0.0f) {
norm = 1.0f / (float)Math.sqrt(norm);
this.x *= norm;
this.y *= norm;
this.z *= norm;
this.w *= norm;
} else {
this.x = (float) 0.0;
this.y = (float) 0.0;
this.z = (float) 0.0;
this.w = (float) 0.0;
}
}
/**
* Sets the value of this quaternion to the rotational component of
* the passed matrix.
* @param m1 the Matrix4f
*/
public final void set(Matrix4f m1)
{
float ww = 0.25f*(m1.m00 + m1.m11 + m1.m22 + m1.m33);
if (ww >= 0) {
if (ww >= EPS2) {
this.w = (float) Math.sqrt((double)ww);
ww = 0.25f/this.w;
this.x = (m1.m21 - m1.m12)*ww;
this.y = (m1.m02 - m1.m20)*ww;
this.z = (m1.m10 - m1.m01)*ww;
return;
}
} else {
this.w = 0;
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.w = 0;
ww = -0.5f*(m1.m11 + m1.m22);
if (ww >= 0) {
if (ww >= EPS2) {
this.x = (float) Math.sqrt((double) ww);
ww = 1.0f/(2.0f*this.x);
this.y = m1.m10*ww;
this.z = m1.m20*ww;
return;
}
} else {
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.x = 0;
ww = 0.5f*(1.0f - m1.m22);
if (ww >= EPS2) {
this.y = (float) Math.sqrt((double) ww);
this.z = m1.m21/(2.0f*this.y);
return;
}
this.y = 0;
this.z = 1;
}
/**
* Sets the value of this quaternion to the rotational component of
* the passed matrix.
* @param m1 the Matrix4d
*/
public final void set(Matrix4d m1)
{
double ww = 0.25*(m1.m00 + m1.m11 + m1.m22 + m1.m33);
if (ww >= 0) {
if (ww >= EPS2) {
this.w = (float) Math.sqrt(ww);
ww = 0.25/this.w;
this.x = (float) ((m1.m21 - m1.m12)*ww);
this.y = (float) ((m1.m02 - m1.m20)*ww);
this.z = (float) ((m1.m10 - m1.m01)*ww);
return;
}
} else {
this.w = 0;
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.w = 0;
ww = -0.5*(m1.m11 + m1.m22);
if (ww >= 0) {
if (ww >= EPS2) {
this.x = (float) Math.sqrt(ww);
ww = 0.5/this.x;
this.y = (float)(m1.m10*ww);
this.z = (float)(m1.m20*ww);
return;
}
} else {
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.x = 0;
ww = 0.5*(1.0 - m1.m22);
if (ww >= EPS2) {
this.y = (float) Math.sqrt(ww);
this.z = (float) (m1.m21/(2.0*(double)(this.y)));
return;
}
this.y = 0;
this.z = 1;
}
/**
* Sets the value of this quaternion to the rotational component of
* the passed matrix.
* @param m1 the Matrix3f
*/
public final void set(Matrix3f m1)
{
float ww = 0.25f*(m1.m00 + m1.m11 + m1.m22 + 1.0f);
if (ww >= 0) {
if (ww >= EPS2) {
this.w = (float) Math.sqrt((double) ww);
ww = 0.25f/this.w;
this.x = (m1.m21 - m1.m12)*ww;
this.y = (m1.m02 - m1.m20)*ww;
this.z = (m1.m10 - m1.m01)*ww;
return;
}
} else {
this.w = 0;
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.w = 0;
ww = -0.5f*(m1.m11 + m1.m22);
if (ww >= 0) {
if (ww >= EPS2) {
this.x = (float) Math.sqrt((double) ww);
ww = 0.5f/this.x;
this.y = m1.m10*ww;
this.z = m1.m20*ww;
return;
}
} else {
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.x = 0;
ww = 0.5f*(1.0f - m1.m22);
if (ww >= EPS2) {
this.y = (float) Math.sqrt((double) ww);
this.z = m1.m21/(2.0f*this.y);
return;
}
this.y = 0;
this.z = 1;
}
/**
* Sets the value of this quaternion to the rotational component of
* the passed matrix.
* @param m1 the Matrix3d
*/
public final void set(Matrix3d m1)
{
double ww = 0.25*(m1.m00 + m1.m11 + m1.m22 + 1.0f);
if (ww >= 0) {
if (ww >= EPS2) {
this.w = (float) Math.sqrt(ww);
ww = 0.25/this.w;
this.x = (float) ((m1.m21 - m1.m12)*ww);
this.y = (float) ((m1.m02 - m1.m20)*ww);
this.z = (float) ((m1.m10 - m1.m01)*ww);
return;
}
} else {
this.w = 0;
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.w = 0;
ww = -0.5*(m1.m11 + m1.m22);
if (ww >= 0) {
if (ww >= EPS2) {
this.x = (float) Math.sqrt(ww);
ww = 0.5/this.x;
this.y = (float) (m1.m10*ww);
this.z = (float) (m1.m20*ww);
return;
}
} else {
this.x = 0;
this.y = 0;
this.z = 1;
return;
}
this.x = 0;
ww = 0.5*(1.0 - m1.m22);
if (ww >= EPS2) {
this.y = (float) Math.sqrt(ww);
this.z = (float) (m1.m21/(2.0*(double)(this.y)));
return;
}
this.y = 0;
this.z = 1;
}
/**
* Sets the value of this quaternion to the equivalent rotation
* of the AxisAngle argument.
* @param a the AxisAngle to be emulated
*/
public final void set(AxisAngle4f a)
{
float mag,amag;
// Quat = cos(theta/2) + sin(theta/2)(roation_axis)
amag = (float)Math.sqrt( a.x*a.x + a.y*a.y + a.z*a.z);
if (amag < EPS ) {
w = 0.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
} else {
amag = 1.0f/amag;
mag = (float)Math.sin(a.angle/2.0);
w = (float)Math.cos(a.angle/2.0);
x = a.x*amag*mag;
y = a.y*amag*mag;
z = a.z*amag*mag;
}
}
/**
* Sets the value of this quaternion to the equivalent rotation
* of the AxisAngle argument.
* @param a the AxisAngle to be emulated
*/
public final void set(AxisAngle4d a)
{
float mag,amag;
// Quat = cos(theta/2) + sin(theta/2)(roation_axis)
amag = (float)(1.0/Math.sqrt( a.x*a.x + a.y*a.y + a.z*a.z));
if (amag < EPS ) {
w = 0.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
} else {
amag = 1.0f/amag;
mag = (float)Math.sin(a.angle/2.0);
w = (float)Math.cos(a.angle/2.0);
x = (float)a.x*amag*mag;
y = (float)a.y*amag*mag;
z = (float)a.z*amag*mag;
}
}
/**
* Performs a great circle interpolation between this quaternion
* and the quaternion parameter and places the result into this
* quaternion.
* @param q1 the other quaternion
* @param alpha the alpha interpolation parameter
*/
public final void interpolate(Quat4f q1, float alpha) {
// From "Advanced Animation and Rendering Techniques"
// by Watt and Watt pg. 364, function as implemented appeared to be
// incorrect. Fails to choose the same quaternion for the double
// covering. Resulting in change of direction for rotations.
// Fixed function to negate the first quaternion in the case that the
// dot product of q1 and this is negative. Second case was not needed.
double dot,s1,s2,om,sinom;
dot = x*q1.x + y*q1.y + z*q1.z + w*q1.w;
if ( dot < 0 ) {
// negate quaternion
q1.x = -q1.x; q1.y = -q1.y; q1.z = -q1.z; q1.w = -q1.w;
dot = -dot;
}
if ( (1.0 - dot) > EPS ) {
om = Math.acos(dot);
sinom = Math.sin(om);
s1 = Math.sin((1.0-alpha)*om)/sinom;
s2 = Math.sin( alpha*om)/sinom;
} else{
s1 = 1.0 - alpha;
s2 = alpha;
}
w = (float)(s1*w + s2*q1.w);
x = (float)(s1*x + s2*q1.x);
y = (float)(s1*y + s2*q1.y);
z = (float)(s1*z + s2*q1.z);
}
/**
* Performs a great circle interpolation between quaternion q1
* and quaternion q2 and places the result into this quaternion.
* @param q1 the first quaternion
* @param q2 the second quaternion
* @param alpha the alpha interpolation parameter
*/
public final void interpolate(Quat4f q1, Quat4f q2, float alpha) {
// From "Advanced Animation and Rendering Techniques"
// by Watt and Watt pg. 364, function as implemented appeared to be
// incorrect. Fails to choose the same quaternion for the double
// covering. Resulting in change of direction for rotations.
// Fixed function to negate the first quaternion in the case that the
// dot product of q1 and this is negative. Second case was not needed.
double dot,s1,s2,om,sinom;
dot = q2.x*q1.x + q2.y*q1.y + q2.z*q1.z + q2.w*q1.w;
if ( dot < 0 ) {
// negate quaternion
q1.x = -q1.x; q1.y = -q1.y; q1.z = -q1.z; q1.w = -q1.w;
dot = -dot;
}
if ( (1.0 - dot) > EPS ) {
om = Math.acos(dot);
sinom = Math.sin(om);
s1 = Math.sin((1.0-alpha)*om)/sinom;
s2 = Math.sin( alpha*om)/sinom;
} else{
s1 = 1.0 - alpha;
s2 = alpha;
}
w = (float)(s1*q1.w + s2*q2.w);
x = (float)(s1*q1.x + s2*q2.x);
y = (float)(s1*q1.y + s2*q2.y);
z = (float)(s1*q1.z + s2*q2.z);
}
}
source-cvs/vecmath/src/javax/vecmath/GVector.java 0000644 0001750 0001750 00000063370 10761613452 021433 0 ustar jonny jonny /*
* $RCSfile: GVector.java,v $
*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* $Revision: 1.7 $
* $Date: 2008/02/28 20:18:50 $
* $State: Exp $
*/
package javax.vecmath;
import java.lang.Math;
/**
* A double precision, general, dynamically-resizable,
* one-dimensional vector class. Index numbering begins with zero.
*/
public class GVector implements java.io.Serializable, Cloneable {
private int length;
double[] values;
// Compatible with 1.1
static final long serialVersionUID = 1398850036893875112L;
/**
* Constructs a new GVector of the specified
* length with all vector elements initialized to 0.
* @param length the number of elements in this GVector.
*/
public GVector(int length)
{
int i;
this.length = length;
values = new double[length];
for(i = 0; i < length; i++) values[i] = 0.0;
}
/**
* Constructs a new GVector from the specified array elements.
* The length of this GVector is set to the length of the
* specified array. The array elements are copied into this new
* GVector.
* @param vector the values for the new GVector.
*/
public GVector(double[] vector)
{
int i;
length = vector.length;
values = new double[vector.length];
for(i = 0; i < length; i++) values[i] = vector[i];
}
/**
* Constructs a new GVector from the specified vector.
* The vector elements are copied into this new GVector.
* @param vector the source GVector for this new GVector.
*/
public GVector(GVector vector)
{
int i;
values = new double[vector.length];
length = vector.length;
for(i = 0; i < length; i++) values[i] = vector.values[i];
}
/**
* Constructs a new GVector and copies the initial values
* from the specified tuple.
* @param tuple the source for the new GVector's initial values
*/
public GVector(Tuple2f tuple)
{
values = new double[2];
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
length = 2;
}
/**
* Constructs a new GVector and copies the initial values
* from the specified tuple.
* @param tuple the source for the new GVector's initial values
*/
public GVector(Tuple3f tuple)
{
values = new double[3];
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
values[2] = (double)tuple.z;
length = 3;
}
/**
* Constructs a new GVector and copies the initial values
* from the specified tuple.
* @param tuple the source for the new GVector's initial values
*/
public GVector(Tuple3d tuple)
{
values = new double[3];
values[0] = tuple.x;
values[1] = tuple.y;
values[2] = tuple.z;
length = 3;
}
/**
* Constructs a new GVector and copies the initial values
* from the specified tuple.
* @param tuple the source for the new GVector's initial values
*/
public GVector(Tuple4f tuple)
{
values = new double[4];
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
values[2] = (double)tuple.z;
values[3] = (double)tuple.w;
length = 4;
}
/**
* Constructs a new GVector and copies the initial values
* from the specified tuple.
* @param tuple the source for the new GVector's initial values
*/
public GVector(Tuple4d tuple)
{
values = new double[4];
values[0] = tuple.x;
values[1] = tuple.y;
values[2] = tuple.z;
values[3] = tuple.w;
length = 4;
}
/**
* Constructs a new GVector of the specified length and
* initializes it by copying the specified number of elements from
* the specified array. The array must contain at least
* length
elements (i.e., vector.length
>=
* length
. The length of this new GVector is set to
* the specified length.
* @param vector The array from which the values will be copied.
* @param length The number of values copied from the array.
*/
public GVector(double vector[], int length) {
int i;
this.length = length;
values = new double [length];
for(i=0;i=0; j--){
values[j] = 0.0;
for(int i=v1.length-1;i>=0; i--){
values[j] += m1.values[j][i] * v[i];
}
}
}
/**
* Multiplies the transpose of vector v1 (ie, v1 becomes a row
* vector with respect to the multiplication) times matrix m1
* and places the result into this vector
* (this = transpose(v1)*m1). The result is technically a
* row vector, but the GVector class only knows about column
* vectors, and so the result is stored as a column vector.
* @param m1 The matrix in the multiplication
* @param v1 The vector that is temporarily transposed
*/
public final void mul(GVector v1, GMatrix m1) {
if (m1.getNumRow() != v1.length)
throw new MismatchedSizeException(VecMathI18N.getString("GVector12"));
if (length != m1.getNumCol())
throw new MismatchedSizeException(VecMathI18N.getString("GVector13"));
double v[];
if (v1 != this) {
v = v1.values;
} else {
v = (double []) values.clone();
}
for (int j=length-1; j>=0; j--){
values[j] = 0.0;
for(int i=v1.length-1; i>=0; i--){
values[j] += m1.values[i][j] * v[i];
}
}
}
/**
* Negates the value of this vector: this = -this.
*/
public final void negate() {
for(int i=length-1; i>=0; i--) {
this.values[i] *= -1.0;
}
}
/**
* Sets all the values in this vector to zero.
*/
public final void zero() {
for (int i=0; i < this.length; i++) {
this.values[i] = 0.0;
}
}
/**
* Changes the size of this vector dynamically. If the size is increased
* no data values will be lost. If the size is decreased, only those data
* values whose vector positions were eliminated will be lost.
* @param length number of desired elements in this vector
*/
public final void setSize(int length) {
double[] tmp = new double[length];
int i,max;
if( this.length < length)
max = this.length;
else
max = length;
for(i=0;i=0; i--)
values[i] = vector[i];
}
/**
* Sets the value of this vector to the values found in vector vector.
* @param vector the source vector
*/
public final void set(GVector vector) {
int i;
if (length < vector.length) {
length = vector.length;
values = new double[length];
for(i = 0; i < length; i++)
values[i] = vector.values[i];
}else {
for(i = 0; i < vector.length; i++)
values[i] = vector.values[i];
for(i = vector.length; i < length; i++)
values[i] = 0.0;
}
}
/**
* Sets the value of this vector to the values in tuple
* @param tuple the source for the new GVector's new values
*/
public final void set(Tuple2f tuple)
{
if (length < 2) {
length = 2;
values = new double[2];
}
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
for(int i = 2; i < length; i++) values[i] = 0.0;
}
/**
* Sets the value of this vector to the values in tuple
* @param tuple the source for the new GVector's new values
*/
public final void set(Tuple3f tuple)
{
if (length < 3) {
length = 3;
values = new double[3];
}
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
values[2] = (double)tuple.z;
for(int i = 3; i < length; i++) values[i] = 0.0;
}
/**
* Sets the value of this vector to the values in tuple
* @param tuple the source for the new GVector's new values
*/
public final void set(Tuple3d tuple)
{
if (length < 3) {
length = 3;
values = new double[3];
}
values[0] = tuple.x;
values[1] = tuple.y;
values[2] = tuple.z;
for(int i = 3; i < length; i++) values[i] = 0.0;
}
/**
* Sets the value of this vector to the values in tuple
* @param tuple the source for the new GVector's new values
*/
public final void set(Tuple4f tuple)
{
if (length < 4) {
length = 4;
values = new double[4];
}
values[0] = (double)tuple.x;
values[1] = (double)tuple.y;
values[2] = (double)tuple.z;
values[3] = (double)tuple.w;
for(int i = 4; i < length; i++) values[i] = 0.0;
}
/**
* Sets the value of this vector to the values in tuple
* @param tuple the source for the new GVector's new values
*/
public final void set(Tuple4d tuple)
{
if (length < 4) {
length = 4;
values = new double[4];
}
values[0] = tuple.x;
values[1] = tuple.y;
values[2] = tuple.z;
values[3] = tuple.w;
for(int i = 4; i < length; i++) values[i] = 0.0;
}
/**
* Returns the number of elements in this vector.
* @return number of elements in this vector
*/
public final int getSize()
{
return values.length;
}
/**
* Retrieves the value at the specified index value of this vector.
* @param index the index of the element to retrieve (zero indexed)
* @return the value at the indexed element
*/
public final double getElement(int index)
{
return values[index];
}
/**
* Modifies the value at the specified index of this vector.
* @param index the index if the element to modify (zero indexed)
* @param value the new vector element value
*/
public final void setElement(int index, double value)
{
values[index] = value;
}
/**
* Returns a string that contains the values of this GVector.
* @return the String representation
*/
public String toString() {
StringBuffer buffer = new StringBuffer(length*8);
int i;
for(i=0;i> 32));
}
/**
* Returns true if all of the data members of GVector vector1 are
* equal to the corresponding data members in this GVector.
* @param vector1 The vector with which the comparison is made.
* @return true or false
*/
public boolean equals(GVector vector1)
{
try {
if( length != vector1.length) return false;
for(int i = 0;i epsilon) return false;
}
return true;
}
/**
* Returns the dot product of this vector and vector v1.
* @param v1 the other vector
* @return the dot product of this and v1
*/
public final double dot(GVector v1)
{
if( length != v1.length)
throw new MismatchedSizeException(VecMathI18N.getString("GVector14"));
double result = 0.0;
for(int i = 0;i