From 101567f5f16d91a13c8067764d5e14eefb2b9936 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 15 Mar 2014 16:54:34 +0100 Subject: FloatUtil/VectorUtil: Enhance isEqual/compare w/ and w/o epsilon, add unit tests - Cleanup VectorUtil (vec2/3 naming, remove dedundant functions) --- .../com/jogamp/graph/curve/OutlineShape.java | 13 +- .../classes/com/jogamp/graph/geom/Outline.java | 2 +- .../classes/com/jogamp/graph/geom/SVertex.java | 5 +- .../classes/com/jogamp/opengl/math/FloatUtil.java | 88 ++++++- .../classes/com/jogamp/opengl/math/Quaternion.java | 34 +-- .../classes/com/jogamp/opengl/math/VectorUtil.java | 287 ++++++++++----------- .../com/jogamp/opengl/math/geom/AABBox.java | 31 ++- src/jogl/classes/jogamp/graph/curve/tess/Loop.java | 16 +- src/jogl/classes/jogamp/opengl/ProjectFloat.java | 8 +- .../test/junit/jogl/math/TestFloatUtil01NOUI.java | 236 ++++++++++++++++- .../test/junit/jogl/math/TestQuaternion01NOUI.java | 104 ++++---- 11 files changed, 566 insertions(+), 258 deletions(-) (limited to 'src') diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index 160e171e4..bac67eb5f 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -436,9 +436,9 @@ public class OutlineShape implements Comparable { } private void subdivideTriangle(final Outline outline, Vertex a, Vertex b, Vertex c, int index){ - VectorUtil.mid(tmpV1, a.getCoord(), b.getCoord()); - VectorUtil.mid(tmpV3, b.getCoord(), c.getCoord()); - VectorUtil.mid(tmpV2, tmpV1, tmpV3); + VectorUtil.midVec3(tmpV1, a.getCoord(), b.getCoord()); + VectorUtil.midVec3(tmpV3, b.getCoord(), c.getCoord()); + VectorUtil.midVec3(tmpV2, tmpV1, tmpV3); //drop off-curve vertex to image on the curve b.setCoord(tmpV2, 0, 3); @@ -517,7 +517,7 @@ public class OutlineShape implements Comparable { continue; } - if( VectorUtil.vertexInTriangle3(a.getCoord(), b.getCoord(), c.getCoord(), + if( VectorUtil.isVec3InTriangle3(a.getCoord(), b.getCoord(), c.getCoord(), current.getCoord(), nextV.getCoord(), prevV.getCoord(), tmpV1, tmpV2, tmpV3) ) { return current; @@ -542,7 +542,7 @@ public class OutlineShape implements Comparable { final Vertex currentVertex = outline.getVertex(i); final Vertex nextVertex = outline.getVertex((i+1)%vertexCount); if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) { - VectorUtil.mid(tmpV1, currentVertex.getCoord(), nextVertex.getCoord()); + VectorUtil.midVec3(tmpV1, currentVertex.getCoord(), nextVertex.getCoord()); final Vertex v = vertexFactory.create(tmpV1, 0, 3, true); i++; vertexCount++; @@ -557,8 +557,7 @@ public class OutlineShape implements Comparable { } if( vertexCount > 0 ) { - if(VectorUtil.checkEquality(outline.getVertex(0).getCoord(), - outline.getLastVertex().getCoord())) { + if(VectorUtil.isVec3Equal( outline.getVertex(0).getCoord(), 0, outline.getLastVertex().getCoord(), 0, FloatUtil.EPSILON )) { outline.removeVertex(vertexCount-1); } } diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java index 9d4d1f26d..80aea2af4 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java @@ -172,7 +172,7 @@ public class Outline implements Cloneable, Comparable { if( !isEmpty() ) { final Vertex first = vertices.get(0); final Vertex last = getLastVertex(); - if( !VectorUtil.checkEquality( first.getCoord(), last.getCoord() ) ) { + if( !VectorUtil.isVec3Equal( first.getCoord(), 0, last.getCoord(), 0, FloatUtil.EPSILON ) ) { if( closeTail ) { vertices.add(first.clone()); } else { diff --git a/src/jogl/classes/com/jogamp/graph/geom/SVertex.java b/src/jogl/classes/com/jogamp/graph/geom/SVertex.java index 99f10a694..beac908d4 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/SVertex.java +++ b/src/jogl/classes/com/jogamp/graph/geom/SVertex.java @@ -27,6 +27,7 @@ */ package com.jogamp.graph.geom; +import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.VectorUtil; /** A Simple Vertex Implementation. Where the coordinates, and other attributes are @@ -188,8 +189,8 @@ public class SVertex implements Vertex { final Vertex v = (Vertex) obj; return this == v || isOnCurve() == v.isOnCurve() && - VectorUtil.checkEqualityVec2(getTexCoord(), v.getTexCoord()) && - VectorUtil.checkEquality(getCoord(), v.getCoord()) ; + VectorUtil.isVec2Equal(getTexCoord(), 0, v.getTexCoord(), 0, FloatUtil.EPSILON) && + VectorUtil.isVec3Equal(getCoord(), 0, v.getCoord(), 0, FloatUtil.EPSILON) ; } @Override diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java index ee57fc7e8..bb40fed33 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java @@ -122,7 +122,7 @@ public class FloatUtil { final float s = sin(angrad); tmpVec3f[0]=x; tmpVec3f[1]=y; tmpVec3f[2]=z; - VectorUtil.normalize(tmpVec3f); + VectorUtil.normalizeVec3(tmpVec3f); x = tmpVec3f[0]; y = tmpVec3f[1]; z = tmpVec3f[2]; // Rotation matrix (Row Order): @@ -712,12 +712,96 @@ public class FloatUtil { */ public static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d + /** + * Return true if both values are equal w/o regarding an epsilon. + *

+ * Implementation considers following corner cases: + *

    + *
  • NaN == NaN
  • + *
  • +Inf == +Inf
  • + *
  • -Inf == -Inf
  • + *
+ *

+ * @see #isEqual(float, float, float) + */ + public static boolean isEqual(final float a, final float b) { + // Values are equal (Inf, Nan .. ) + return Float.floatToIntBits(a) == Float.floatToIntBits(b); + } + /** * Return true if both values are equal, i.e. their absolute delta < epsilon. + *

+ * Implementation considers following corner cases: + *

    + *
  • NaN == NaN
  • + *
  • +Inf == +Inf
  • + *
  • -Inf == -Inf
  • + *
+ *

* @see #EPSILON */ public static boolean isEqual(final float a, final float b, final float epsilon) { - return Math.abs(a - b) < epsilon; + if ( Math.abs(a - b) < epsilon ) { + return true; + } else { + // Values are equal (Inf, Nan .. ) + return Float.floatToIntBits(a) == Float.floatToIntBits(b); + } + } + + /** + * Return true if both values are equal w/o regarding an epsilon. + *

+ * Implementation considers following corner cases: + *

    + *
  • NaN == NaN
  • + *
  • +Inf == +Inf
  • + *
  • -Inf == -Inf
  • + *
  • NaN > 0
  • + *
  • +Inf > -Inf
  • + *
+ *

+ * @see #compare(float, float, float) + */ + public static int compare(final float a, final float b) { + if (a < b) { + return -1; // Neither is NaN, a is smaller + } + if (a > b) { + return 1; // Neither is NaN, a is larger + } + final int aBits = Float.floatToIntBits(a); + final int bBits = Float.floatToIntBits(b); + if( aBits == bBits ) { + return 0; // Values are equal (Inf, Nan .. ) + } else if( aBits < bBits ) { + return -1; // (-0.0, 0.0) or (!NaN, NaN) + } else { + return 1; // ( 0.0, -0.0) or ( NaN, !NaN) + } + } + + /** + * Return true if both values are equal, i.e. their absolute delta < epsilon. + *

+ * Implementation considers following corner cases: + *

    + *
  • NaN == NaN
  • + *
  • +Inf == +Inf
  • + *
  • -Inf == -Inf
  • + *
  • NaN > 0
  • + *
  • +Inf > -Inf
  • + *
+ *

+ * @see #EPSILON + */ + public static int compare(final float a, final float b, final float epsilon) { + if ( Math.abs(a - b) < epsilon ) { + return 0; + } else { + return compare(a, b); + } } /** diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java index 6e567fc1d..e2b23544a 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java @@ -404,7 +404,7 @@ public class Quaternion { * @see Matrix-FAQ Q63 */ public final float[] rotateVector(final float[] vecOut, final int vecOutOffset, final float[] vecIn, final int vecInOffset) { - if ( VectorUtil.isZero(vecIn, vecInOffset, FloatUtil.EPSILON) ) { + if ( VectorUtil.isVec3Zero(vecIn, vecInOffset, FloatUtil.EPSILON) ) { vecOut[0+vecOutOffset] = 0f; vecOut[1+vecOutOffset] = 0f; vecOut[2+vecOutOffset] = 0f; @@ -537,18 +537,18 @@ public class Quaternion { public Quaternion setLookAt(final float[] directionIn, final float[] upIn, final float[] xAxisOut, final float[] yAxisOut, final float[] zAxisOut) { // Z = norm(dir) - VectorUtil.normalize(zAxisOut, directionIn); + VectorUtil.normalizeVec3(zAxisOut, directionIn); // X = upIn x Z // (borrow yAxisOut for upNorm) - VectorUtil.normalize(yAxisOut, upIn); - VectorUtil.cross(xAxisOut, yAxisOut, zAxisOut); - VectorUtil.normalize(xAxisOut); + VectorUtil.normalizeVec3(yAxisOut, upIn); + VectorUtil.crossVec3(xAxisOut, yAxisOut, zAxisOut); + VectorUtil.normalizeVec3(xAxisOut); // Y = Z x X // - VectorUtil.cross(yAxisOut, zAxisOut, xAxisOut); - VectorUtil.normalize(yAxisOut); + VectorUtil.crossVec3(yAxisOut, zAxisOut, xAxisOut); + VectorUtil.normalizeVec3(yAxisOut); /** final float m00 = xAxisOut[0]; @@ -588,16 +588,16 @@ public class Quaternion { * @return this quaternion for chaining. */ public final Quaternion setFromVectors(final float[] v1, final float[] v2, final float[] tmpPivotVec, final float[] tmpNormalVec) { - final float factor = VectorUtil.length(v1) * VectorUtil.length(v2); + final float factor = VectorUtil.vec3Length(v1) * VectorUtil.vec3Length(v2); if ( FloatUtil.isZero(factor, FloatUtil.EPSILON ) ) { return setIdentity(); } else { - final float dot = VectorUtil.dot(v1, v2) / factor; // normalize + final float dot = VectorUtil.vec3Dot(v1, v2) / factor; // normalize final float theta = FloatUtil.acos(Math.max(-1.0f, Math.min(dot, 1.0f))); // clipping [-1..1] - VectorUtil.cross(tmpPivotVec, v1, v2); + VectorUtil.crossVec3(tmpPivotVec, v1, v2); - if ( dot < 0.0f && FloatUtil.isZero( VectorUtil.length(tmpPivotVec), FloatUtil.EPSILON ) ) { + if ( dot < 0.0f && FloatUtil.isZero( VectorUtil.vec3Length(tmpPivotVec), FloatUtil.EPSILON ) ) { // Vectors parallel and opposite direction, therefore a rotation of 180 degrees about any vector // perpendicular to this vector will rotate vector a onto vector b. // @@ -643,16 +643,16 @@ public class Quaternion { * @return this quaternion for chaining. */ public final Quaternion setFromNormalVectors(final float[] v1, final float[] v2, final float[] tmpPivotVec) { - final float factor = VectorUtil.length(v1) * VectorUtil.length(v2); + final float factor = VectorUtil.vec3Length(v1) * VectorUtil.vec3Length(v2); if ( FloatUtil.isZero(factor, FloatUtil.EPSILON ) ) { return setIdentity(); } else { - final float dot = VectorUtil.dot(v1, v2) / factor; // normalize + final float dot = VectorUtil.vec3Dot(v1, v2) / factor; // normalize final float theta = FloatUtil.acos(Math.max(-1.0f, Math.min(dot, 1.0f))); // clipping [-1..1] - VectorUtil.cross(tmpPivotVec, v1, v2); + VectorUtil.crossVec3(tmpPivotVec, v1, v2); - if ( dot < 0.0f && FloatUtil.isZero( VectorUtil.length(tmpPivotVec), FloatUtil.EPSILON ) ) { + if ( dot < 0.0f && FloatUtil.isZero( VectorUtil.vec3Length(tmpPivotVec), FloatUtil.EPSILON ) ) { // Vectors parallel and opposite direction, therefore a rotation of 180 degrees about any vector // perpendicular to this vector will rotate vector a onto vector b. // @@ -696,7 +696,7 @@ public class Quaternion { * @see #toAngleAxis(float[]) */ public final Quaternion setFromAngleAxis(final float angle, final float[] vector, final float[] tmpV3f) { - VectorUtil.normalize(tmpV3f, vector); + VectorUtil.normalizeVec3(tmpV3f, vector); return setFromAngleNormalAxis(angle, tmpV3f); } @@ -716,7 +716,7 @@ public class Quaternion { * @see #toAngleAxis(float[]) */ public final Quaternion setFromAngleNormalAxis(final float angle, final float[] vector) { - if ( VectorUtil.isZero(vector, 0, FloatUtil.EPSILON) ) { + if ( VectorUtil.isVec3Zero(vector, 0, FloatUtil.EPSILON) ) { setIdentity(); } else { final float halfangle = angle * 0.5f; diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 4aa1baf78..778c17a53 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -31,9 +31,6 @@ import java.util.ArrayList; public class VectorUtil { - /** Zero vector */ - public static final float[] ZERO = new float[] { 0f, 0f, 0f }; - public enum Winding { CW(-1), CCW(1); @@ -44,8 +41,6 @@ public class VectorUtil { } } - public static final int COLLINEAR = 0; - /** * Copies a vector of length 3 * @param dst output vector @@ -75,47 +70,78 @@ public class VectorUtil { } /** - * Return true if both vectors are equal, no {@link FloatUtil#EPSILON} is taken into consideration. + * Return true if both vectors are equal w/o regarding an epsilon. + *

+ * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. + *

+ */ + public static boolean isVec2Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { + return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && + FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) ; + } + + /** + * Return true if both vectors are equal w/o regarding an epsilon. + *

+ * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. + *

*/ - public static boolean isEqual(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { - return vec1[0+vec1Offset] == vec2[0+vec2Offset] && - vec1[1+vec1Offset] == vec2[1+vec2Offset] && - vec1[2+vec1Offset] == vec2[2+vec2Offset]; + public static boolean isVec3Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { + return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && + FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) && + FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset]) ; } /** * Return true if both vectors are equal, i.e. their absolute delta < epsilon. - * @see FloatUtil#EPSILON + *

+ * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. + *

*/ - public static boolean isEqual(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { - return Math.abs(vec1[0+vec1Offset] - vec2[0+vec2Offset]) < epsilon && - Math.abs(vec1[1+vec1Offset] - vec2[1+vec2Offset]) < epsilon && - Math.abs(vec1[2+vec1Offset] - vec2[2+vec2Offset]) < epsilon ; + public static boolean isVec2Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { + return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && + FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) ; + } + + /** + * Return true if both vectors are equal, i.e. their absolute delta < epsilon. + *

+ * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. + *

+ */ + public static boolean isVec3Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { + return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && + FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) && + FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset], epsilon) ; } /** * Return true if vector is zero, no {@link FloatUtil#EPSILON} is taken into consideration. */ - public static boolean isZero(final float[] vec, final int vecOffset) { + public static boolean isVec3Zero(final float[] vec, final int vecOffset) { return 0f == vec[0+vecOffset] && 0f == vec[1+vecOffset] && 0f == vec[2+vecOffset]; } /** * Return true if vector is zero, i.e. it's absolute components < epsilon. - * @see FloatUtil#EPSILON + *

+ * Implementation uses {@link FloatUtil#isZero(float, float)}, see API doc for details. + *

*/ - public static boolean isZero(final float[] vec, final int vecOffset, final float epsilon) { + public static boolean isVec3Zero(final float[] vec, final int vecOffset, final float epsilon) { return isZero(vec[0+vecOffset], vec[1+vecOffset], vec[2+vecOffset], epsilon); } /** * Return true if all three vector components are zero, i.e. it's their absolute value < epsilon. - * @see FloatUtil#EPSILON + *

+ * Implementation uses {@link FloatUtil#isZero(float, float)}, see API doc for details. + *

*/ public static boolean isZero(final float x, final float y, final float z, final float epsilon) { - return Math.abs(x) < epsilon && - Math.abs(y) < epsilon && - Math.abs(z) < epsilon ; + return FloatUtil.isZero(x, epsilon) && + FloatUtil.isZero(y, epsilon) && + FloatUtil.isZero(z, epsilon) ; } /** @@ -125,7 +151,7 @@ public class VectorUtil { * distances, thus avoiding an expensive square root operation. *

*/ - public static float distanceSquared(final float[] v1, final float[] v2) { + public static float vec3DistanceSquare(final float[] v1, final float[] v2) { final float dx = v1[0] - v2[0]; final float dy = v1[1] - v2[1]; final float dz = v1[2] - v2[2]; @@ -135,41 +161,43 @@ public class VectorUtil { /** * Return the distance between the given two points described vector v1 and v2. */ - public static float distance(final float[] v1, final float[] v2) { - return FloatUtil.sqrt(distanceSquared(v1, v2)); + public static float vec3Distance(final float[] v1, final float[] v2) { + return FloatUtil.sqrt(vec3DistanceSquare(v1, v2)); } - /** compute the dot product of two points + /** + * Compute the dot product of two points * @param vec1 vector 1 * @param vec2 vector 2 * @return the dot product as float */ - public static float dot(final float[] vec1, final float[] vec2) + public static float vec3Dot(final float[] vec1, final float[] vec2) { - return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]); + return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]; } /** * Compute the squared length of a vector, a.k.a the squared norm */ - public static float lengthSquared(final float[] vec) { + public static float vec3LengthSquare(final float[] vec) { return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; } /** * Compute the length of a vector, a.k.a the norm */ - public static float length(final float[] vec) { - return FloatUtil.sqrt(lengthSquared(vec)); + public static float vec3Length(final float[] vec) { + return FloatUtil.sqrt(vec3LengthSquare(vec)); } /** * Normalize a vector - * @param result output vector + * @param result output vector, may be vector (in-place) * @param vector input vector * @return normalized output vector + * @return result vector for chaining */ - public static float[] normalize(final float[] result, final float[] vector) { - final float lengthSq = lengthSquared(vector); + public static float[] normalizeVec3(final float[] result, final float[] vector) { + final float lengthSq = vec3LengthSquare(vector); if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { result[0] = 0f; result[1] = 0f; @@ -185,12 +213,11 @@ public class VectorUtil { /** * Normalize a vector in place - * @param result output vector * @param vector input vector * @return normalized output vector */ - public static float[] normalize(final float[] vector) { - final float lengthSq = lengthSquared(vector); + public static float[] normalizeVec3(final float[] vector) { + final float lengthSq = vec3LengthSquare(vector); if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { vector[0] = 0f; vector[1] = 0f; @@ -206,24 +233,26 @@ public class VectorUtil { /** * Scales a vector by param using given result float[] - * @param result vector for the result + * @param result vector for the result, may be vector (in-place) * @param vector input vector * @param scale single scale constant for all vector components + * @return result vector for chaining */ - public static float[] scale(final float[] result, final float[] vector, final float scale) { + public static float[] scaleVec3(final float[] result, final float[] vector, final float scale) { result[0] = vector[0] * scale; result[1] = vector[1] * scale; result[2] = vector[2] * scale; return result; } - /** Scales a vector by param using given result float[] - * @param result vector for the result + /** + * Scales a vector by param using given result float[] + * @param result vector for the result, may be vector (in-place) * @param vector input vector * @param scale 3 component scale constant for each vector component - * @return given result vector + * @return result vector for chaining */ - public static float[] scale(final float[] result, final float[] vector, final float[] scale) + public static float[] scaleVec3(final float[] result, final float[] vector, final float[] scale) { result[0] = vector[0] * scale[0]; result[1] = vector[1] * scale[1]; @@ -232,12 +261,13 @@ public class VectorUtil { } /** - * Adds two vectors + * Adds two vectors, result = v1 + v2 + * @param result float[3] result vector, may be either v1 or v2 (in-place) * @param v1 vector 1 * @param v2 vector 2 - * @return v1 + v2 + * @return result vector for chaining */ - public static float[] vectorAdd(final float[] result, final float[] v1, final float[] v2) { + public static float[] addVec3(final float[] result, final float[] v1, final float[] v2) { result[0] = v1[0] + v2[0]; result[1] = v1[1] + v2[1]; result[2] = v1[2] + v2[2]; @@ -245,12 +275,13 @@ public class VectorUtil { } /** - * Subtracts two vectors + * Subtracts two vectors, result = v1 - v2 + * @param result float[3] result vector, may be either v1 or v2 (in-place) * @param v1 vector 1 * @param v2 vector 2 - * @return v1 - v2 + * @return result vector for chaining */ - public static float[] vectorSub(final float[] result, final float[] v1, final float[] v2) { + public static float[] subVec3(final float[] result, final float[] v1, final float[] v2) { result[0] = v1[0] - v2[0]; result[1] = v1[1] - v2[1]; result[2] = v1[2] - v2[2]; @@ -263,7 +294,7 @@ public class VectorUtil { * @param v2 vector 2 * @return the resulting vector */ - public static float[] cross(final float[] result, final float[] v1, final float[] v2) + public static float[] crossVec3(final float[] result, final float[] v1, final float[] v2) { result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[1] = v1[2] * v2[0] - v1[0] * v2[2]; @@ -271,12 +302,13 @@ public class VectorUtil { return result; } - /** Column Matrix Vector multiplication + /** + * Multiplication of column-major 4x4 matrix with vector * @param colMatrix column matrix (4x4) * @param vec vector(x,y,z) * @return result */ - public static float[] colMatrixVectorMult(final float[] result, final float[] colMatrix, final float[] vec) + public static float[] mulColMat4Vec3(final float[] result, final float[] colMatrix, final float[] vec) { result[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12]; result[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13]; @@ -285,12 +317,13 @@ public class VectorUtil { return result; } - /** Matrix Vector multiplication + /** + * Matrix Vector multiplication * @param rawMatrix column matrix (4x4) * @param vec vector(x,y,z) * @return result */ - public static float[] rowMatrixVectorMult(final float[] result, final float[] rawMatrix, final float[] vec) + public static float[] mulRowMat4Vec3(final float[] result, final float[] rawMatrix, final float[] vec) { result[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3]; result[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7]; @@ -299,103 +332,53 @@ public class VectorUtil { return result; } - /** Calculate the midpoint of two values + /** + * Calculate the midpoint of two values * @param p1 first value * @param p2 second vale * @return midpoint */ - public static float mid(final float p1, final float p2) - { + public static float mid(final float p1, final float p2) { return (p1+p2)/2.0f; } /** * Calculate the midpoint of two points - * @param p1 first point - * @param p2 second point + * @param p1 first point vector + * @param p2 second point vector * @return midpoint */ - public static float[] mid(final float[] result, final float[] p1, final float[] p2) - { + public static float[] midVec3(final float[] result, final float[] p1, final float[] p2) { result[0] = (p1[0] + p2[0])*0.5f; result[1] = (p1[1] + p2[1])*0.5f; result[2] = (p1[2] + p2[2])*0.5f; - return result; } - /** Compute distance between 2 points - * @param p0 a ref point on the line - * @param vec vector representing the direction of the line - * @param point the point to compute the relative distance of - * @return distance float - */ - public static float computeLength(final float[] p0, final float[] point) - { - final float w0 = point[0]-p0[0]; - final float w1 = point[1]-p0[1]; - final float w2 = point[2]-p0[2]; - - return FloatUtil.sqrt(w0*w0 + w1*w1 + w2*w2); - } - - /**Check equality of 2 vec3 vectors - * @param v1 vertex 1 - * @param v2 vertex 2 - * @return - */ - public static boolean checkEquality(final float[] v1, final float[] v2) - { - return Float.compare(v1[0], v2[0]) == 0 && - Float.compare(v1[1], v2[1]) == 0 && - Float.compare(v1[2], v2[2]) == 0 ; - } - - /**Check equality of 2 vec2 vectors - * @param v1 vertex 1 - * @param v2 vertex 2 - * @return - */ - public static boolean checkEqualityVec2(final float[] v1, final float[] v2) - { - return Float.compare(v1[0], v2[0]) == 0 && - Float.compare(v1[1], v2[1]) == 0 ; - } - - /** Compute the determinant of 3 vectors + /** + * Compute the determinant of 3 vectors * @param a vector 1 * @param b vector 2 * @param c vector 3 * @return the determinant value */ - public static float computeDeterminant(final float[] a, final float[] b, final float[] c) - { + public static float vec3Determinant(final float[] a, final float[] b, final float[] c) { return a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[0]*b[2]*c[1] - a[1]*b[0]*c[2] - a[2]*b[1]*c[0]; } - /** Check if three vertices are colliniear + /** + * Check if three vertices are colliniear * @param v1 vertex 1 * @param v2 vertex 2 * @param v3 vertex 3 * @return true if collinear, false otherwise */ - public static boolean checkCollinear(final float[] v1, final float[] v2, final float[] v3) - { - return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR); + public static boolean isVec3Collinear(final float[] v1, final float[] v2, final float[] v3) { + return FloatUtil.isZero( vec3Determinant(v1, v2, v3), FloatUtil.EPSILON ); } - /** Compute Vector - * @param vector storage for resulting Vector V1V2 - * @param v1 vertex 1 - * @param v2 vertex2 2 - */ - public static void computeVector(final float[] vector, final float[] v1, final float[] v2) { - vector[0] = v2[0] - v1[0]; - vector[1] = v2[1] - v1[1]; - vector[2] = v2[2] - v1[2]; - } - - /** Check if vertices in triangle circumcircle + /** + * Check if vertices in triangle circumcircle * @param a triangle vertex 1 * @param b triangle vertex 2 * @param c triangle vertex 3 @@ -403,7 +386,7 @@ public class VectorUtil { * @return true if the vertex d is inside the circle defined by the * vertices a, b, c. from paper by Guibas and Stolfi (1985). */ - public static boolean inCircle(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { + public static boolean isInCircle(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { final float[] A = a.getCoord(); final float[] B = b.getCoord(); final float[] C = c.getCoord(); @@ -414,7 +397,8 @@ public class VectorUtil { (D[0] * D[0] + D[1] * D[1]) * triArea(A, B, C) > 0; } - /** Computes oriented area of a triangle + /** + * Computes oriented area of a triangle * @param a first vertex * @param b second vertex * @param c third vertex @@ -428,7 +412,8 @@ public class VectorUtil { return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]); } - /** Computes oriented area of a triangle + /** + * Computes oriented area of a triangle * @param A first vertex * @param B second vertex * @param C third vertex @@ -439,7 +424,8 @@ public class VectorUtil { return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1])*(C[0] - A[0]); } - /** Check if a vertex is in triangle using + /** + * Check if a vertex is in triangle using * barycentric coordinates computation. * @param a first triangle vertex * @param b second triangle vertex @@ -447,20 +433,20 @@ public class VectorUtil { * @param p the vertex in question * @return true if p is in triangle (a, b, c), false otherwise. */ - public static boolean vertexInTriangle(final float[] a, final float[] b, final float[] c, + public static boolean isVec3InTriangle(final float[] a, final float[] b, final float[] c, final float[] p, final float[] ac, final float[] ab, final float[] ap){ // Compute vectors - computeVector(ac, a, c); //v0 - computeVector(ab, a, b); //v1 - computeVector(ap, a, p); //v2 + subVec3(ac, c, a); //v0 + subVec3(ab, b, a); //v1 + subVec3(ap, p, a); //v2 // Compute dot products - final float dot00 = dot(ac, ac); - final float dot01 = dot(ac, ab); - final float dot02 = dot(ac, ap); - final float dot11 = dot(ab, ab); - final float dot12 = dot(ab, ap); + final float dot00 = vec3Dot(ac, ac); + final float dot01 = vec3Dot(ac, ab); + final float dot02 = vec3Dot(ac, ap); + final float dot11 = vec3Dot(ab, ab); + final float dot12 = vec3Dot(ab, ap); // Compute barycentric coordinates final float invDenom = 1 / (dot00 * dot11 - dot01 * dot01); @@ -485,24 +471,24 @@ public class VectorUtil { * @param tmpAP * @return true if p1 or p2 or p3 is in triangle (a, b, c), false otherwise. */ - public static boolean vertexInTriangle3(final float[] a, final float[] b, final float[] c, + public static boolean isVec3InTriangle3(final float[] a, final float[] b, final float[] c, final float[] p1, final float[] p2, final float[] p3, final float[] tmpAC, final float[] tmpAB, final float[] tmpAP){ // Compute vectors - computeVector(tmpAC, a, c); //v0 - computeVector(tmpAB, a, b); //v1 + subVec3(tmpAC, c, a); //v0 + subVec3(tmpAB, b, a); //v1 // Compute dot products - final float dotAC_AC = dot(tmpAC, tmpAC); - final float dotAC_AB = dot(tmpAC, tmpAB); - final float dotAB_AB = dot(tmpAB, tmpAB); + final float dotAC_AC = vec3Dot(tmpAC, tmpAC); + final float dotAC_AB = vec3Dot(tmpAC, tmpAB); + final float dotAB_AB = vec3Dot(tmpAB, tmpAB); // Compute barycentric coordinates final float invDenom = 1 / (dotAC_AC * dotAB_AB - dotAC_AB * dotAC_AB); { - computeVector(tmpAP, a, p1); //v2 - final float dotAC_AP1 = dot(tmpAC, tmpAP); - final float dotAB_AP1 = dot(tmpAB, tmpAP); + subVec3(tmpAP, p1, a); //v2 + final float dotAC_AP1 = vec3Dot(tmpAC, tmpAP); + final float dotAB_AP1 = vec3Dot(tmpAB, tmpAP); final float u1 = (dotAB_AB * dotAC_AP1 - dotAC_AB * dotAB_AP1) * invDenom; final float v1 = (dotAC_AC * dotAB_AP1 - dotAC_AB * dotAC_AP1) * invDenom; @@ -513,9 +499,9 @@ public class VectorUtil { } { - computeVector(tmpAP, a, p2); //v2 - final float dotAC_AP2 = dot(tmpAC, tmpAP); - final float dotAB_AP2 = dot(tmpAB, tmpAP); + subVec3(tmpAP, p1, a); //v2 + final float dotAC_AP2 = vec3Dot(tmpAC, tmpAP); + final float dotAB_AP2 = vec3Dot(tmpAB, tmpAP); final float u = (dotAB_AB * dotAC_AP2 - dotAC_AB * dotAB_AP2) * invDenom; final float v = (dotAC_AC * dotAB_AP2 - dotAC_AB * dotAC_AP2) * invDenom; @@ -526,9 +512,9 @@ public class VectorUtil { } { - computeVector(tmpAP, a, p3); //v2 - final float dotAC_AP3 = dot(tmpAC, tmpAP); - final float dotAB_AP3 = dot(tmpAB, tmpAP); + subVec3(tmpAP, p2, a); //v2 + final float dotAC_AP3 = vec3Dot(tmpAC, tmpAP); + final float dotAB_AP3 = vec3Dot(tmpAB, tmpAP); final float u = (dotAB_AB * dotAC_AP3 - dotAC_AB * dotAB_AP3) * invDenom; final float v = (dotAC_AC * dotAB_AP3 - dotAC_AB * dotAC_AP3) * invDenom; @@ -655,7 +641,9 @@ public class VectorUtil { * @return the intersection coordinates if the lines intersect, otherwise * returns null */ - public static float[] line2lineIntersection(final float[] result, final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { + public static float[] line2lineIntersection(final float[] result, + final Vert2fImmutable a, final Vert2fImmutable b, + final Vert2fImmutable c, final Vert2fImmutable d) { final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX()); if (determinant == 0) @@ -680,7 +668,8 @@ public class VectorUtil { * @param e vertex 2 of first segment * @return true if the segment intersects at least one segment of the triangle, false otherwise */ - public static boolean testTri2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d, final Vert2fImmutable e){ + public static boolean testTri2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, + final Vert2fImmutable d, final Vert2fImmutable e){ return testSeg2SegIntersection(a, b, d, e) || testSeg2SegIntersection(b, c, d, e) || testSeg2SegIntersection(a, c, d, e) ; diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java index 23edfd6e7..3be8a77f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java +++ b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java @@ -245,8 +245,9 @@ public class AABBox implements Cloneable { resize(xyz[0], xyz[1], xyz[2]); } - /** Check if the x & y coordinates are bounded/contained - * by this AABBox + /** + * Check if the x & y coordinates are bounded/contained + * by this AABBox * @param x x-axis coordinate value * @param y y-axis coordinate value * @return true if x belong to (low.x, high.x) and @@ -262,8 +263,9 @@ public class AABBox implements Cloneable { return true; } - /** Check if the xyz coordinates are bounded/contained - * by this AABBox. + /** + * Check if the xyz coordinates are bounded/contained + * by this AABBox. * @param x x-axis coordinate value * @param y y-axis coordinate value * @param z z-axis coordinate value @@ -283,8 +285,9 @@ public class AABBox implements Cloneable { return true; } - /** Check if there is a common region between this AABBox and the passed - * 2D region irrespective of z range + /** + * Check if there is a common region between this AABBox and the passed + * 2D region irrespective of z range * @param x lower left x-coord * @param y lower left y-coord * @param w width @@ -316,7 +319,7 @@ public class AABBox implements Cloneable { * @return a float representing the size of the AABBox */ public final float getSize() { - return VectorUtil.computeLength(low, high); + return VectorUtil.vec3Distance(low, high); } /**Get the Center of the AABBox @@ -336,15 +339,15 @@ public class AABBox implements Cloneable { tmpV3[1] = high[1] - center[1]; tmpV3[2] = high[2] - center[2]; - VectorUtil.scale(tmpV3, tmpV3, size); // in-place scale - VectorUtil.vectorAdd(high, center, tmpV3); + VectorUtil.scaleVec3(tmpV3, tmpV3, size); // in-place scale + VectorUtil.addVec3(high, center, tmpV3); tmpV3[0] = low[0] - center[0]; tmpV3[1] = low[1] - center[1]; tmpV3[2] = low[2] - center[2]; - VectorUtil.scale(tmpV3, tmpV3, size); // in-place scale - VectorUtil.vectorAdd(low, center, tmpV3); + VectorUtil.scaleVec3(tmpV3, tmpV3, size); // in-place scale + VectorUtil.addVec3(low, center, tmpV3); } public final float getMinX() { @@ -396,9 +399,9 @@ public class AABBox implements Cloneable { if( null == obj || !(obj instanceof AABBox) ) { return false; } - final AABBox other = (AABBox) obj; - return VectorUtil.checkEquality(low, other.low) && - VectorUtil.checkEquality(high, other.high) ; + final AABBox other = (AABBox) obj; + return VectorUtil.isVec2Equal(low, 0, other.low, 0, FloatUtil.EPSILON) && + VectorUtil.isVec3Equal(high, 0, other.high, 0, FloatUtil.EPSILON) ; } /** diff --git a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java index 5810e3bc9..f96726e5b 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java @@ -192,20 +192,20 @@ public class Loop { float minDistance = Float.MAX_VALUE; boolean inValid = false; - ArrayList initVertices = initialOutline.getGraphPoint(); - ArrayList vertices = polyline.getGraphPoint(); + final ArrayList initVertices = initialOutline.getGraphPoint(); + final ArrayList vertices = polyline.getGraphPoint(); for(int i=0; i< initVertices.size()-1; i++){ - GraphVertex v = initVertices.get(i); - GraphVertex nextV = initVertices.get(i+1); + final GraphVertex v = initVertices.get(i); + final GraphVertex nextV = initVertices.get(i+1); for(int pos=0; pos d "+delta+", exp "+expWE+", equal "+equalWE+", comp "+compWE+" - "+msgWE+", epsilon "+EPSILON); + } + private void dumpTestNE(int tstNum, int exp, final float a, final float b) { + final float delta = a-b; + final boolean equal = FloatUtil.isEqual(a, b); + final int comp = FloatUtil.compare(a, b); + final String msg = ( exp != comp ) ? "**** mismatch ****" : " OK"; + System.err.println("Print.NE."+tstNum+": a: "+a+", b: "+b+" -> d "+delta+", exp "+exp+", equal "+equal+", comp "+comp+" - "+msg); + } + + @Test + public void test01aZeroWithFixedEpsilon() { + testZeroWithEpsilon(10, FloatUtil.EPSILON); + } + @Test + public void test01bZeroWithMachEpsilon() { + testZeroWithEpsilon(100, MACH_EPSILON); + } + private void testZeroWithEpsilon(int i, final float EPSILON) { + System.err.println(); + testZeroWithEpsilon(i++, true, 0f, EPSILON); + testZeroWithEpsilon(i++, true, 0f-EPSILON/2f, EPSILON); + testZeroWithEpsilon(i++, true, 0f+EPSILON/2f, EPSILON); + testZeroWithEpsilon(i++, true, 0f-Float.MIN_VALUE, EPSILON); + testZeroWithEpsilon(i++, true, 0f+Float.MIN_VALUE, EPSILON); + testZeroWithEpsilon(i++, true, -0f, EPSILON); + testZeroWithEpsilon(i++, true, +0f, EPSILON); + + testZeroWithEpsilon(i++, false, 0f+EPSILON+Float.MIN_VALUE, EPSILON); + testZeroWithEpsilon(i++, false, 0f-EPSILON-Float.MIN_VALUE, EPSILON); + + // Unpredicted .. accuracy beyond epsilon, or deltaMachEpsLEQEpsilon or deltaFixedEpsLEQEpsilon; + dumpTestWE(i++, 1, 0f, 0f+EPSILON-Float.MIN_VALUE, EPSILON); + dumpTestWE(i++, 1, 0f, 0f-EPSILON+Float.MIN_VALUE, EPSILON); + } + private void testZeroWithEpsilon(int tstNum, boolean exp, final float a, final float EPSILON) { + final boolean zero = FloatUtil.isZero(a, EPSILON); + final float delta = a-0f; + System.err.println("Zero."+tstNum+": a: "+a+", -> d "+delta+", exp "+exp+", zero "+zero+", epsilon "+EPSILON); + Assert.assertEquals("Zero failed a: "+a+" within "+EPSILON, exp, zero); + } + + @Test + public void test02EqualsNoEpsilon() { + int i=0; + System.err.println(); + testEqualsNoEpsilon(i++, true, 0f, 0f); + + testEqualsNoEpsilon(i++, true, Float.MAX_VALUE, Float.MAX_VALUE); + testEqualsNoEpsilon(i++, true, Float.MIN_VALUE, Float.MIN_VALUE); + testEqualsNoEpsilon(i++, true, Float.MIN_NORMAL, Float.MIN_NORMAL); + testEqualsNoEpsilon(i++, true, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + testEqualsNoEpsilon(i++, true, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); + testEqualsNoEpsilon(i++, true, Float.NaN, Float.NaN); + testEqualsNoEpsilon(i++, false, -0f, 0f); + testEqualsNoEpsilon(i++, false, 0f, -0f); + + // Unpredicted .. accuracy beyond epsilon, or deltaMachEpsLEQEpsilon or deltaFixedEpsLEQEpsilon; + dumpTestNE(i++, 0, 1f, 1f-MACH_EPSILON/2f); + dumpTestNE(i++, 0, 0f, 0f-MACH_EPSILON/2f); + dumpTestNE(i++, 0, 1f, 1f+MACH_EPSILON/2f); + dumpTestNE(i++, 0, 0f, 0f+MACH_EPSILON/2f); + dumpTestNE(i++, 0, 1f, 1f-Float.MIN_VALUE); + dumpTestNE(i++, 0, 0f, 0f-Float.MIN_VALUE); + dumpTestNE(i++, 0, 1f, 1f+Float.MIN_VALUE); + dumpTestNE(i++, 0, 0f, 0f+Float.MIN_VALUE); + } + private void testEqualsNoEpsilon(int tstNum, boolean exp, final float a, final float b) { + final boolean equal = FloatUtil.isEqual(a, b); + final int comp = FloatUtil.compare(a, b); + final float delta = a-b; + System.err.println("Equal.NE."+tstNum+": a: "+a+", b: "+b+" -> d "+delta+", exp "+exp+", equal "+equal+", comp "+comp); + Assert.assertEquals("Compare failed a: "+a+", b: "+b, exp, 0==comp); + Assert.assertEquals("Equal failed a: "+a+", b: "+b, exp, equal); + } + + @Test + public void test03aEqualsWithFixedEpsilon() { + testEqualsWithEpsilon(10, FloatUtil.EPSILON); } + @Test + public void test03bEqualsWithMachEpsilon() { + testEqualsWithEpsilon(50, MACH_EPSILON); + } + private void testEqualsWithEpsilon(int i, final float EPSILON) { + System.err.println(); + testEqualsWithEpsilon(i++, true, 0f, 0f, EPSILON); + testEqualsWithEpsilon(i++, true, 1f, 1f-EPSILON/2f, EPSILON); + testEqualsWithEpsilon(i++, true, 1f, 1f+EPSILON/2f, EPSILON); + testEqualsWithEpsilon(i++, true, 1f, 1f-Float.MIN_VALUE, EPSILON); + testEqualsWithEpsilon(i++, true, 1f, 1f+Float.MIN_VALUE, EPSILON); + testEqualsWithEpsilon(i++, true, Float.MAX_VALUE, Float.MAX_VALUE, EPSILON); + testEqualsWithEpsilon(i++, true, Float.MIN_VALUE, Float.MIN_VALUE, EPSILON); + testEqualsWithEpsilon(i++, true, Float.MIN_NORMAL, Float.MIN_NORMAL, EPSILON); + testEqualsWithEpsilon(i++, true, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, EPSILON); + testEqualsWithEpsilon(i++, true, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, EPSILON); + testEqualsWithEpsilon(i++, true, Float.NaN, Float.NaN, EPSILON); + testEqualsWithEpsilon(i++, true, -0f, 0f, EPSILON); + testEqualsWithEpsilon(i++, true, 0f, -0f, EPSILON); + + testEqualsWithEpsilon(i++, false, 1f, 1f+EPSILON+Float.MIN_VALUE, EPSILON); + testEqualsWithEpsilon(i++, false, 1f, 1f-EPSILON-Float.MIN_VALUE, EPSILON); + + // Unpredicted .. accuracy beyond epsilon, or deltaMachEpsLEQEpsilon or deltaFixedEpsLEQEpsilon; + dumpTestWE(i++, 1, 1f, 1f+EPSILON-Float.MIN_VALUE, EPSILON); + dumpTestWE(i++, 1, 1f, 1f-EPSILON+Float.MIN_VALUE, EPSILON); + } + private void testEqualsWithEpsilon(int tstNum, boolean exp, final float a, final float b, final float EPSILON) { + final boolean equal = FloatUtil.isEqual(a, b, EPSILON); + final int comp = FloatUtil.compare(a, b, EPSILON); + final float delta = a-b; + System.err.println("Equal.WE."+tstNum+": a: "+a+", b: "+b+" -> d "+delta+", exp "+exp+", equal "+equal+", comp "+comp); + Assert.assertEquals("Compare failed a: "+a+", b: "+b+" within "+EPSILON, exp, 0==comp); + Assert.assertEquals("Equal failed a: "+a+", b: "+b+" within "+EPSILON, exp, equal); + } + + @Test + public void test04CompareNoEpsilon() { + int i=0; + System.err.println(); + testCompareNoEpsilon(i++, 0, 0f, 0f); + testCompareNoEpsilon(i++, 0, Float.MAX_VALUE, Float.MAX_VALUE); + testCompareNoEpsilon(i++, 0, Float.MIN_VALUE, Float.MIN_VALUE); + testCompareNoEpsilon(i++, 0, Float.MIN_NORMAL, Float.MIN_NORMAL); + testCompareNoEpsilon(i++, 0, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + testCompareNoEpsilon(i++, 0, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); + testCompareNoEpsilon(i++, 0, Float.NaN, Float.NaN); + + testCompareNoEpsilon(i++, 1, 1f, 0f); + testCompareNoEpsilon(i++, -1, 0f, 1f); + testCompareNoEpsilon(i++, 1, 0f, -1f); + testCompareNoEpsilon(i++, -1, -1f, 0f); + + testCompareNoEpsilon(i++, 1, Float.MAX_VALUE, Float.MIN_VALUE); + testCompareNoEpsilon(i++, -1, Float.MIN_VALUE, Float.MAX_VALUE); + testCompareNoEpsilon(i++, 1, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY); + testCompareNoEpsilon(i++, -1, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); + + testCompareNoEpsilon(i++, -1, 0f, Float.NaN); + testCompareNoEpsilon(i++, 1, Float.NaN, 0f); + + testCompareNoEpsilon(i++, -1, -0f, 0f); + testCompareNoEpsilon(i++, 1, 0f, -0f); + + // Unpredicted .. accuracy beyond epsilon, or deltaMachEpsLEQEpsilon or deltaFixedEpsLEQEpsilon; + dumpTestNE(i++, 0, 1f, 1f-MACH_EPSILON/2f); + dumpTestNE(i++, 0, 0f, 0f-MACH_EPSILON/2f); + dumpTestNE(i++, 0, 1f, 1f+MACH_EPSILON/2f); + dumpTestNE(i++, 0, 0f, 0f+MACH_EPSILON/2f); + dumpTestNE(i++, 0, 1f, 1f-Float.MIN_VALUE); + dumpTestNE(i++, 0, 0f, 0f-Float.MIN_VALUE); + dumpTestNE(i++, 0, 1f, 1f+Float.MIN_VALUE); + dumpTestNE(i++, 0, 0f, 0f+Float.MIN_VALUE); + } + private void testCompareNoEpsilon(int tstNum, final int exp, final float a, final float b) { + final boolean equal = FloatUtil.isEqual(a, b); + final int comp = FloatUtil.compare(a, b); + final float delta = a-b; + System.err.println("Comp.NE."+tstNum+": a: "+a+", b: "+b+" -> d "+delta+", equal "+equal+", comp: exp "+exp+" has "+comp); + Assert.assertEquals("Compare failed a: "+a+", b: "+b, exp, comp); + } + + @Test + public void test05aCompareWithFixedEpsilon() { + test05CompareWithEpsilon(10, FloatUtil.EPSILON); + } + @Test + public void test05bCompareWithMachEpsilon() { + test05CompareWithEpsilon(50, MACH_EPSILON); + } + private void test05CompareWithEpsilon(int i, final float EPSILON) { + System.err.println(); + testCompareWithEpsilon(i++, 0, 0f, 0f, EPSILON); + testCompareWithEpsilon(i++, 0, 1f, 1f-EPSILON/2f, EPSILON); + testCompareWithEpsilon(i++, 0, 1f, 1f+EPSILON/2f, EPSILON); + testCompareWithEpsilon(i++, 0, 1f, 1f-Float.MIN_VALUE, EPSILON); + testCompareWithEpsilon(i++, 0, 1f, 1f+Float.MIN_VALUE, EPSILON); + testCompareWithEpsilon(i++, 0, Float.MAX_VALUE, Float.MAX_VALUE, EPSILON); + testCompareWithEpsilon(i++, 0, Float.MIN_VALUE, Float.MIN_VALUE, EPSILON); + testCompareWithEpsilon(i++, 0, Float.MIN_NORMAL, Float.MIN_NORMAL, EPSILON); + testCompareWithEpsilon(i++, 0, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, EPSILON); + testCompareWithEpsilon(i++, 0, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, EPSILON); + testCompareWithEpsilon(i++, 0, Float.NaN, Float.NaN, EPSILON); + + testCompareWithEpsilon(i++, 1, 1f, 0f, EPSILON); + testCompareWithEpsilon(i++, -1, 0f, 1f, EPSILON); + testCompareWithEpsilon(i++, 1, 0f, -1f, EPSILON); + testCompareWithEpsilon(i++, -1, -1f, 0f, EPSILON); + + testCompareWithEpsilon(i++, 1, Float.MAX_VALUE, Float.MIN_VALUE, EPSILON); + testCompareWithEpsilon(i++, -1, Float.MIN_VALUE, Float.MAX_VALUE, EPSILON); + testCompareWithEpsilon(i++, 1, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, EPSILON); + testCompareWithEpsilon(i++, -1, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, EPSILON); + + testCompareWithEpsilon(i++, -1, 0f,Float.NaN, EPSILON); + testCompareWithEpsilon(i++, 1, Float.NaN, 0f, EPSILON); + + testCompareWithEpsilon(i++, 0, -0f, 0f, EPSILON); + testCompareWithEpsilon(i++, 0, 0f, -0f, EPSILON); + } + private void testCompareWithEpsilon(int tstNum, final int exp, final float a, final float b, float EPSILON) { + final boolean equal = FloatUtil.isEqual(a, b, EPSILON); + final int comp = FloatUtil.compare(a, b, EPSILON); + final float delta = a-b; + System.err.println("Comp.WE."+tstNum+": a: "+a+", b: "+b+" -> d "+delta+", equal "+equal+", comp: exp "+exp+" has "+comp); + Assert.assertEquals("Compare failed a: "+a+", b: "+b+" within "+EPSILON, exp, comp); + } + public static void main(String args[]) { org.junit.runner.JUnitCore.main(TestFloatUtil01NOUI.class.getName()); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestQuaternion01NOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestQuaternion01NOUI.java index 0f47f5889..19758539b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestQuaternion01NOUI.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestQuaternion01NOUI.java @@ -123,10 +123,10 @@ public class TestQuaternion01NOUI { quat1.rotateVector(vecOut1, 0, ONE, 0); quat2.rotateVector(vecOut2, 0, ONE, 0); Assert.assertArrayEquals(vecOut1, vecOut2, FloatUtil.EPSILON); - Assert.assertEquals(0f, Math.abs( VectorUtil.distance(vecOut1, vecOut2) ), FloatUtil.EPSILON ); + Assert.assertEquals(0f, Math.abs( VectorUtil.vec3Distance(vecOut1, vecOut2) ), FloatUtil.EPSILON ); quat1.rotateVector(vecOut1, 0, UNIT_Z, 0); - Assert.assertEquals(0f, Math.abs( VectorUtil.distance(NEG_UNIT_Y, vecOut1) ), FloatUtil.EPSILON ); + Assert.assertEquals(0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Y, vecOut1) ), FloatUtil.EPSILON ); quat2.setFromAngleAxis(FloatUtil.HALF_PI, ZERO, tmpV3f); Assert.assertEquals(QUAT_IDENT, quat2); @@ -159,19 +159,19 @@ public class TestQuaternion01NOUI { quat.setFromVectors(UNIT_Z, NEG_UNIT_Z, tmp0V3f, tmp1V3f); quat.rotateVector(vecOut, 0, UNIT_Z, 0); // System.err.println("vecOut: "+Arrays.toString(vecOut)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_Z, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Z, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); quat.setFromVectors(UNIT_X, NEG_UNIT_X, tmp0V3f, tmp1V3f); quat.rotateVector(vecOut, 0, UNIT_X, 0); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); quat.setFromVectors(UNIT_Y, NEG_UNIT_Y, tmp0V3f, tmp1V3f); quat.rotateVector(vecOut, 0, UNIT_Y, 0); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_Y, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Y, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); quat.setFromVectors(ONE, NEG_ONE, tmp0V3f, tmp1V3f); quat.rotateVector(vecOut, 0, ONE, 0); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_ONE, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_ONE, vecOut) ), Quaternion.ALLOWED_DEVIANCE ); quat.setFromVectors(ZERO, ZERO, tmp0V3f, tmp1V3f); Assert.assertEquals(QUAT_IDENT, quat); @@ -230,17 +230,17 @@ public class TestQuaternion01NOUI { Assert.assertEquals(1.0f, quat.magnitude(), FloatUtil.EPSILON); final float[] v2 = quat.rotateVector(new float[3], 0, UNIT_X, 0); - Assert.assertEquals(0f, Math.abs(VectorUtil.distance(NEG_UNIT_Z, v2)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs(VectorUtil.vec3Distance(NEG_UNIT_Z, v2)), FloatUtil.EPSILON); quat.setFromEuler(0, 0, -FloatUtil.HALF_PI); Assert.assertEquals(1.0f, quat.magnitude(), FloatUtil.EPSILON); quat.rotateVector(v2, 0, UNIT_X, 0); - Assert.assertEquals(0f, Math.abs(VectorUtil.distance(NEG_UNIT_Y, v2)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs(VectorUtil.vec3Distance(NEG_UNIT_Y, v2)), FloatUtil.EPSILON); quat.setFromEuler(FloatUtil.HALF_PI, 0, 0); Assert.assertEquals(1.0f, quat.magnitude(), FloatUtil.EPSILON); quat.rotateVector(v2, 0, UNIT_Y, 0); - Assert.assertEquals(0f, Math.abs(VectorUtil.distance(UNIT_Z, v2)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs(VectorUtil.vec3Distance(UNIT_Z, v2)), FloatUtil.EPSILON); } @Test @@ -278,13 +278,13 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, UNIT_Y, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(UNIT_Z, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(UNIT_Z, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); } quat.setFromMatrix(mat1, 0); quat.rotateVector(vecHas, 0, UNIT_Y, 0); // System.err.println("exp0 "+Arrays.toString(UNIT_Z)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(UNIT_Z, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(UNIT_Z, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); quat.toMatrix(mat2, 0); // System.err.println(FloatUtil.matrixToString(null, null, "%10.5f", mat1, 0, mat2, 0, 4, 4, false).toString()); @@ -292,7 +292,7 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, NEG_ONE, 0); FloatUtil.multMatrixVecf(mat2, NEG_ONE_v4, vecOut2); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); // // 180 degrees rotation on X @@ -312,13 +312,13 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, UNIT_Y, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_Y, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Y, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); } quat.setFromMatrix(mat1, 0); quat.rotateVector(vecHas, 0, UNIT_Y, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_Y)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_Y, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Y, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); quat.toMatrix(mat2, 0); // System.err.println(FloatUtil.matrixToString(null, null, "%10.5f", mat1, 0, mat2, 0, 4, 4, false).toString()); @@ -326,7 +326,7 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, ONE, 0); FloatUtil.multMatrixVecf(mat2, ONE_v4, vecOut2); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); // // 180 degrees rotation on Y @@ -346,13 +346,13 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); } quat.setFromMatrix(mat1, 0); quat.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); quat.toMatrix(mat2, 0); // System.err.println(FloatUtil.matrixToString(null, "matr-rot", "%10.5f", mat1, 0, mat2, 0, 4, 4, false).toString()); @@ -360,7 +360,7 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, NEG_ONE, 0); FloatUtil.multMatrixVecf(mat2, NEG_ONE_v4, vecOut2); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); // // 180 degrees rotation on Z @@ -380,13 +380,13 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); } quat.setFromMatrix(mat1, 0); quat.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecHas) ), Quaternion.ALLOWED_DEVIANCE ); quat.toMatrix(mat2, 0); // System.err.println(FloatUtil.matrixToString(null, "matr-rot", "%10.5f", mat1, 0, mat2, 0, 4, 4, false).toString()); @@ -394,7 +394,7 @@ public class TestQuaternion01NOUI { quat.rotateVector(vecHas, 0, ONE, 0); FloatUtil.multMatrixVecf(mat2, ONE_v4, vecOut2); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecHas, vecOut2) ), Quaternion.ALLOWED_DEVIANCE ); // // Test Matrix-Columns @@ -413,19 +413,19 @@ public class TestQuaternion01NOUI { quat.copyMatrixColumn(0, vecCol, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)); // System.err.println("has0 "+Arrays.toString(vecCol)); - Assert.assertEquals(0f, Math.abs( VectorUtil.distance(vecExp, vecCol)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs( VectorUtil.vec3Distance(vecExp, vecCol)), FloatUtil.EPSILON); FloatUtil.copyMatrixColumn(mat1, 0, 1, vecExp, 0); quat.copyMatrixColumn(1, vecCol, 0); // System.err.println("exp1 "+Arrays.toString(vecExp)); // System.err.println("has1 "+Arrays.toString(vecCol)); - Assert.assertEquals(0f, Math.abs( VectorUtil.distance(vecExp, vecCol)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs( VectorUtil.vec3Distance(vecExp, vecCol)), FloatUtil.EPSILON); FloatUtil.copyMatrixColumn(mat1, 0, 2, vecExp, 0); quat.copyMatrixColumn(2, vecCol, 0); // System.err.println("exp2 "+Arrays.toString(vecExp)); // System.err.println("has2 "+Arrays.toString(vecCol)); - Assert.assertEquals(0f, Math.abs( VectorUtil.distance(vecExp, vecCol)), FloatUtil.EPSILON); + Assert.assertEquals(0f, Math.abs( VectorUtil.vec3Distance(vecExp, vecCol)), FloatUtil.EPSILON); quat.set(0f, 0f, 0f, 0f); Assert.assertArrayEquals(UNIT_X, quat.copyMatrixColumn(0, vecCol, 0), FloatUtil.EPSILON); @@ -563,18 +563,18 @@ public class TestQuaternion01NOUI { final float[] vecOut = new float[3]; quat2.rotateVector(vecOut, 0, UNIT_Z, 0); - Assert.assertTrue( Math.abs( VectorUtil.distance(UNIT_X, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); + Assert.assertTrue( Math.abs( VectorUtil.vec3Distance(UNIT_X, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); quat2.setFromAngleNormalAxis(FloatUtil.HALF_PI, UNIT_Y); // 90 degr on Y quat1.mult(quat1); // q1 = q1 * q1 -> 2 * 45 degr -> 90 degr on Y quat1.mult(quat2); // q1 = q1 * q2 -> 2 * 90 degr -> 180 degr on Y quat1.rotateVector(vecOut, 0, UNIT_Z, 0); - Assert.assertTrue( Math.abs( VectorUtil.distance(NEG_UNIT_Z, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); + Assert.assertTrue( Math.abs( VectorUtil.vec3Distance(NEG_UNIT_Z, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); quat2.setFromEuler(0f, FloatUtil.HALF_PI, 0f); quat1.mult(quat2); // q1 = q1 * q2 = q1 * rotMat(0, 90degr, 0) quat1.rotateVector(vecOut, 0, UNIT_Z, 0); - Assert.assertTrue( Math.abs( VectorUtil.distance(NEG_UNIT_X, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); + Assert.assertTrue( Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecOut)) <= Quaternion.ALLOWED_DEVIANCE); } @Test @@ -645,7 +645,7 @@ public class TestQuaternion01NOUI { // put together matrix, then apply to vector, so YZX worker.rotateByAngleY(FloatUtil.QUARTER_PI).rotateByAngleZ(FloatUtil.PI).rotateByAngleX(FloatUtil.HALF_PI); quat.rotateVector(vecExp, 0, vecExp, 0); - Assert.assertEquals(0f, VectorUtil.distance(vecExp, vecRot), FloatUtil.EPSILON); + Assert.assertEquals(0f, VectorUtil.vec3Distance(vecExp, vecRot), FloatUtil.EPSILON); // test axis rotation methods against general purpose // X AXIS @@ -655,7 +655,7 @@ public class TestQuaternion01NOUI { worker.setIdentity().rotateByAngleNormalAxis(FloatUtil.QUARTER_PI, 1f, 0f, 0f).rotateVector(vecRot, 0, vecRot, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)+", len "+VectorUtil.length(vecExp)); // System.err.println("has0 "+Arrays.toString(vecRot)+", len "+VectorUtil.length(vecRot)); - Assert.assertEquals(0f, VectorUtil.distance(vecExp, vecRot), FloatUtil.EPSILON); + Assert.assertEquals(0f, VectorUtil.vec3Distance(vecExp, vecRot), FloatUtil.EPSILON); // Y AXIS vecExp = new float[] { 1f, 1f, 1f }; @@ -664,7 +664,7 @@ public class TestQuaternion01NOUI { worker.setIdentity().rotateByAngleNormalAxis(FloatUtil.QUARTER_PI, 0f, 1f, 0f).rotateVector(vecRot, 0, vecRot, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)); // System.err.println("has0 "+Arrays.toString(vecRot)); - Assert.assertEquals(0f, VectorUtil.distance(vecExp, vecRot), FloatUtil.EPSILON); + Assert.assertEquals(0f, VectorUtil.vec3Distance(vecExp, vecRot), FloatUtil.EPSILON); // Z AXIS vecExp = new float[] { 1f, 1f, 1f }; @@ -673,7 +673,7 @@ public class TestQuaternion01NOUI { worker.setIdentity().rotateByAngleNormalAxis(FloatUtil.QUARTER_PI, 0f, 0f, 1f).rotateVector(vecRot, 0, vecRot, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)); // System.err.println("has0 "+Arrays.toString(vecRot)); - Assert.assertEquals(0f, VectorUtil.distance(vecExp, vecRot), FloatUtil.EPSILON); + Assert.assertEquals(0f, VectorUtil.vec3Distance(vecExp, vecRot), FloatUtil.EPSILON); quat.set(worker); worker.rotateByAngleNormalAxis(0f, 0f, 0f, 0f); @@ -716,7 +716,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_Z, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecExp, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecExp, vecHas)), Quaternion.ALLOWED_DEVIANCE); // delta == 100% quat2.setIdentity().rotateByAngleZ(FloatUtil.PI); // angle: 180 degrees, axis Z @@ -725,7 +725,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(NEG_UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(NEG_UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(NEG_UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); quat2.setIdentity().rotateByAngleZ(FloatUtil.PI); // angle: 180 degrees, axis Z // System.err.println("Slerp #03: 1/2 * 180 degrees Z"); @@ -733,7 +733,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(UNIT_Y)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(UNIT_Y, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(UNIT_Y, vecHas)), Quaternion.ALLOWED_DEVIANCE); // delta == 0% quat2.setIdentity().rotateByAngleZ(FloatUtil.PI); // angle: 180 degrees, axis Z @@ -742,7 +742,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); // a==b quat2.setIdentity(); @@ -751,7 +751,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_X, 0); // System.err.println("exp0 "+Arrays.toString(UNIT_X)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(UNIT_X, vecHas)), Quaternion.ALLOWED_DEVIANCE); // negative dot product vecExp = new float[] { 0f, -FloatUtil.sin(FloatUtil.QUARTER_PI), FloatUtil.sin(FloatUtil.QUARTER_PI) }; @@ -762,7 +762,7 @@ public class TestQuaternion01NOUI { quatS.rotateVector(vecHas, 0, UNIT_Y, 0); // System.err.println("exp0 "+Arrays.toString(vecExp)); // System.err.println("has0 "+Arrays.toString(vecHas)); - Assert.assertEquals( 0f, Math.abs( VectorUtil.distance(vecExp, vecHas)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals( 0f, Math.abs( VectorUtil.vec3Distance(vecExp, vecHas)), Quaternion.ALLOWED_DEVIANCE); } @@ -778,37 +778,37 @@ public class TestQuaternion01NOUI { if( DEBUG ) System.err.println("LookAt #01"); VectorUtil.copyVec3(direction, 0, NEG_UNIT_X, 0); final Quaternion quat = new Quaternion().setLookAt(direction, UNIT_Y, xAxis, yAxis, zAxis); - Assert.assertEquals(0f, VectorUtil.distance(direction, quat.rotateVector(vecHas, 0, UNIT_Z, 0)), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals(0f, VectorUtil.vec3Distance(direction, quat.rotateVector(vecHas, 0, UNIT_Z, 0)), Quaternion.ALLOWED_DEVIANCE); if( DEBUG ) System.err.println("LookAt #02"); - VectorUtil.normalize(VectorUtil.copyVec3(direction, 0, ONE, 0)); + VectorUtil.normalizeVec3(VectorUtil.copyVec3(direction, 0, ONE, 0)); quat.setLookAt(direction, UNIT_Y, xAxis, yAxis, zAxis); if( DEBUG )System.err.println("quat0 "+quat); quat.rotateVector(vecHas, 0, UNIT_Z, 0); if( DEBUG ) { - System.err.println("xAxis "+Arrays.toString(xAxis)+", len "+VectorUtil.length(xAxis)); - System.err.println("yAxis "+Arrays.toString(yAxis)+", len "+VectorUtil.length(yAxis)); - System.err.println("zAxis "+Arrays.toString(zAxis)+", len "+VectorUtil.length(zAxis)); - System.err.println("exp0 "+Arrays.toString(direction)+", len "+VectorUtil.length(direction)); - System.err.println("has0 "+Arrays.toString(vecHas)+", len "+VectorUtil.length(vecHas)); + System.err.println("xAxis "+Arrays.toString(xAxis)+", len "+VectorUtil.vec3Length(xAxis)); + System.err.println("yAxis "+Arrays.toString(yAxis)+", len "+VectorUtil.vec3Length(yAxis)); + System.err.println("zAxis "+Arrays.toString(zAxis)+", len "+VectorUtil.vec3Length(zAxis)); + System.err.println("exp0 "+Arrays.toString(direction)+", len "+VectorUtil.vec3Length(direction)); + System.err.println("has0 "+Arrays.toString(vecHas)+", len "+VectorUtil.vec3Length(vecHas)); } // Assert.assertEquals(0f, VectorUtil.distance(direction, quat.rotateVector(vecHas, 0, UNIT_Z, 0)), Quaternion.ALLOWED_DEVIANCE); - Assert.assertEquals(0f, VectorUtil.distance(direction, vecHas), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals(0f, VectorUtil.vec3Distance(direction, vecHas), Quaternion.ALLOWED_DEVIANCE); if( DEBUG )System.err.println("LookAt #03"); - VectorUtil.normalize(VectorUtil.copyVec3(direction, 0, new float[] { -1f, 2f, -1f }, 0)); + VectorUtil.normalizeVec3(VectorUtil.copyVec3(direction, 0, new float[] { -1f, 2f, -1f }, 0)); quat.setLookAt(direction, UNIT_Y, xAxis, yAxis, zAxis); if( DEBUG )System.err.println("quat0 "+quat); quat.rotateVector(vecHas, 0, UNIT_Z, 0); if( DEBUG ) { - System.err.println("xAxis "+Arrays.toString(xAxis)+", len "+VectorUtil.length(xAxis)); - System.err.println("yAxis "+Arrays.toString(yAxis)+", len "+VectorUtil.length(yAxis)); - System.err.println("zAxis "+Arrays.toString(zAxis)+", len "+VectorUtil.length(zAxis)); - System.err.println("exp0 "+Arrays.toString(direction)+", len "+VectorUtil.length(direction)); - System.err.println("has0 "+Arrays.toString(vecHas)+", len "+VectorUtil.length(vecHas)); + System.err.println("xAxis "+Arrays.toString(xAxis)+", len "+VectorUtil.vec3Length(xAxis)); + System.err.println("yAxis "+Arrays.toString(yAxis)+", len "+VectorUtil.vec3Length(yAxis)); + System.err.println("zAxis "+Arrays.toString(zAxis)+", len "+VectorUtil.vec3Length(zAxis)); + System.err.println("exp0 "+Arrays.toString(direction)+", len "+VectorUtil.vec3Length(direction)); + System.err.println("has0 "+Arrays.toString(vecHas)+", len "+VectorUtil.vec3Length(vecHas)); } // Assert.assertEquals(0f, VectorUtil.distance(direction, quat.rotateVector(vecHas, 0, UNIT_Z, 0)), Quaternion.ALLOWED_DEVIANCE); - Assert.assertEquals(0f, VectorUtil.distance(direction, vecHas), Quaternion.ALLOWED_DEVIANCE); + Assert.assertEquals(0f, VectorUtil.vec3Distance(direction, vecHas), Quaternion.ALLOWED_DEVIANCE); } public static void main(String args[]) { -- cgit v1.2.3