day3 (german!) libs
This commit is contained in:
Executable
BIN
Binary file not shown.
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* b-spline source code from: Tim Lambert 'nice page on curves, splines etc.'
|
||||
* http://www.cse.unsw.edu.au/~lambert/splines/
|
||||
*/
|
||||
public abstract class BSpline {
|
||||
|
||||
/* the basis function for a cubic B spline */
|
||||
private static float b(int i, float t) {
|
||||
switch (i) {
|
||||
case -2:
|
||||
return (((-t + 3) * t - 3) * t + 1) / 6;
|
||||
case -1:
|
||||
return (((3 * t - 6) * t) * t + 4) / 6;
|
||||
case 0:
|
||||
return (((-3 * t + 3) * t + 3) * t + 1) / 6;
|
||||
case 1:
|
||||
return (t * t * t) / 6;
|
||||
}
|
||||
return 0; //we only get here if an invalid i is specified
|
||||
}
|
||||
|
||||
|
||||
/* evaluate a point on the B spline */
|
||||
private static Vector3f p(Vector<Vector3f> thePoints, int i, float t) {
|
||||
Vector3f p = new Vector3f();
|
||||
for (int j = -2; j <= 1; j++) {
|
||||
p.x += b(j, t) * thePoints.get(i + j).x;
|
||||
p.y += b(j, t) * thePoints.get(i + j).y;
|
||||
p.z += b(j, t) * thePoints.get(i + j).z;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public static Vector<Vector3f> curve(Vector<Vector3f> thePoints, int theSteps, Vector<Vector3f> theResult) {
|
||||
for (int i = 2; i < thePoints.size() - 1; i++) {
|
||||
for (int j = 1; j <= theSteps; j++) {
|
||||
theResult.add(p(thePoints, i, j / (float) theSteps));
|
||||
}
|
||||
}
|
||||
return theResult;
|
||||
}
|
||||
|
||||
public static Vector<Vector3f> curve(Vector<Vector3f> thePoints, int theSteps) {
|
||||
return curve(thePoints, theSteps, new Vector<Vector3f>());
|
||||
}
|
||||
|
||||
public static Vector<Vector3f> closeCurve(Vector<Vector3f> thePoints) {
|
||||
/* copy points */
|
||||
Vector<Vector3f> myClosedPoints = new Vector<Vector3f>();
|
||||
for (int i = 0; i < thePoints.size(); i++) {
|
||||
myClosedPoints.add(thePoints.get(i));
|
||||
}
|
||||
|
||||
/* repeat first three points */
|
||||
if (thePoints.size() > 2) {
|
||||
myClosedPoints.add(thePoints.get(0));
|
||||
myClosedPoints.add(thePoints.get(1));
|
||||
myClosedPoints.add(thePoints.get(2));
|
||||
}
|
||||
return myClosedPoints;
|
||||
}
|
||||
}
|
||||
+916
@@ -0,0 +1,916 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* beware this is not really in good shape. i ll read my linear algebra book and
|
||||
* fix this class. someday. hopefully.
|
||||
*/
|
||||
public final class Intersection
|
||||
implements Serializable,
|
||||
Mathematik {
|
||||
|
||||
private static final long serialVersionUID = -5392974339890719551L;
|
||||
|
||||
private static final Vector3f h = new Vector3f();
|
||||
|
||||
private static final Vector3f s = new Vector3f();
|
||||
|
||||
private static final Vector3f q = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempEdge1 = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempEdge2 = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempNormal = new Vector3f();
|
||||
|
||||
private static final Vector3f pvec = new Vector3f();
|
||||
|
||||
private static final Vector3f tvec = new Vector3f();
|
||||
|
||||
private static final Vector3f qvec = new Vector3f();
|
||||
|
||||
public static boolean intersectRayPlane(final Ray3f theRay,
|
||||
final Plane3f thePlane,
|
||||
final Vector3f theResult,
|
||||
final boolean doPlanar,
|
||||
final boolean quad) {
|
||||
Vector3f diff = mathematik.Util.sub(theRay.origin, thePlane.origin); // mathematik.Util.sub(theRay.origin, v0);
|
||||
Vector3f edge1 = thePlane.vectorA; // mathematik.Util.sub(v1, v0);
|
||||
Vector3f edge2 = thePlane.vectorB; // mathematik.Util.sub(v2, v0);
|
||||
|
||||
Vector3f norm = thePlane.normal; //new Vector3f();
|
||||
|
||||
if (thePlane.normal == null) {
|
||||
thePlane.updateNormal();
|
||||
norm = thePlane.normal;
|
||||
}
|
||||
|
||||
float dirDotNorm = theRay.direction.dot(norm);
|
||||
float sign;
|
||||
if (dirDotNorm > EPSILON) {
|
||||
sign = 1;
|
||||
} else if (dirDotNorm < EPSILON) {
|
||||
sign = -1f;
|
||||
dirDotNorm = -dirDotNorm;
|
||||
} else {
|
||||
// ray and triangle are parallel
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3f myCross;
|
||||
myCross = new Vector3f();
|
||||
myCross.cross(diff, edge2);
|
||||
float dirDotDiffxEdge2 = sign * theRay.direction.dot(myCross);
|
||||
if (dirDotDiffxEdge2 > 0.0f) {
|
||||
myCross = new Vector3f();
|
||||
myCross.cross(edge1, diff);
|
||||
float dirDotEdge1xDiff = sign * theRay.direction.dot(myCross);
|
||||
if (dirDotEdge1xDiff >= 0.0f) {
|
||||
if (!quad ? dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm : dirDotEdge1xDiff <= dirDotNorm) {
|
||||
float diffDotNorm = -sign * diff.dot(norm);
|
||||
if (diffDotNorm >= 0.0f) {
|
||||
// ray intersects triangle
|
||||
// if storage vector is null, just return true,
|
||||
if (theResult == null) {
|
||||
return true;
|
||||
}
|
||||
// else fill in.
|
||||
float inv = 1f / dirDotNorm;
|
||||
float t = diffDotNorm * inv;
|
||||
if (!doPlanar) {
|
||||
theResult.set(theRay.origin);
|
||||
theResult.add(theRay.direction.x * t,
|
||||
theRay.direction.y * t,
|
||||
theRay.direction.z * t);
|
||||
} else {
|
||||
// these weights can be used to determine
|
||||
// interpolated values, such as texture coord.
|
||||
// eg. texcoord s,t at intersection point:
|
||||
// s = w0*s0 + w1*s1 + w2*s2;
|
||||
// t = w0*t0 + w1*t1 + w2*t2;
|
||||
float w1 = dirDotDiffxEdge2 * inv;
|
||||
float w2 = dirDotEdge1xDiff * inv;
|
||||
//float w0 = 1.0f - w1 - w2;
|
||||
theResult.set(t, w1, w2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @deprecated not in good state.
|
||||
// * @param v0 first point of the triangle.
|
||||
// * @param v1 second point of the triangle.
|
||||
// * @param v2 third point of the triangle.
|
||||
// * @param store storage vector - if null, no intersection is calc'd
|
||||
// * @param doPlanar true if we are calcing planar results.
|
||||
// * @param quad
|
||||
// * @return true if ray intersects triangle
|
||||
// */
|
||||
// public static boolean intersectRayTriangle(final Ray3f theRay,
|
||||
// final Vector3f v0,
|
||||
// final Vector3f v1,
|
||||
// final Vector3f v2,
|
||||
// final Vector3f store,
|
||||
// final boolean doPlanar,
|
||||
// final boolean quad) {
|
||||
// Vector3f diff = mathematik.Util.sub(theRay.origin, v0);
|
||||
// Vector3f edge1 = mathematik.Util.sub(v1, v0);
|
||||
// Vector3f edge2 = mathematik.Util.sub(v2, v0);
|
||||
// Vector3f norm = new Vector3f();
|
||||
// norm.cross(edge1, edge2);
|
||||
//
|
||||
// float dirDotNorm = theRay.direction.dot(norm);
|
||||
// float sign;
|
||||
// if (dirDotNorm > EPSILON) {
|
||||
// sign = 1;
|
||||
// } else if (dirDotNorm < EPSILON) {
|
||||
// sign = -1f;
|
||||
// dirDotNorm = -dirDotNorm;
|
||||
// } else {
|
||||
// // ray and triangle are parallel
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Vector3f myCross;
|
||||
// myCross = new Vector3f();
|
||||
// myCross.cross(diff, edge2);
|
||||
// float dirDotDiffxEdge2 = sign * theRay.direction.dot(myCross);
|
||||
// if (dirDotDiffxEdge2 > 0.0f) {
|
||||
// myCross = new Vector3f();
|
||||
// myCross.cross(edge1, diff);
|
||||
// float dirDotEdge1xDiff = sign * theRay.direction.dot(myCross);
|
||||
// if (dirDotEdge1xDiff >= 0.0f) {
|
||||
// if (!quad ? dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm : dirDotEdge1xDiff <= dirDotNorm) {
|
||||
// float diffDotNorm = -sign * diff.dot(norm);
|
||||
// if (diffDotNorm >= 0.0f) {
|
||||
// // ray intersects triangle
|
||||
// // if storage vector is null, just return true,
|
||||
// if (store == null) {
|
||||
// return true;
|
||||
// }
|
||||
// // else fill in.
|
||||
// float inv = 1f / dirDotNorm;
|
||||
// float t = diffDotNorm * inv;
|
||||
// if (!doPlanar) {
|
||||
// store.set(theRay.origin);
|
||||
// store.add(theRay.direction.x * t,
|
||||
// theRay.direction.y * t,
|
||||
// theRay.direction.z * t);
|
||||
// } else {
|
||||
// // these weights can be used to determine
|
||||
// // interpolated values, such as texture coord.
|
||||
// // eg. texcoord s,t at intersection point:
|
||||
// // s = w0*s0 + w1*s1 + w2*s2;
|
||||
// // t = w0*t0 + w1*t1 + w2*t2;
|
||||
// float w1 = dirDotDiffxEdge2 * inv;
|
||||
// float w2 = dirDotEdge1xDiff * inv;
|
||||
// //float w0 = 1.0f - w1 - w2;
|
||||
// store.set(t, w1, w2);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
/*
|
||||
* Practical Analysis of Optimized Ray-Triangle Intersection
|
||||
* Tomas Moeller
|
||||
* Department of Computer Engineering, Chalmers University of Technology, Sweden.
|
||||
*
|
||||
* code rewritten to do tests on the sign of the determinant
|
||||
* the division is before the test of the sign of the det
|
||||
* and one CROSS has been moved out from the if-else if-else
|
||||
* from -- http://www.cs.lth.se/home/Tomas_Akenine_Moller/raytri/raytri.c
|
||||
*/
|
||||
public static boolean intersectRayTriangle(final Vector3f orig,
|
||||
final Vector3f dir,
|
||||
final Vector3f vert0,
|
||||
final Vector3f vert1,
|
||||
final Vector3f vert2,
|
||||
float[] result) {
|
||||
final int T = 0;
|
||||
final int U = 1;
|
||||
final int V = 2;
|
||||
Vector3f edge1;
|
||||
Vector3f edge2;
|
||||
Vector3f tvec;
|
||||
Vector3f pvec;
|
||||
Vector3f qvec;
|
||||
float det;
|
||||
float inv_det;
|
||||
|
||||
/* find vectors for two edges sharing vert0 */
|
||||
edge1 = mathematik.Util.sub(vert1, vert0);
|
||||
edge2 = mathematik.Util.sub(vert2, vert0);
|
||||
|
||||
/* begin calculating determinant - also used to calculate U parameter */
|
||||
pvec = mathematik.Util.cross(dir, edge2);
|
||||
|
||||
/* if determinant is near zero, ray lies in plane of triangle */
|
||||
det = edge1.dot(pvec);
|
||||
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
tvec = mathematik.Util.sub(orig, vert0);
|
||||
inv_det = 1.0f / det;
|
||||
|
||||
qvec = mathematik.Util.cross(tvec, edge1);
|
||||
|
||||
if (det > EPSILON) {
|
||||
result[U] = tvec.dot(pvec);
|
||||
if (result[U] < 0.0f || result[U] > det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
result[V] = dir.dot(qvec);
|
||||
if (result[V] < 0.0f || result[U] + result[V] > det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (det < -EPSILON) {
|
||||
/* calculate U parameter and test bounds */
|
||||
result[U] = tvec.dot(pvec);
|
||||
if (result[U] > 0.0f || result[U] < det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
result[V] = dir.dot(qvec);
|
||||
if (result[V] > 0.0f || result[U] + result[V] < det) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false; /* ray is parallell to the plane of the triangle */
|
||||
}
|
||||
|
||||
result[T] = edge2.dot(qvec) * inv_det;
|
||||
result[U] *= inv_det;
|
||||
result[V] *= inv_det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* grabbed from Xith
|
||||
*
|
||||
* @todo not sure whether this is for ray-plane or line-plane intersection.
|
||||
* but i think it s for latter, hence the method name.
|
||||
*
|
||||
* @param thePlane Plane3f
|
||||
* @param theRay Ray3f
|
||||
* @param theIntersectionPoint Vector3f
|
||||
* @return float
|
||||
*/
|
||||
public static float intersectLinePlane(final Ray3f theRay,
|
||||
final Plane3f thePlane,
|
||||
final Vector3f theIntersectionPoint) {
|
||||
double time = 0;
|
||||
_myTempNormal.cross(thePlane.vectorA, thePlane.vectorB);
|
||||
double denom = _myTempNormal.dot(theRay.direction);
|
||||
|
||||
if (denom == 0) {
|
||||
System.err.println("### ERROR @ Intersection / NEGATIVE_INFINITY");
|
||||
return Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
double numer = _myTempNormal.dot(theRay.origin);
|
||||
double D = -(thePlane.origin.dot(_myTempNormal));
|
||||
time = -((numer + D) / denom);
|
||||
|
||||
if (theIntersectionPoint != null) {
|
||||
theIntersectionPoint.set(theRay.direction);
|
||||
theIntersectionPoint.scale((float) time);
|
||||
theIntersectionPoint.add(theRay.origin);
|
||||
}
|
||||
|
||||
return (float) time;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @deprecated this method might contain errors.
|
||||
// * @param theRay Ray3f
|
||||
// * @param thePlane Plane3f
|
||||
// * @param theResult Vector3f
|
||||
// * @param theCullingFlag boolean
|
||||
// * @return float
|
||||
// */
|
||||
// public static float intersectRayTriangle(final Ray3f theRay,
|
||||
// final Plane3f thePlane,
|
||||
// final Vector3f theResult,
|
||||
// final boolean theCullingFlag) {
|
||||
// float a;
|
||||
// float f;
|
||||
// float u;
|
||||
// float v;
|
||||
// float t;
|
||||
//
|
||||
// _myTempEdge1.set(thePlane.vectorA);
|
||||
// _myTempEdge2.set(thePlane.vectorB);
|
||||
//
|
||||
// h.cross(theRay.direction, _myTempEdge2);
|
||||
//
|
||||
// a = _myTempEdge1.dot(h);
|
||||
// if (a > -EPSILON && a < EPSILON) {
|
||||
// return Float.NaN;
|
||||
// }
|
||||
// if (theCullingFlag) {
|
||||
// // u
|
||||
// s.sub(theRay.origin,
|
||||
// thePlane.origin);
|
||||
// u = s.dot(h);
|
||||
// if (u < 0.0f || u > a) {
|
||||
// return Float.NaN;
|
||||
// }
|
||||
// // v
|
||||
// v = theRay.direction.dot(q);
|
||||
// if (v < 0.0f || u + v > a) {
|
||||
// return Float.NaN;
|
||||
// }
|
||||
// // t
|
||||
// q.cross(s,
|
||||
// _myTempEdge1);
|
||||
// t = _myTempEdge2.dot(q);
|
||||
// // invert
|
||||
// f = 1.0f / a;
|
||||
// u *= f;
|
||||
// v *= f;
|
||||
// t *= f;
|
||||
// } else {
|
||||
// f = 1f / a;
|
||||
// // u
|
||||
// s.sub(theRay.origin,
|
||||
// thePlane.origin);
|
||||
// u = f * s.dot(h);
|
||||
// if (u < 0.0f || u > 1.0f) {
|
||||
// return Float.NaN;
|
||||
// }
|
||||
// // v
|
||||
// q.cross(s,
|
||||
// _myTempEdge1);
|
||||
// v = f * theRay.direction.dot(q);
|
||||
// if (v < 0.0 || u + v > 1.0) {
|
||||
// return Float.NaN;
|
||||
// }
|
||||
// // t
|
||||
// t = _myTempEdge2.dot(q) * f;
|
||||
// }
|
||||
// // result
|
||||
// theResult.scale(t,
|
||||
// theRay.direction);
|
||||
// theResult.add(theRay.origin);
|
||||
//
|
||||
// return t;
|
||||
// }
|
||||
/**
|
||||
* @deprecated this method might contain errors.
|
||||
* @param theRayOrigin Vector3f
|
||||
* @param theRayDirection Vector3f
|
||||
* @param thePlanePointA Vector3f
|
||||
* @param thePlanePointB Vector3f
|
||||
* @param thePlanePointC Vector3f
|
||||
* @param theResult Vector3f
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean intersectRayPlane(final Vector3f theRayOrigin,
|
||||
final Vector3f theRayDirection,
|
||||
final Vector3f thePlanePointA,
|
||||
final Vector3f thePlanePointB,
|
||||
final Vector3f thePlanePointC,
|
||||
final Vector3f theResult) {
|
||||
float a;
|
||||
float f;
|
||||
float u;
|
||||
float v;
|
||||
float t;
|
||||
|
||||
_myTempEdge1.sub(thePlanePointB,
|
||||
thePlanePointA);
|
||||
_myTempEdge2.sub(thePlanePointC,
|
||||
thePlanePointA);
|
||||
h.cross(theRayDirection,
|
||||
_myTempEdge2);
|
||||
|
||||
a = _myTempEdge1.dot(h);
|
||||
if (a > -EPSILON && a < EPSILON) {
|
||||
return false; // parallel
|
||||
}
|
||||
// u
|
||||
s.sub(theRayOrigin,
|
||||
thePlanePointA);
|
||||
u = s.dot(h);
|
||||
// v
|
||||
v = theRayDirection.dot(q);
|
||||
// t
|
||||
q.cross(s,
|
||||
_myTempEdge1);
|
||||
t = _myTempEdge2.dot(q);
|
||||
// invert
|
||||
f = 1.0f / a;
|
||||
u *= f;
|
||||
v *= f;
|
||||
t *= f;
|
||||
|
||||
// result
|
||||
theResult.scale(t,
|
||||
theRayDirection);
|
||||
theResult.add(theRayOrigin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method might contain errors.
|
||||
* @param theRay Ray3f
|
||||
* @param thePlane Plane3f
|
||||
* @param theResult Vector3f
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean intersectRayPlane(final Ray3f theRay,
|
||||
final Plane3f thePlane,
|
||||
final Vector3f theResult) {
|
||||
float a;
|
||||
float f;
|
||||
float u;
|
||||
float v;
|
||||
float t;
|
||||
|
||||
_myTempEdge1.set(thePlane.vectorA);
|
||||
_myTempEdge2.set(thePlane.vectorB);
|
||||
h.cross(theRay.direction,
|
||||
_myTempEdge2);
|
||||
|
||||
a = _myTempEdge1.dot(h);
|
||||
if (a > -EPSILON && a < EPSILON) {
|
||||
return false; // parallel
|
||||
}
|
||||
// u
|
||||
s.sub(theRay.origin,
|
||||
thePlane.origin);
|
||||
u = s.dot(h);
|
||||
// v
|
||||
v = theRay.direction.dot(q);
|
||||
// t
|
||||
q.cross(s,
|
||||
_myTempEdge1);
|
||||
t = _myTempEdge2.dot(q);
|
||||
// invert
|
||||
f = 1.0f / a;
|
||||
u *= f;
|
||||
v *= f;
|
||||
t *= f;
|
||||
|
||||
// result
|
||||
theResult.scale(t,
|
||||
theRay.direction);
|
||||
theResult.add(theRay.origin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method might contain errors.
|
||||
* @param theRay Ray3f
|
||||
* @param thePlane Plane3f
|
||||
* @return float
|
||||
*/
|
||||
public static float intersectRayPlane(final Ray3f theRay,
|
||||
final Plane3f thePlane) {
|
||||
float a;
|
||||
float f;
|
||||
float u;
|
||||
float v;
|
||||
float t;
|
||||
|
||||
_myTempEdge1.set(thePlane.vectorA);
|
||||
_myTempEdge2.set(thePlane.vectorB);
|
||||
h.cross(theRay.direction, _myTempEdge2);
|
||||
|
||||
a = _myTempEdge1.dot(h);
|
||||
if (a > -EPSILON && a < EPSILON) {
|
||||
return Float.NaN; // parallel
|
||||
}
|
||||
// u
|
||||
s.sub(theRay.origin,
|
||||
thePlane.origin);
|
||||
u = s.dot(h);
|
||||
// v
|
||||
v = theRay.direction.dot(q);
|
||||
// t
|
||||
q.cross(s,
|
||||
_myTempEdge1);
|
||||
t = _myTempEdge2.dot(q);
|
||||
// invert
|
||||
f = 1.0f / a;
|
||||
u *= f;
|
||||
v *= f;
|
||||
t *= f;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast, Minimum Storage Ray-Triangle Intersection by Tomas Moeller & Ben
|
||||
* Trumbore http://jgt.akpeters.com/papers/MollerTrumbore97/code.html
|
||||
*
|
||||
* @param theRayOrigin Vector3f
|
||||
* @param theRayDirection Vector3f
|
||||
* @param theVertex0 Vector3f
|
||||
* @param theVertex1 Vector3f
|
||||
* @param theVertex2 Vector3f
|
||||
* @param theResult Result
|
||||
* @param theCullingFlag boolean
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean intersectRayTriangle(final Vector3f theRayOrigin,
|
||||
final Vector3f theRayDirection,
|
||||
final Vector3f theVertex0,
|
||||
final Vector3f theVertex1,
|
||||
final Vector3f theVertex2,
|
||||
final IntersectionResult theResult,
|
||||
final boolean theCullingFlag) {
|
||||
|
||||
float det;
|
||||
float inv_det;
|
||||
|
||||
/* find vectors for two edges sharing vert0 */
|
||||
_myTempEdge1.sub(theVertex1, theVertex0);
|
||||
_myTempEdge2.sub(theVertex2, theVertex0);
|
||||
|
||||
/* begin calculating determinant - also used to calculate U parameter */
|
||||
pvec.cross(theRayDirection, _myTempEdge2);
|
||||
|
||||
/* if determinant is near zero, ray lies in plane of triangle */
|
||||
det = _myTempEdge1.dot(pvec);
|
||||
|
||||
if (theCullingFlag) { /* define TEST_CULL if culling is desired */
|
||||
if (det < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
tvec.sub(theRayOrigin, theVertex0);
|
||||
|
||||
/* calculate U parameter and test bounds */
|
||||
theResult.u = tvec.dot(pvec);
|
||||
if (theResult.u < 0.0f || theResult.u > det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* prepare to test V parameter */
|
||||
qvec.cross(tvec, _myTempEdge1);
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
theResult.v = theRayDirection.dot(qvec);
|
||||
if (theResult.v < 0.0f || theResult.u + theResult.v > det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate t, scale parameters, ray intersects triangle */
|
||||
theResult.t = _myTempEdge2.dot(qvec);
|
||||
inv_det = 1.0f / det;
|
||||
theResult.t *= inv_det;
|
||||
theResult.u *= inv_det;
|
||||
theResult.v *= inv_det;
|
||||
} else { /* the non-culling branch */
|
||||
if (det > -EPSILON && det < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
inv_det = 1.0f / det;
|
||||
|
||||
/* calculate distance from vert0 to ray origin */
|
||||
tvec.sub(theRayOrigin, theVertex0);
|
||||
|
||||
/* calculate U parameter and test bounds */
|
||||
theResult.u = tvec.dot(pvec) * inv_det;
|
||||
if (theResult.u < 0.0f || theResult.u > 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* prepare to test V parameter */
|
||||
qvec.cross(tvec, _myTempEdge1);
|
||||
|
||||
/* calculate V parameter and test bounds */
|
||||
theResult.v = theRayDirection.dot(qvec) * inv_det;
|
||||
if (theResult.v < 0.0f || theResult.u + theResult.v > 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate t, ray intersects triangle */
|
||||
theResult.t = _myTempEdge2.dot(qvec) * inv_det;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class IntersectionResult {
|
||||
|
||||
public float t;
|
||||
|
||||
public float u;
|
||||
|
||||
public float v;
|
||||
|
||||
}
|
||||
|
||||
public static float intersectRayTriangle(final Vector3f theRayOrigin,
|
||||
final Vector3f theRayDirection,
|
||||
final Vector3f thePlanePointA,
|
||||
final Vector3f thePlanePointB,
|
||||
final Vector3f thePlanePointC,
|
||||
final Vector3f theResult,
|
||||
final boolean theCullingFlag) {
|
||||
float a;
|
||||
float f;
|
||||
float u;
|
||||
float v;
|
||||
float t;
|
||||
|
||||
_myTempEdge1.sub(thePlanePointB,
|
||||
thePlanePointA);
|
||||
_myTempEdge2.sub(thePlanePointC,
|
||||
thePlanePointA);
|
||||
|
||||
h.cross(theRayDirection,
|
||||
_myTempEdge2);
|
||||
|
||||
a = _myTempEdge1.dot(h);
|
||||
if (a > -EPSILON && a < EPSILON) {
|
||||
return Float.NaN;
|
||||
}
|
||||
if (theCullingFlag) {
|
||||
// u
|
||||
s.sub(theRayOrigin,
|
||||
thePlanePointA);
|
||||
u = s.dot(h);
|
||||
if (u < 0.0f || u > a) {
|
||||
return Float.NaN;
|
||||
}
|
||||
// v
|
||||
v = theRayDirection.dot(q);
|
||||
if (v < 0.0f || u + v > a) {
|
||||
return Float.NaN;
|
||||
}
|
||||
// t
|
||||
q.cross(s,
|
||||
_myTempEdge1);
|
||||
t = _myTempEdge2.dot(q);
|
||||
// invert
|
||||
f = 1.0f / a;
|
||||
u *= f;
|
||||
v *= f;
|
||||
t *= f;
|
||||
} else {
|
||||
f = 1f / a;
|
||||
// u
|
||||
s.sub(theRayOrigin,
|
||||
thePlanePointA);
|
||||
u = f * s.dot(h);
|
||||
if (u < 0.0f || u > 1.0f) {
|
||||
return Float.NaN;
|
||||
}
|
||||
// v
|
||||
q.cross(s,
|
||||
_myTempEdge1);
|
||||
v = f * theRayDirection.dot(q);
|
||||
if (v < 0.0 || u + v > 1.0) {
|
||||
return Float.NaN;
|
||||
}
|
||||
// t
|
||||
t = _myTempEdge2.dot(q) * f;
|
||||
}
|
||||
// result
|
||||
theResult.scale(t,
|
||||
theRayDirection);
|
||||
theResult.add(theRayOrigin);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/raysphere.c
|
||||
* Calculate the intersection of a ray and a sphere The line segment is
|
||||
* defined from p1 to p2 The sphere is of radius r and centered at sc There
|
||||
* are potentially two points of intersection given by p = p1 + mu1 (p2 -
|
||||
* p1) p = p1 + mu2 (p2 - p1) Return FALSE if the ray doesn't intersect the
|
||||
* sphere.
|
||||
*/
|
||||
public static boolean RaySphere(Vector3f p1,
|
||||
Vector3f p2,
|
||||
Vector3f sc,
|
||||
float r) {
|
||||
float a, b, c;
|
||||
float bb4ac;
|
||||
Vector3f dp = new Vector3f();
|
||||
|
||||
dp.x = p2.x - p1.x;
|
||||
dp.y = p2.y - p1.y;
|
||||
dp.z = p2.z - p1.z;
|
||||
a = dp.x * dp.x + dp.y * dp.y + dp.z * dp.z;
|
||||
b = 2 * (dp.x * (p1.x - sc.x) + dp.y * (p1.y - sc.y) + dp.z * (p1.z - sc.z));
|
||||
c = sc.x * sc.x + sc.y * sc.y + sc.z * sc.z;
|
||||
c += p1.x * p1.x + p1.y * p1.y + p1.z * p1.z;
|
||||
c -= 2 * (sc.x * p1.x + sc.y * p1.y + sc.z * p1.z);
|
||||
c -= r * r;
|
||||
bb4ac = b * b - 4 * a * c;
|
||||
if (Math.abs(a) < EPSILON || bb4ac < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// float mu1 = ( -b + (float) Math.sqrt(bb4ac)) / (2 * a);
|
||||
// float mu2 = ( -b - (float) Math.sqrt(bb4ac)) / (2 * a);
|
||||
//
|
||||
// Vector3f myP1 = new Vector3f(dp);
|
||||
// myP1.scale(mu1);
|
||||
// myP1.add(p1);
|
||||
//
|
||||
// Vector3f myP2 = new Vector3f(dp);
|
||||
// myP2.scale(mu2);
|
||||
// myP2.add(p1);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* from paul bourke (
|
||||
* http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ )
|
||||
*
|
||||
*/
|
||||
public static final int COINCIDENT = 0;
|
||||
|
||||
public static final int PARALLEL = 1;
|
||||
|
||||
public static final int INTERESECTING = 2;
|
||||
|
||||
public static final int NOT_INTERESECTING = 3;
|
||||
|
||||
public static int lineLineIntersect(Vector2f aBegin, Vector2f aEnd,
|
||||
Vector2f bBegin, Vector2f bEnd,
|
||||
Vector2f theIntersection) {
|
||||
float denom = ((bEnd.y - bBegin.y) * (aEnd.x - aBegin.x))
|
||||
- ((bEnd.x - bBegin.x) * (aEnd.y - aBegin.y));
|
||||
|
||||
float nume_a = ((bEnd.x - bBegin.x) * (aBegin.y - bBegin.y))
|
||||
- ((bEnd.y - bBegin.y) * (aBegin.x - bBegin.x));
|
||||
|
||||
float nume_b = ((aEnd.x - aBegin.x) * (aBegin.y - bBegin.y))
|
||||
- ((aEnd.y - aBegin.y) * (aBegin.x - bBegin.x));
|
||||
|
||||
if (denom == 0.0f) {
|
||||
if (nume_a == 0.0f && nume_b == 0.0f) {
|
||||
return COINCIDENT;
|
||||
}
|
||||
return PARALLEL;
|
||||
}
|
||||
|
||||
float ua = nume_a / denom;
|
||||
float ub = nume_b / denom;
|
||||
|
||||
if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
|
||||
if (theIntersection != null) {
|
||||
// Get the intersection point.
|
||||
theIntersection.x = aBegin.x + ua * (aEnd.x - aBegin.x);
|
||||
theIntersection.y = aBegin.y + ua * (aEnd.y - aBegin.y);
|
||||
}
|
||||
return INTERESECTING;
|
||||
}
|
||||
|
||||
return NOT_INTERESECTING;
|
||||
}
|
||||
|
||||
/**
|
||||
* from paul bourke (
|
||||
* http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/ )
|
||||
*
|
||||
* Calculate the line segment PaPb that is the shortest route between two
|
||||
* lines P1P2 and P3P4. Calculate also the values of mua and mub where Pa =
|
||||
* P1 + mua (P2 - P1) Pb = P3 + mub (P4 - P3) Return FALSE if no solution
|
||||
* exists.
|
||||
*
|
||||
*/
|
||||
public static boolean lineLineIntersect(Vector3f p1, Vector3f p2, Vector3f p3, Vector3f p4,
|
||||
Vector3f pa, Vector3f pb,
|
||||
float[] theResult) {
|
||||
|
||||
final Vector3f p13 = mathematik.Util.sub(p1, p3);
|
||||
final Vector3f p43 = mathematik.Util.sub(p4, p3);
|
||||
if (Math.abs(p43.x) < EPSILON && Math.abs(p43.y) < EPSILON && Math.abs(p43.z) < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Vector3f p21 = mathematik.Util.sub(p2, p1);
|
||||
if (Math.abs(p21.x) < EPSILON && Math.abs(p21.y) < EPSILON && Math.abs(p21.z) < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final float d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z;
|
||||
final float d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z;
|
||||
final float d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z;
|
||||
final float d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z;
|
||||
final float d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z;
|
||||
|
||||
final float denom = d2121 * d4343 - d4321 * d4321;
|
||||
if (Math.abs(denom) < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
final float numer = d1343 * d4321 - d1321 * d4343;
|
||||
|
||||
final float mua = numer / denom;
|
||||
final float mub = (d1343 + d4321 * mua) / d4343;
|
||||
|
||||
pa.x = p1.x + mua * p21.x;
|
||||
pa.y = p1.y + mua * p21.y;
|
||||
pa.z = p1.z + mua * p21.z;
|
||||
pb.x = p3.x + mub * p43.x;
|
||||
pb.y = p3.y + mub * p43.y;
|
||||
pb.z = p3.z + mub * p43.z;
|
||||
|
||||
if (theResult != null) {
|
||||
theResult[0] = mua;
|
||||
theResult[1] = mub;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Vector3f[] intersectRaySpherePoints(Vector3f pSphereCenter,
|
||||
float pSphereRadius,
|
||||
Vector3f pRayDirection,
|
||||
Vector3f pRayOrigin) {
|
||||
// Solve quadratic equation
|
||||
float a = pRayDirection.lengthSquared();
|
||||
if (a == 0.0) {
|
||||
return null;
|
||||
}
|
||||
float b = 2.0f * (pRayOrigin.dot(pRayDirection) - pRayDirection.dot(pSphereCenter));
|
||||
Vector3f tempDiff = mathematik.Util.sub(pSphereCenter, pRayOrigin);
|
||||
float c = tempDiff.lengthSquared() - (pSphereRadius * pSphereRadius);
|
||||
float disc = b * b - 4 * a * c;
|
||||
if (disc < 0.0f) {
|
||||
return null;
|
||||
}
|
||||
int numIntersections;
|
||||
if (disc == 0.0f) {
|
||||
numIntersections = 1;
|
||||
} else {
|
||||
numIntersections = 2;
|
||||
}
|
||||
|
||||
// Atleast one intersection
|
||||
Vector3f[] points = new Vector3f[numIntersections];
|
||||
float t0;
|
||||
float t1 = 0.0f;
|
||||
t0 = ((0.5f * (-1.0f * b + (float) Math.sqrt(disc))) / a);
|
||||
if (numIntersections == 2) {
|
||||
t1 = ((0.5f * (-1.0f * b - (float) Math.sqrt(disc))) / a);
|
||||
}
|
||||
// point 1 of intersection
|
||||
points[0] = new Vector3f(pRayDirection);
|
||||
points[0].scale(t0);
|
||||
points[0].add(pRayOrigin);
|
||||
if (numIntersections == 2) {
|
||||
points[1] = new Vector3f(pRayDirection);
|
||||
points[1].scale(t1);
|
||||
points[1].add(pRayOrigin);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Vector3f myP1 = new Vector3f();
|
||||
Vector3f myP2 = new Vector3f(10, 10, 10);
|
||||
Vector3f myP3 = new Vector3f(10, 0, 0);
|
||||
Vector3f myP4 = new Vector3f(0, 10, 10);
|
||||
Vector3f myPA = new Vector3f();
|
||||
Vector3f myPB = new Vector3f();
|
||||
lineLineIntersect(myP1, myP2, myP3, myP4, myPA, myPB, null);
|
||||
System.out.println(myPA);
|
||||
System.out.println(myPB);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Linef<T extends Vectorf>
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1748179277316146123L;
|
||||
|
||||
public T p1;
|
||||
|
||||
public T p2;
|
||||
|
||||
public Linef(Class<T> theClass) {
|
||||
try {
|
||||
p1 = theClass.newInstance();
|
||||
p2 = theClass.newInstance();
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (InstantiationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Linef<Vector2f> myLine = new Linef<Vector2f> (Vector2f.class);
|
||||
* Linef<Vector3f> myLine3f = new Linef<Vector3f> (Vector3f.class);
|
||||
*/
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
public interface Mathematik {
|
||||
|
||||
float EPSILON = 0.00001f;
|
||||
|
||||
}
|
||||
+619
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* a 3x3 matrix.
|
||||
*
|
||||
* rotation
|
||||
*
|
||||
* rxx ryx rzx rxy ryy rzy rxz ryy rzz
|
||||
*
|
||||
* scale
|
||||
*
|
||||
* sx 0 0 0 sy 0 0 0 sz
|
||||
*
|
||||
*
|
||||
* also read 'The Matrix and Quaternions FAQ' at
|
||||
* http://www.flipcode.com/documents/matrfaq.html
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Matrix3f
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 104839874874759581L;
|
||||
|
||||
public static final int IDENTITY = 1;
|
||||
|
||||
public float xx;
|
||||
|
||||
public float xy;
|
||||
|
||||
public float xz;
|
||||
|
||||
public float yx;
|
||||
|
||||
public float yy;
|
||||
|
||||
public float yz;
|
||||
|
||||
public float zx;
|
||||
|
||||
public float zy;
|
||||
|
||||
public float zz;
|
||||
|
||||
private final float[] _myArrayRepresentation = new float[9];
|
||||
|
||||
private final float[] _myArray4fRepresentation = new float[16];
|
||||
|
||||
public Matrix3f() {
|
||||
xx = 0.0f;
|
||||
xy = 0.0f;
|
||||
xz = 0.0f;
|
||||
yx = 0.0f;
|
||||
yy = 0.0f;
|
||||
yz = 0.0f;
|
||||
zx = 0.0f;
|
||||
zy = 0.0f;
|
||||
zz = 0.0f;
|
||||
}
|
||||
|
||||
public Matrix3f(Matrix3f theMatrix) {
|
||||
set(theMatrix);
|
||||
}
|
||||
|
||||
public Matrix3f(int theType) {
|
||||
switch (theType) {
|
||||
case IDENTITY:
|
||||
setIdentity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void set(float xx,
|
||||
float yx,
|
||||
float zx,
|
||||
float xy,
|
||||
float yy,
|
||||
float zy,
|
||||
float xz,
|
||||
float yz,
|
||||
float zz) {
|
||||
this.xx = xx;
|
||||
this.xy = xy;
|
||||
this.xz = xz;
|
||||
this.yx = yx;
|
||||
this.yy = yy;
|
||||
this.yz = yz;
|
||||
this.zx = zx;
|
||||
this.zy = zy;
|
||||
this.zz = zz;
|
||||
}
|
||||
|
||||
public final void set(float[] _myArrayRepresentation) {
|
||||
xx = _myArrayRepresentation[0];
|
||||
yx = _myArrayRepresentation[1];
|
||||
zx = _myArrayRepresentation[2];
|
||||
xy = _myArrayRepresentation[3];
|
||||
yy = _myArrayRepresentation[4];
|
||||
zy = _myArrayRepresentation[5];
|
||||
xz = _myArrayRepresentation[6];
|
||||
yz = _myArrayRepresentation[7];
|
||||
zz = _myArrayRepresentation[8];
|
||||
}
|
||||
|
||||
public final void set(Matrix3f theMatrix) {
|
||||
xx = theMatrix.xx;
|
||||
xy = theMatrix.xy;
|
||||
xz = theMatrix.xz;
|
||||
yx = theMatrix.yx;
|
||||
yy = theMatrix.yy;
|
||||
yz = theMatrix.yz;
|
||||
zx = theMatrix.zx;
|
||||
zy = theMatrix.zy;
|
||||
zz = theMatrix.zz;
|
||||
}
|
||||
|
||||
public void setIdentity() {
|
||||
xx = 1.0f;
|
||||
xy = 0.0f;
|
||||
xz = 0.0f;
|
||||
yx = 0.0f;
|
||||
yy = 1.0f;
|
||||
yz = 0.0f;
|
||||
zx = 0.0f;
|
||||
zy = 0.0f;
|
||||
zz = 1.0f;
|
||||
}
|
||||
|
||||
public final void setZero() {
|
||||
xx = 0.0f;
|
||||
xy = 0.0f;
|
||||
xz = 0.0f;
|
||||
yx = 0.0f;
|
||||
yy = 0.0f;
|
||||
yz = 0.0f;
|
||||
zx = 0.0f;
|
||||
zy = 0.0f;
|
||||
zz = 0.0f;
|
||||
}
|
||||
|
||||
public void add(float theValue) {
|
||||
xx += theValue;
|
||||
xy += theValue;
|
||||
xz += theValue;
|
||||
yx += theValue;
|
||||
yy += theValue;
|
||||
yz += theValue;
|
||||
zx += theValue;
|
||||
zy += theValue;
|
||||
zz += theValue;
|
||||
}
|
||||
|
||||
public void add(Matrix3f theMatrixA,
|
||||
Matrix3f theMatrixB) {
|
||||
xx = theMatrixA.xx + theMatrixB.xx;
|
||||
xy = theMatrixA.xy + theMatrixB.xy;
|
||||
xz = theMatrixA.xz + theMatrixB.xz;
|
||||
yx = theMatrixA.yx + theMatrixB.yx;
|
||||
yy = theMatrixA.yy + theMatrixB.yy;
|
||||
yz = theMatrixA.yz + theMatrixB.yz;
|
||||
zx = theMatrixA.zx + theMatrixB.zx;
|
||||
zy = theMatrixA.zy + theMatrixB.zy;
|
||||
zz = theMatrixA.zz + theMatrixB.zz;
|
||||
}
|
||||
|
||||
public void add(Matrix3f theMatrix) {
|
||||
xx += theMatrix.xx;
|
||||
xy += theMatrix.xy;
|
||||
xz += theMatrix.xz;
|
||||
yx += theMatrix.yx;
|
||||
yy += theMatrix.yy;
|
||||
yz += theMatrix.yz;
|
||||
zx += theMatrix.zx;
|
||||
zy += theMatrix.zy;
|
||||
zz += theMatrix.zz;
|
||||
}
|
||||
|
||||
public void sub(Matrix3f theMatrixA,
|
||||
Matrix3f theMatrixB) {
|
||||
xx = theMatrixA.xx - theMatrixB.xx;
|
||||
xy = theMatrixA.xy - theMatrixB.xy;
|
||||
xz = theMatrixA.xz - theMatrixB.xz;
|
||||
yx = theMatrixA.yx - theMatrixB.yx;
|
||||
yy = theMatrixA.yy - theMatrixB.yy;
|
||||
yz = theMatrixA.yz - theMatrixB.yz;
|
||||
zx = theMatrixA.zx - theMatrixB.zx;
|
||||
zy = theMatrixA.zy - theMatrixB.zy;
|
||||
zz = theMatrixA.zz - theMatrixB.zz;
|
||||
}
|
||||
|
||||
public void sub(Matrix3f theMatrix) {
|
||||
xx -= theMatrix.xx;
|
||||
xy -= theMatrix.xy;
|
||||
xz -= theMatrix.xz;
|
||||
yx -= theMatrix.yx;
|
||||
yy -= theMatrix.yy;
|
||||
yz -= theMatrix.yz;
|
||||
zx -= theMatrix.zx;
|
||||
zy -= theMatrix.zy;
|
||||
zz -= theMatrix.zz;
|
||||
}
|
||||
|
||||
public void transpose() {
|
||||
|
||||
/*
|
||||
* NOTE if the matrix is a rotation matrix ie the determinant is 1, the
|
||||
* transpose is equivalent to the invers of the matrix.
|
||||
*/
|
||||
|
||||
float mySwap = yx;
|
||||
yx = xy;
|
||||
xy = mySwap;
|
||||
mySwap = zx;
|
||||
zx = xz;
|
||||
xz = mySwap;
|
||||
mySwap = zy;
|
||||
zy = yz;
|
||||
yz = mySwap;
|
||||
}
|
||||
|
||||
public void transpose(Matrix3f theMatrix) {
|
||||
if (this != theMatrix) {
|
||||
xx = theMatrix.xx;
|
||||
xy = theMatrix.yx;
|
||||
xz = theMatrix.zx;
|
||||
yx = theMatrix.xy;
|
||||
yy = theMatrix.yy;
|
||||
yz = theMatrix.zy;
|
||||
zx = theMatrix.xz;
|
||||
zy = theMatrix.yz;
|
||||
zz = theMatrix.zz;
|
||||
} else {
|
||||
transpose();
|
||||
}
|
||||
}
|
||||
|
||||
public final float determinant() {
|
||||
return xx * (yy * zz - yz * zy) + xy * (yz * zx - yx * zz) + xz * (yx * zy - yy * zx);
|
||||
}
|
||||
|
||||
public final void invert() {
|
||||
float myDeterminant = determinant();
|
||||
if (myDeterminant == 0.0) {
|
||||
return;
|
||||
}
|
||||
myDeterminant = 1 / myDeterminant;
|
||||
set(yy * zz - zy * yz,
|
||||
zx * yz - yx * zz,
|
||||
yx * zy - zx * yy,
|
||||
zy * xz - xy * zz,
|
||||
xx * zz - zx * xz,
|
||||
zx * xy - xx * zy,
|
||||
xy * yz - yy * xz,
|
||||
yx * xz - xx * yz,
|
||||
xx * yy - yx * xy);
|
||||
multiply(myDeterminant);
|
||||
}
|
||||
|
||||
public final void setXAxis(Vector3f theVector) {
|
||||
xx = theVector.x;
|
||||
yx = theVector.y;
|
||||
zx = theVector.z;
|
||||
}
|
||||
|
||||
public final void setYAxis(Vector3f theVector) {
|
||||
xy = theVector.x;
|
||||
yy = theVector.y;
|
||||
zy = theVector.z;
|
||||
}
|
||||
|
||||
public final void setZAxis(Vector3f theVector) {
|
||||
xz = theVector.x;
|
||||
yz = theVector.y;
|
||||
zz = theVector.z;
|
||||
}
|
||||
|
||||
public final void getXAxis(Vector3f theVector) {
|
||||
theVector.x = xx;
|
||||
theVector.y = yx;
|
||||
theVector.z = zx;
|
||||
}
|
||||
|
||||
public final void getYAxis(Vector3f theVector) {
|
||||
theVector.x = xy;
|
||||
theVector.y = yy;
|
||||
theVector.z = zy;
|
||||
}
|
||||
|
||||
public final void getZAxis(Vector3f theVector) {
|
||||
theVector.x = xz;
|
||||
theVector.y = yz;
|
||||
theVector.z = zz;
|
||||
}
|
||||
|
||||
public final Vector3f getXAxis() {
|
||||
return new Vector3f(xx, yx, zx);
|
||||
}
|
||||
|
||||
public final Vector3f getYAxis() {
|
||||
return new Vector3f(xy, yy, zy);
|
||||
}
|
||||
|
||||
public final Vector3f getZAxis() {
|
||||
return new Vector3f(xz, yz, zz);
|
||||
}
|
||||
|
||||
public final void setXRotation(float theRadians) {
|
||||
float sin = (float) Math.sin(theRadians);
|
||||
float cos = (float) Math.cos(theRadians);
|
||||
|
||||
xx = 1.0f;
|
||||
yx = 0.0f;
|
||||
zx = 0.0f;
|
||||
|
||||
xy = 0.0f;
|
||||
yy = cos;
|
||||
zy = sin;
|
||||
|
||||
xz = 0.0f;
|
||||
yz = -sin;
|
||||
zz = cos;
|
||||
}
|
||||
|
||||
public final void setYRotation(float theRadians) {
|
||||
|
||||
/**
|
||||
* @todo check why these differ from 'the matrix and quaternions faq'
|
||||
*
|
||||
* cos 0 sin(!) 0 1 0 -sin(!) 0 cos
|
||||
*
|
||||
*/
|
||||
float sin = (float) Math.sin(theRadians);
|
||||
float cos = (float) Math.cos(theRadians);
|
||||
|
||||
xx = cos;
|
||||
yx = 0.0f;
|
||||
zx = -sin;
|
||||
|
||||
xy = 0.0f;
|
||||
yy = 1.0f;
|
||||
zy = 0.0f;
|
||||
|
||||
xz = sin;
|
||||
yz = 0.0f;
|
||||
zz = cos;
|
||||
}
|
||||
|
||||
public final void setZRotation(float theRadians) {
|
||||
float sin = (float) Math.sin(theRadians);
|
||||
float cos = (float) Math.cos(theRadians);
|
||||
|
||||
xx = cos;
|
||||
yx = sin;
|
||||
zx = 0.0f;
|
||||
|
||||
xy = -sin;
|
||||
yy = cos;
|
||||
zy = 0.0f;
|
||||
|
||||
xz = 0.0f;
|
||||
yz = 0.0f;
|
||||
zz = 1.0f;
|
||||
}
|
||||
|
||||
public final void setXYZRotation(Vector3f theRotation) {
|
||||
setXYZRotation(theRotation.x,
|
||||
theRotation.y,
|
||||
theRotation.z);
|
||||
}
|
||||
|
||||
public final void setXYZRotation(float theX,
|
||||
float theY,
|
||||
float theZ) {
|
||||
/* using radiants */
|
||||
final float a = (float) Math.cos(theX);
|
||||
final float b = (float) Math.sin(theX);
|
||||
final float c = (float) Math.cos(theY);
|
||||
final float d = (float) Math.sin(theY);
|
||||
final float e = (float) Math.cos(theZ);
|
||||
final float f = (float) Math.sin(theZ);
|
||||
|
||||
final float ad = a * d;
|
||||
final float bd = b * d;
|
||||
|
||||
xx = c * e;
|
||||
yx = bd * e + a * f;
|
||||
zx = -ad * e + b * f;
|
||||
|
||||
xy = -c * f;
|
||||
yy = -bd * f + a * e;
|
||||
zy = ad * f + b * e;
|
||||
|
||||
xz = d;
|
||||
yz = -b * c;
|
||||
zz = a * c;
|
||||
}
|
||||
|
||||
public final void setRotation(final Vector4f theRotation) {
|
||||
final float u = theRotation.x;
|
||||
final float v = theRotation.y;
|
||||
final float w = theRotation.z;
|
||||
|
||||
final float rcos = (float) Math.cos(theRotation.w);
|
||||
final float rsin = (float) Math.sin(theRotation.w);
|
||||
|
||||
xx = rcos + u * u * (1 - rcos);
|
||||
yx = w * rsin + v * u * (1 - rcos);
|
||||
zx = -v * rsin + w * u * (1 - rcos);
|
||||
|
||||
xy = -w * rsin + u * v * (1 - rcos);
|
||||
yy = rcos + v * v * (1 - rcos);
|
||||
zy = u * rsin + w * v * (1 - rcos);
|
||||
|
||||
xz = v * rsin + u * w * (1 - rcos);
|
||||
yz = -u * rsin + v * w * (1 - rcos);
|
||||
zz = rcos + w * w * (1 - rcos);
|
||||
}
|
||||
|
||||
public final void multiply(float theValue) {
|
||||
xx *= theValue;
|
||||
xy *= theValue;
|
||||
xz *= theValue;
|
||||
yx *= theValue;
|
||||
yy *= theValue;
|
||||
yz *= theValue;
|
||||
zx *= theValue;
|
||||
zy *= theValue;
|
||||
zz *= theValue;
|
||||
}
|
||||
|
||||
public final void multiply(Matrix3f theMatrix) {
|
||||
float tmp1 = xx * theMatrix.xx + xy * theMatrix.yx + xz * theMatrix.zx;
|
||||
float tmp2 = xx * theMatrix.xy + xy * theMatrix.yy + xz * theMatrix.zy;
|
||||
float tmp3 = xx * theMatrix.xz + xy * theMatrix.yz + xz * theMatrix.zz;
|
||||
float tmp4 = yx * theMatrix.xx + yy * theMatrix.yx + yz * theMatrix.zx;
|
||||
float tmp5 = yx * theMatrix.xy + yy * theMatrix.yy + yz * theMatrix.zy;
|
||||
float tmp6 = yx * theMatrix.xz + yy * theMatrix.yz + yz * theMatrix.zz;
|
||||
float tmp7 = zx * theMatrix.xx + zy * theMatrix.yx + zz * theMatrix.zx;
|
||||
float tmp8 = zx * theMatrix.xy + zy * theMatrix.yy + zz * theMatrix.zy;
|
||||
float tmp9 = zx * theMatrix.xz + zy * theMatrix.yz + zz * theMatrix.zz;
|
||||
xx = tmp1;
|
||||
xy = tmp2;
|
||||
xz = tmp3;
|
||||
yx = tmp4;
|
||||
yy = tmp5;
|
||||
yz = tmp6;
|
||||
zx = tmp7;
|
||||
zy = tmp8;
|
||||
zz = tmp9;
|
||||
}
|
||||
|
||||
public final void transform(Vector3f theVector) {
|
||||
theVector.set(xx * theVector.x + yx * theVector.y + zx * theVector.z,
|
||||
xy * theVector.x + yy * theVector.y + zy * theVector.z,
|
||||
theVector.z = xz * theVector.x + yz * theVector.y + zz * theVector.z);
|
||||
}
|
||||
|
||||
public void setScale(Vector3f theScale) {
|
||||
xx = theScale.x;
|
||||
yx = 0.0f;
|
||||
zx = 0.0f;
|
||||
|
||||
xy = 0.0f;
|
||||
yy = theScale.y;
|
||||
zy = 0.0f;
|
||||
|
||||
xz = 0.0f;
|
||||
yz = 0.0f;
|
||||
zz = theScale.z;
|
||||
}
|
||||
|
||||
public final float[] toArray() {
|
||||
_myArrayRepresentation[0] = xx;
|
||||
_myArrayRepresentation[1] = yx;
|
||||
_myArrayRepresentation[2] = zx;
|
||||
_myArrayRepresentation[3] = xy;
|
||||
_myArrayRepresentation[4] = yy;
|
||||
_myArrayRepresentation[5] = zy;
|
||||
_myArrayRepresentation[6] = xz;
|
||||
_myArrayRepresentation[7] = yz;
|
||||
_myArrayRepresentation[8] = zz;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public final float[] toArray4f() {
|
||||
/* so that opengl can understand it */
|
||||
_myArray4fRepresentation[0] = xx;
|
||||
_myArray4fRepresentation[1] = yx;
|
||||
_myArray4fRepresentation[2] = zx;
|
||||
_myArray4fRepresentation[3] = 0;
|
||||
_myArray4fRepresentation[4] = xy;
|
||||
_myArray4fRepresentation[5] = yy;
|
||||
_myArray4fRepresentation[6] = zy;
|
||||
_myArray4fRepresentation[7] = 0;
|
||||
_myArray4fRepresentation[8] = xz;
|
||||
_myArray4fRepresentation[9] = yz;
|
||||
_myArray4fRepresentation[10] = zz;
|
||||
_myArray4fRepresentation[11] = 0;
|
||||
_myArray4fRepresentation[12] = 0;
|
||||
_myArray4fRepresentation[13] = 0;
|
||||
_myArray4fRepresentation[14] = 0;
|
||||
_myArray4fRepresentation[15] = 1;
|
||||
return _myArray4fRepresentation;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return xx + ", " + yx + ", " + zx + "\n" + xy + ", " + yy + ", " + zy + "\n" + xz + ", " + yz + ", " + zz;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Matrix3f myMatrix;
|
||||
|
||||
{
|
||||
/* invert and transpose */
|
||||
|
||||
System.out.println("### invert and transpose\n");
|
||||
|
||||
myMatrix = new Matrix3f(Matrix3f.IDENTITY);
|
||||
myMatrix.setXYZRotation(new Vector3f(0.2f, 0.3f, 0.4f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.transpose();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.transpose();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix = new Matrix3f(Matrix3f.IDENTITY);
|
||||
myMatrix.setXYZRotation(new Vector3f(0.2f, 0.3f, 0.4f));
|
||||
|
||||
myMatrix.invert();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.invert();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
{
|
||||
/* x */
|
||||
|
||||
myMatrix = new Matrix3f(Matrix3f.IDENTITY);
|
||||
|
||||
System.out.println("### rotation x\n");
|
||||
|
||||
myMatrix.setXYZRotation(new Vector3f(0.2f, 0.0f, 0.0f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setXRotation(0.2f);
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setRotation(new Vector4f(1, 0, 0, 0.2f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
/* y */
|
||||
|
||||
System.out.println("### rotation y\n");
|
||||
|
||||
myMatrix.setXYZRotation(new Vector3f(0.0f, 0.3f, 0.0f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setYRotation(0.3f);
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setRotation(new Vector4f(0, 1, 0, 0.3f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
/* z */
|
||||
|
||||
System.out.println("### rotation z\n");
|
||||
|
||||
myMatrix.setXYZRotation(new Vector3f(0.0f, 0.0f, 0.4f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setZRotation(0.4f);
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.setRotation(new Vector4f(0, 0, 1, 0.4f));
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
+433
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* a more general 4x4 matrix.
|
||||
*
|
||||
* xx yx zx wx xy yy zy wy xz yz zz wz xw yw zw ww
|
||||
*
|
||||
* also read 'The Matrix and Quaternions FAQ' at
|
||||
* http://www.flipcode.com/documents/matrfaq.html
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Matrix4f
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1088603850006298206L;
|
||||
|
||||
public float xx;
|
||||
|
||||
public float xy;
|
||||
|
||||
public float xz;
|
||||
|
||||
public float xw;
|
||||
|
||||
public float yx;
|
||||
|
||||
public float yy;
|
||||
|
||||
public float yz;
|
||||
|
||||
public float yw;
|
||||
|
||||
public float zx;
|
||||
|
||||
public float zy;
|
||||
|
||||
public float zz;
|
||||
|
||||
public float zw;
|
||||
|
||||
public float wx;
|
||||
|
||||
public float wy;
|
||||
|
||||
public float wz;
|
||||
|
||||
public float ww;
|
||||
|
||||
private final float[] _myArrayRepresentation = new float[16];
|
||||
|
||||
public Matrix4f() {
|
||||
}
|
||||
|
||||
public Matrix4f(TransformMatrix4f theTransformMatrix) {
|
||||
xx = theTransformMatrix.rotation.xx;
|
||||
yx = theTransformMatrix.rotation.yx;
|
||||
zx = theTransformMatrix.rotation.zx;
|
||||
wx = 0;
|
||||
|
||||
xy = theTransformMatrix.rotation.xy;
|
||||
yy = theTransformMatrix.rotation.yy;
|
||||
zy = theTransformMatrix.rotation.zy;
|
||||
wy = 0;
|
||||
|
||||
xz = theTransformMatrix.rotation.xz;
|
||||
yz = theTransformMatrix.rotation.yz;
|
||||
zz = theTransformMatrix.rotation.zz;
|
||||
wz = 0;
|
||||
|
||||
xw = theTransformMatrix.translation.x;
|
||||
yw = theTransformMatrix.translation.y;
|
||||
zw = theTransformMatrix.translation.z;
|
||||
ww = 1;
|
||||
}
|
||||
|
||||
public Matrix4f(Matrix4f theTransformMatrix) {
|
||||
xx = theTransformMatrix.xx;
|
||||
yx = theTransformMatrix.yx;
|
||||
zx = theTransformMatrix.zx;
|
||||
wx = theTransformMatrix.wx;
|
||||
|
||||
xy = theTransformMatrix.xy;
|
||||
yy = theTransformMatrix.yy;
|
||||
zy = theTransformMatrix.zy;
|
||||
wy = theTransformMatrix.wy;
|
||||
|
||||
xz = theTransformMatrix.xz;
|
||||
yz = theTransformMatrix.yz;
|
||||
zz = theTransformMatrix.zz;
|
||||
wz = theTransformMatrix.wz;
|
||||
|
||||
xw = theTransformMatrix.xw;
|
||||
yw = theTransformMatrix.yw;
|
||||
zw = theTransformMatrix.zw;
|
||||
ww = theTransformMatrix.ww;
|
||||
}
|
||||
|
||||
public Matrix4f(float[] theMatrix) {
|
||||
set(theMatrix);
|
||||
}
|
||||
|
||||
public Matrix4f(double[] theMatrix) {
|
||||
set(theMatrix);
|
||||
}
|
||||
|
||||
public Matrix4f(float xx,
|
||||
float yx,
|
||||
float zx,
|
||||
float wx,
|
||||
float xy,
|
||||
float yy,
|
||||
float zy,
|
||||
float wy,
|
||||
float xz,
|
||||
float yz,
|
||||
float zz,
|
||||
float wz,
|
||||
float xw,
|
||||
float yw,
|
||||
float zw,
|
||||
float ww) {
|
||||
this.xx = xx;
|
||||
this.xy = xy;
|
||||
this.xz = xz;
|
||||
this.xw = xw;
|
||||
|
||||
this.yx = yx;
|
||||
this.yy = yy;
|
||||
this.yz = yz;
|
||||
this.yw = yw;
|
||||
|
||||
this.zx = zx;
|
||||
this.zy = zy;
|
||||
this.zz = zz;
|
||||
this.zw = zw;
|
||||
|
||||
this.wx = wx;
|
||||
this.wy = wy;
|
||||
this.wz = wz;
|
||||
this.ww = ww;
|
||||
}
|
||||
|
||||
public void set(float[] theMatrix) {
|
||||
xx = theMatrix[0];
|
||||
yx = theMatrix[1];
|
||||
zx = theMatrix[2];
|
||||
wx = theMatrix[3];
|
||||
|
||||
xy = theMatrix[4];
|
||||
yy = theMatrix[5];
|
||||
zy = theMatrix[6];
|
||||
wy = theMatrix[7];
|
||||
|
||||
xz = theMatrix[8];
|
||||
yz = theMatrix[9];
|
||||
zz = theMatrix[10];
|
||||
wz = theMatrix[11];
|
||||
|
||||
xw = theMatrix[12];
|
||||
yw = theMatrix[13];
|
||||
zw = theMatrix[14];
|
||||
ww = theMatrix[15];
|
||||
}
|
||||
|
||||
public void set(double[] theMatrix) {
|
||||
xx = (float) theMatrix[0];
|
||||
yx = (float) theMatrix[1];
|
||||
zx = (float) theMatrix[2];
|
||||
wx = (float) theMatrix[3];
|
||||
|
||||
xy = (float) theMatrix[4];
|
||||
yy = (float) theMatrix[5];
|
||||
zy = (float) theMatrix[6];
|
||||
wy = (float) theMatrix[7];
|
||||
|
||||
xz = (float) theMatrix[8];
|
||||
yz = (float) theMatrix[9];
|
||||
zz = (float) theMatrix[10];
|
||||
wz = (float) theMatrix[11];
|
||||
|
||||
xw = (float) theMatrix[12];
|
||||
yw = (float) theMatrix[13];
|
||||
zw = (float) theMatrix[14];
|
||||
ww = (float) theMatrix[15];
|
||||
}
|
||||
|
||||
public void set(float xx,
|
||||
float yx,
|
||||
float zx,
|
||||
float wx,
|
||||
float xy,
|
||||
float yy,
|
||||
float zy,
|
||||
float wy,
|
||||
float xz,
|
||||
float yz,
|
||||
float zz,
|
||||
float wz,
|
||||
float xw,
|
||||
float yw,
|
||||
float zw,
|
||||
float ww) {
|
||||
this.xx = xx;
|
||||
this.xy = xy;
|
||||
this.xz = xz;
|
||||
this.xw = xw;
|
||||
|
||||
this.yx = yx;
|
||||
this.yy = yy;
|
||||
this.yz = yz;
|
||||
this.yw = yw;
|
||||
|
||||
this.zx = zx;
|
||||
this.zy = zy;
|
||||
this.zz = zz;
|
||||
this.zw = zw;
|
||||
|
||||
this.wx = wx;
|
||||
this.wy = wy;
|
||||
this.wz = wz;
|
||||
this.ww = ww;
|
||||
}
|
||||
|
||||
public void invert() {
|
||||
float myDeterminant = determinant();
|
||||
if (myDeterminant == 0.0) {
|
||||
return;
|
||||
}
|
||||
myDeterminant = 1 / myDeterminant;
|
||||
set(yy * (zz * ww - zw * wz) + yz * (zw * wy - zy * ww) + yw * (zy * wz - zz * wy),
|
||||
zy * (xz * ww - xw * wz) + zz * (xw * wy - xy * ww) + zw * (xy * wz - xz * wy),
|
||||
wy * (xz * yw - xw * yz) + wz * (xw * yy - xy * yw) + ww * (xy * yz - xz * yy),
|
||||
xy * (yw * zz - yz * zw) + xz * (yy * zw - yw * zy) + xw * (yz * zy - yy * zz),
|
||||
yz * (zx * ww - zw * wx) + yw * (zz * wx - zx * wz) + yx * (zw * wz - zz * ww),
|
||||
zz * (xx * ww - xw * wx) + zw * (xz * wx - xx * wz) + zx * (xw * wz - xz * ww),
|
||||
wz * (xx * yw - xw * yx) + ww * (xz * yx - xx * yz) + wx * (xw * yz - xz * yw),
|
||||
xz * (yw * zx - yx * zw) + xw * (yx * zz - yz * zx) + xx * (yz * zw - yw * zz),
|
||||
yw * (zx * wy - zy * wx) + yx * (zy * ww - zw * wy) + yy * (zw * wx - zx * ww),
|
||||
zw * (xx * wy - xy * wx) + zx * (xy * ww - xw * wy) + zy * (xw * wx - xx * ww),
|
||||
ww * (xx * yy - xy * yx) + wx * (xy * yw - xw * yy) + wy * (xw * yx - xx * yw),
|
||||
xw * (yy * zx - yx * zy) + xx * (yw * zy - yy * zw) + xy * (yx * zw - yw * zx),
|
||||
yx * (zz * wy - zy * wz) + yy * (zx * wz - zz * wx) + yz * (zy * wx - zx * wy),
|
||||
zx * (xz * wy - xy * wz) + zy * (xx * wz - xz * wx) + zz * (xy * wx - xx * wy),
|
||||
wx * (xz * yy - xy * yz) + wy * (xx * yz - xz * yx) + wz * (xy * yx - xx * yy),
|
||||
xx * (yy * zz - yz * zy) + xy * (yz * zx - yx * zz) + xz * (yx * zy - yy * zx));
|
||||
|
||||
multiply(myDeterminant);
|
||||
}
|
||||
|
||||
public void multiply(float scalar) {
|
||||
xx *= scalar;
|
||||
xy *= scalar;
|
||||
xz *= scalar;
|
||||
xw *= scalar;
|
||||
yx *= scalar;
|
||||
yy *= scalar;
|
||||
yz *= scalar;
|
||||
yw *= scalar;
|
||||
zx *= scalar;
|
||||
zy *= scalar;
|
||||
zz *= scalar;
|
||||
zw *= scalar;
|
||||
wx *= scalar;
|
||||
wy *= scalar;
|
||||
wz *= scalar;
|
||||
ww *= scalar;
|
||||
}
|
||||
|
||||
public final void multiply(Matrix4f theMatrix) {
|
||||
multiply(this,
|
||||
theMatrix);
|
||||
}
|
||||
|
||||
public final void multiply(Matrix4f theA,
|
||||
Matrix4f theB) {
|
||||
/**
|
||||
* @todo here we still have an ugly bug :(
|
||||
*/
|
||||
set(theA.xx * theB.xx + theA.yx * theB.xy + theA.zx * theB.xz + theA.wx * theB.xw,
|
||||
theA.xx * theB.yx + theA.yx * theB.yy + theA.zx * theB.yz + theA.wx * theB.yw,
|
||||
theA.xx * theB.zx + theA.yx * theB.zy + theA.zx * theB.zz + theA.wx * theB.zw,
|
||||
theA.xx * theB.wx + theA.yx * theB.wy + theA.zx * theB.wz + theA.wx * theB.ww,
|
||||
theA.xy * theB.xx + theA.yy * theB.xy + theA.zy * theB.xz + theA.wy * theB.xw,
|
||||
theA.xy * theB.yx + theA.yy * theB.yy + theA.zy * theB.yz + theA.wy * theB.yw,
|
||||
theA.xy * theB.zx + theA.yy * theB.zy + theA.zy * theB.zz + theA.wy * theB.zw,
|
||||
theA.xy * theB.wx + theA.yy * theB.wy + theA.zy * theB.wz + theA.wy * theB.ww,
|
||||
theA.xz * theB.xx + theA.yz * theB.xy + theA.zz * theB.xz + theA.wz * theB.xw,
|
||||
theA.xz * theB.yx + theA.yz * theB.yy + theA.zz * theB.yz + theA.wz * theB.yw,
|
||||
theA.xz * theB.zx + theA.yz * theB.zy + theA.zz * theB.zz + theA.wz * theB.zw,
|
||||
theA.xz * theB.wx + theA.yz * theB.wy + theA.zz * theB.wz + theA.wz * theB.ww,
|
||||
theA.xw * theB.xx + theA.yw * theB.xy + theA.zw * theB.xz + theA.ww * theB.xw,
|
||||
theA.xw * theB.yx + theA.yw * theB.yy + theA.zw * theB.yz + theA.ww * theB.yw,
|
||||
theA.xw * theB.zx + theA.yw * theB.zy + theA.zw * theB.zz + theA.ww * theB.zw,
|
||||
theA.xw * theB.wx + theA.yw * theB.wy + theA.zw * theB.wz + theA.ww * theB.ww);
|
||||
}
|
||||
|
||||
public float determinant() {
|
||||
/**
|
||||
* @todo check if this is correct
|
||||
*/
|
||||
return (xx * yy - xy * yx) * (zz * ww - zw * wz) - (xx * yz - xz * yx) * (zy * ww - zw * wy)
|
||||
+ (xx * yw - xw * yx) * (zy * wz - zz * wy) + (xy * yz - xz * yy) * (zx * ww - zw * wx)
|
||||
- (xy * yw - xw * yy) * (zx * wz - zz * wx) + (xz * yw - xw * yz) * (zx * wy - zy * wx);
|
||||
}
|
||||
|
||||
public final void transform(Vector3f theResult) {
|
||||
theResult.set(xx * theResult.x + xy * theResult.y + xz * theResult.z + xw,
|
||||
yx * theResult.x + yy * theResult.y + yz * theResult.z + yw,
|
||||
zx * theResult.x + zy * theResult.y + zz * theResult.z + zw);
|
||||
}
|
||||
|
||||
public final void transform(Vector4f theVector) {
|
||||
theVector.set(xx * theVector.x + xy * theVector.y + xz * theVector.z + xw * theVector.w,
|
||||
yx * theVector.x + yy * theVector.y + yz * theVector.z + yw * theVector.w,
|
||||
zx * theVector.x + zy * theVector.y + zz * theVector.z + zw * theVector.w,
|
||||
wx * theVector.x + wy * theVector.y + wz * theVector.z + ww * theVector.w);
|
||||
}
|
||||
|
||||
public float[] toArray() {
|
||||
/* opengl format */
|
||||
_myArrayRepresentation[0] = xx;
|
||||
_myArrayRepresentation[1] = yx;
|
||||
_myArrayRepresentation[2] = zx;
|
||||
_myArrayRepresentation[3] = wx;
|
||||
|
||||
_myArrayRepresentation[4] = xy;
|
||||
_myArrayRepresentation[5] = yy;
|
||||
_myArrayRepresentation[6] = zy;
|
||||
_myArrayRepresentation[7] = wy;
|
||||
|
||||
_myArrayRepresentation[8] = xz;
|
||||
_myArrayRepresentation[9] = yz;
|
||||
_myArrayRepresentation[10] = zz;
|
||||
_myArrayRepresentation[11] = wz;
|
||||
|
||||
_myArrayRepresentation[12] = wx;
|
||||
_myArrayRepresentation[13] = wy;
|
||||
_myArrayRepresentation[14] = wz;
|
||||
_myArrayRepresentation[15] = ww;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public final void transpose() {
|
||||
float swap = yx;
|
||||
yx = xy;
|
||||
xy = swap;
|
||||
swap = zx;
|
||||
zx = xz;
|
||||
xz = swap;
|
||||
swap = wx;
|
||||
wx = xw;
|
||||
xw = swap;
|
||||
swap = zy;
|
||||
zy = yz;
|
||||
yz = swap;
|
||||
swap = wy;
|
||||
wy = yw;
|
||||
yw = swap;
|
||||
swap = wz;
|
||||
wz = zw;
|
||||
zw = swap;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return xx + ", " + yx + ", " + zx + ", " + wx + "\n" + xy + ", " + yy + ", " + zy + ", " + wy + "\n" + xz
|
||||
+ ", " + yz + ", " + zz + ", " + wz + "\n" + xw + ", " + yw + ", " + zw + ", " + ww;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TransformMatrix4f myTransMatrix = new TransformMatrix4f(TransformMatrix4f.IDENTITY);
|
||||
myTransMatrix.rotation.setXYZRotation(new Vector3f(0.2f, 0.3f, 0.4f));
|
||||
myTransMatrix.translation.set(2,
|
||||
3,
|
||||
4);
|
||||
|
||||
System.out.println("### transform matrix\n");
|
||||
|
||||
System.out.println(myTransMatrix);
|
||||
System.out.println();
|
||||
|
||||
Matrix4f myMatrix = new Matrix4f(myTransMatrix);
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.invert();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
myMatrix.invert();
|
||||
System.out.println(myMatrix);
|
||||
System.out.println();
|
||||
|
||||
/* transform */
|
||||
Vector3f myVector3f = new Vector3f(5, 8, 7);
|
||||
Vector4f myVector4f = new Vector4f(5, 8, 7, 1);
|
||||
Vector3f myVectorOther3f = new Vector3f(5, 8, 7);
|
||||
|
||||
System.out.println();
|
||||
|
||||
myMatrix.transform(myVector3f);
|
||||
System.out.println(myVector3f);
|
||||
|
||||
myMatrix.transform(myVector4f);
|
||||
System.out.println(myVector4f);
|
||||
|
||||
myTransMatrix.transform(myVectorOther3f);
|
||||
System.out.println(myVectorOther3f);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public abstract class PerlinNoise {
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// PERLIN NOISE
|
||||
// [toxi 040903]
|
||||
// octaves and amplitude amount per octave are now user controlled
|
||||
// via the noiseDetail() function.
|
||||
// [toxi 030902]
|
||||
// cleaned up code and now using bagel's cosine table to speed up
|
||||
// [toxi 030901]
|
||||
// implementation by the german demo group farbrausch
|
||||
// as used in their demo "art": http://www.farb-rausch.de/fr010src.zip
|
||||
static final int PERLIN_YWRAPB = 4;
|
||||
|
||||
static final int PERLIN_YWRAP = 1 << PERLIN_YWRAPB;
|
||||
|
||||
static final int PERLIN_ZWRAPB = 8;
|
||||
|
||||
static final int PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;
|
||||
|
||||
static final int PERLIN_SIZE = 4095;
|
||||
|
||||
static int perlin_octaves = 4; // default to medium smooth
|
||||
|
||||
static float perlin_amp_falloff = 0.5f; // 50% reduction/octave
|
||||
|
||||
// [toxi 031112]
|
||||
// new vars needed due to recent change of cos table in PGraphics
|
||||
static int perlin_TWOPI, perlin_PI;
|
||||
|
||||
static float[] perlin_cosTable;
|
||||
|
||||
static float[] perlin;
|
||||
|
||||
static Random perlinRandom;
|
||||
|
||||
public static int SEED = 0;
|
||||
|
||||
/**
|
||||
* Computes the Perlin noise function value at point x.
|
||||
*/
|
||||
public static float noise(float x) {
|
||||
// is this legit? it's a dumb way to do it (but repair it later)
|
||||
return noise(x, 0f, 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the Perlin noise function value at the point x, y.
|
||||
*/
|
||||
public static float noise(float x, float y) {
|
||||
return noise(x, y, 0f);
|
||||
}
|
||||
|
||||
public static float noise(float x, float y, float z) {
|
||||
if (perlin == null) {
|
||||
if (perlinRandom == null) {
|
||||
perlinRandom = new Random(SEED);
|
||||
}
|
||||
perlin = new float[PERLIN_SIZE + 1];
|
||||
for (int i = 0; i < PERLIN_SIZE + 1; i++) {
|
||||
perlin[i] = perlinRandom.nextFloat(); //(float)Math.random();
|
||||
}
|
||||
// [toxi 031112]
|
||||
// noise broke due to recent change of cos table in PGraphics
|
||||
// this will take care of it
|
||||
perlin_cosTable = cosLUT;
|
||||
perlin_TWOPI = perlin_PI = SINCOS_LENGTH;
|
||||
perlin_PI >>= 1;
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = -y;
|
||||
}
|
||||
if (z < 0) {
|
||||
z = -z;
|
||||
}
|
||||
|
||||
int xi = (int) x, yi = (int) y, zi = (int) z;
|
||||
float xf = (float) (x - xi);
|
||||
float yf = (float) (y - yi);
|
||||
float zf = (float) (z - zi);
|
||||
float rxf, ryf;
|
||||
|
||||
float r = 0;
|
||||
float ampl = 0.5f;
|
||||
|
||||
float n1, n2, n3;
|
||||
|
||||
for (int i = 0; i < perlin_octaves; i++) {
|
||||
int of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB);
|
||||
|
||||
rxf = noise_fsc(xf);
|
||||
ryf = noise_fsc(yf);
|
||||
|
||||
n1 = perlin[of & PERLIN_SIZE];
|
||||
n1 += rxf * (perlin[(of + 1) & PERLIN_SIZE] - n1);
|
||||
n2 = perlin[(of + PERLIN_YWRAP) & PERLIN_SIZE];
|
||||
n2 += rxf * (perlin[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n2);
|
||||
n1 += ryf * (n2 - n1);
|
||||
|
||||
of += PERLIN_ZWRAP;
|
||||
n2 = perlin[of & PERLIN_SIZE];
|
||||
n2 += rxf * (perlin[(of + 1) & PERLIN_SIZE] - n2);
|
||||
n3 = perlin[(of + PERLIN_YWRAP) & PERLIN_SIZE];
|
||||
n3 += rxf * (perlin[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n3);
|
||||
n2 += ryf * (n3 - n2);
|
||||
|
||||
n1 += noise_fsc(zf) * (n2 - n1);
|
||||
|
||||
r += n1 * ampl;
|
||||
ampl *= perlin_amp_falloff;
|
||||
xi <<= 1;
|
||||
xf *= 2;
|
||||
yi <<= 1;
|
||||
yf *= 2;
|
||||
zi <<= 1;
|
||||
zf *= 2;
|
||||
|
||||
if (xf >= 1.0f) {
|
||||
xi++;
|
||||
xf--;
|
||||
}
|
||||
if (yf >= 1.0f) {
|
||||
yi++;
|
||||
yf--;
|
||||
}
|
||||
if (zf >= 1.0f) {
|
||||
zi++;
|
||||
zf--;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// [toxi 031112]
|
||||
// now adjusts to the size of the cosLUT used via
|
||||
// the new variables, defined above
|
||||
private static float noise_fsc(float i) {
|
||||
// using bagel's cosine table instead
|
||||
return 0.5f * (1.0f - perlin_cosTable[(int) (i * perlin_PI) % perlin_TWOPI]);
|
||||
}
|
||||
// precalculate sin/cos lookup tables [toxi]
|
||||
// circle resolution is determined from the actual used radii
|
||||
// passed to ellipse() method. this will automatically take any
|
||||
// scale transformations into account too
|
||||
// [toxi 031031]
|
||||
// changed table's precision to 0.5 degree steps
|
||||
// introduced new vars for more flexible code
|
||||
static final protected float sinLUT[];
|
||||
|
||||
static final protected float cosLUT[];
|
||||
|
||||
static final protected float SINCOS_PRECISION = 0.5f;
|
||||
|
||||
static final protected int SINCOS_LENGTH = (int) (360f / SINCOS_PRECISION);
|
||||
|
||||
static final float DEG_TO_RAD = (float) Math.PI / 180.0f;
|
||||
|
||||
static final float RAD_TO_DEG = 180.0f / (float) Math.PI;
|
||||
|
||||
static {
|
||||
sinLUT = new float[SINCOS_LENGTH];
|
||||
cosLUT = new float[SINCOS_LENGTH];
|
||||
for (int i = 0; i < SINCOS_LENGTH; i++) {
|
||||
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
|
||||
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Plane3f
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2390391570305327484L;
|
||||
|
||||
public Vector3f origin;
|
||||
|
||||
public Vector3f vectorA;
|
||||
|
||||
public Vector3f vectorB;
|
||||
|
||||
/**
|
||||
* these fields are not used by default and left uninitialized 'null'
|
||||
*/
|
||||
public Vector3f normal;
|
||||
|
||||
public float d = Float.NaN;
|
||||
|
||||
public Plane3f() {
|
||||
origin = new Vector3f();
|
||||
vectorA = new Vector3f();
|
||||
vectorB = new Vector3f();
|
||||
}
|
||||
|
||||
public Plane3f(Vector3f theOrigin,
|
||||
Vector3f theVectorA,
|
||||
Vector3f theVectorB) {
|
||||
origin = theOrigin;
|
||||
vectorA = theVectorA;
|
||||
vectorB = theVectorB;
|
||||
}
|
||||
|
||||
public void updateNormal() {
|
||||
if (normal == null) {
|
||||
normal = new Vector3f();
|
||||
}
|
||||
Util.calculateNormal(vectorA, vectorB, normal);
|
||||
}
|
||||
|
||||
public void updateD() {
|
||||
if (normal != null) {
|
||||
d = -normal.dot(origin);
|
||||
}
|
||||
}
|
||||
// private float intersection(Vector3f a, Vector3f b) {
|
||||
// /*
|
||||
// * updateNormal();
|
||||
// * updateD();
|
||||
// */
|
||||
//
|
||||
// float u = normal.x * a.x +
|
||||
// normal.y * a.y +
|
||||
// normal.z * a.z +
|
||||
// d;
|
||||
// u /= normal.x * (a.x - b.x) +
|
||||
// normal.y * (a.y - b.y) +
|
||||
// normal.z * (a.z - b.z);
|
||||
// return u;
|
||||
// }
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
public class Quaternion {
|
||||
|
||||
public float w;
|
||||
|
||||
public float x;
|
||||
|
||||
public float y;
|
||||
|
||||
public float z;
|
||||
|
||||
public Quaternion() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public Quaternion(float theW, float theX, float theY, float theZ) {
|
||||
w = theW;
|
||||
x = theX;
|
||||
y = theY;
|
||||
z = theZ;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
w = 1.0f;
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
public void set(float theW, Vector3f theVector3f) {
|
||||
w = theW;
|
||||
x = theVector3f.x;
|
||||
y = theVector3f.y;
|
||||
z = theVector3f.z;
|
||||
}
|
||||
|
||||
public void set(Quaternion theQuaternion) {
|
||||
w = theQuaternion.w;
|
||||
x = theQuaternion.x;
|
||||
y = theQuaternion.y;
|
||||
z = theQuaternion.z;
|
||||
}
|
||||
|
||||
public void multiply(Quaternion theA, Quaternion theB) {
|
||||
w = theA.w * theB.w - theA.x * theB.x - theA.y * theB.y - theA.z * theB.z;
|
||||
x = theA.w * theB.x + theA.x * theB.w + theA.y * theB.z - theA.z * theB.y;
|
||||
y = theA.w * theB.y + theA.y * theB.w + theA.z * theB.x - theA.x * theB.z;
|
||||
z = theA.w * theB.z + theA.z * theB.w + theA.x * theB.y - theA.y * theB.x;
|
||||
}
|
||||
|
||||
public Vector4f getVectorAndAngle() {
|
||||
final Vector4f theResult = new Vector4f();
|
||||
|
||||
float s = (float) Math.sqrt(1.0f - w * w);
|
||||
if (s < Mathematik.EPSILON) {
|
||||
s = 1.0f;
|
||||
}
|
||||
|
||||
theResult.w = (float) Math.acos(w) * 2.0f;
|
||||
theResult.x = x / s;
|
||||
theResult.y = y / s;
|
||||
theResult.z = z / s;
|
||||
|
||||
return theResult;
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* generate random numbers.<br/>
|
||||
* note that if different types are requested the random generator moves on
|
||||
* anyway.
|
||||
*/
|
||||
public class Random
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5871934750136232555L;
|
||||
|
||||
private static final java.util.Random _mySeedGenerator = new java.util.Random(System.currentTimeMillis());
|
||||
|
||||
private final java.util.Random myRandomNumberGenerator;
|
||||
|
||||
private static final Random _myInstance;
|
||||
|
||||
static {
|
||||
_myInstance = new Random();
|
||||
}
|
||||
|
||||
public static float FLOAT(float theStart, float theEnd) {
|
||||
return _myInstance.getFloat(theStart, theEnd);
|
||||
}
|
||||
|
||||
public static float INT(int theStart, int theEnd) {
|
||||
return _myInstance.getInt(theStart, theEnd);
|
||||
}
|
||||
|
||||
public Random() {
|
||||
this(_mySeedGenerator.nextLong());
|
||||
}
|
||||
|
||||
public Random(long theSeed) {
|
||||
myRandomNumberGenerator = new java.util.Random(theSeed);
|
||||
}
|
||||
|
||||
public void setSeed(long theSeed) {
|
||||
myRandomNumberGenerator.setSeed(theSeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a random int value from theStart to theEnd, including both values.
|
||||
*
|
||||
* @param theStart int
|
||||
* @param theEnd int
|
||||
* @return int
|
||||
*/
|
||||
public int getInt(int theStart,
|
||||
int theEnd) {
|
||||
int myDiff = (theEnd + 1) - theStart;
|
||||
return myRandomNumberGenerator.nextInt(myDiff) + theStart;
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
return myRandomNumberGenerator.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* return a random float value from theStart to theEnd, excluding both
|
||||
* values.
|
||||
*
|
||||
* @param theStart float
|
||||
* @param theEnd float
|
||||
* @return float
|
||||
*/
|
||||
public float getFloat(float theStart,
|
||||
float theEnd) {
|
||||
final float myDiff = theEnd - theStart;
|
||||
final float myRandomValue = myRandomNumberGenerator.nextFloat() * myDiff;
|
||||
return myRandomValue + theStart;
|
||||
}
|
||||
|
||||
public float getFloat() {
|
||||
return myRandomNumberGenerator.nextFloat();
|
||||
}
|
||||
|
||||
// public static float getFloat(float theStart,
|
||||
// float theEnd) {
|
||||
// return _mySeedGenerator.getFloat(theStart, theEnd);
|
||||
// }
|
||||
public Vector3f getVector3f(float theStart, float theEnd) {
|
||||
return new Vector3f(getFloat(theStart, theEnd),
|
||||
getFloat(theStart, theEnd),
|
||||
getFloat(theStart, theEnd));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
long myTime;
|
||||
Random myRandom;
|
||||
|
||||
myRandom = new Random();
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println("***");
|
||||
|
||||
myRandom = new Random();
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println(myRandom.getInt(20, 100));
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println(myRandom.getFloat(20, 100));
|
||||
System.out.println("***");
|
||||
|
||||
/* use this random generator */
|
||||
myTime = System.currentTimeMillis();
|
||||
myRandom = new Random(0);
|
||||
for (int i = 0; i < 50000000; i++) {
|
||||
float myValue = myRandom.getFloat(20, 100);
|
||||
if (myValue < 20 || myValue > 100) {
|
||||
System.out.println(i + "ERROR");
|
||||
}
|
||||
}
|
||||
System.out.println("DONE: " + (System.currentTimeMillis() - myTime));
|
||||
|
||||
/* use maths random generator */
|
||||
myTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < 50000000; i++) {
|
||||
float myValue = (float) Math.random() * (100 - 20) + 20;
|
||||
if (myValue < 20 || myValue > 100) {
|
||||
System.out.println(i + "ERROR");
|
||||
}
|
||||
}
|
||||
System.out.println("DONE: " + (System.currentTimeMillis() - myTime));
|
||||
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Ray3f
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1748179277316146625L;
|
||||
|
||||
public Vector3f origin;
|
||||
|
||||
public Vector3f direction;
|
||||
|
||||
public Ray3f() {
|
||||
origin = new Vector3f();
|
||||
direction = new Vector3f();
|
||||
}
|
||||
|
||||
public Ray3f(Vector3f theOrigin,
|
||||
Vector3f theDirection) {
|
||||
origin = theOrigin;
|
||||
direction = theDirection;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "origin + " + origin + " / " + " direction " + direction;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public class Rayf<T extends Vectorf>
|
||||
implements Serializable, Vectorf {
|
||||
|
||||
private static final long serialVersionUID = -1748179277316146234L;
|
||||
|
||||
public T origin;
|
||||
|
||||
public T direction;
|
||||
|
||||
public Rayf(Class<T> theClass) {
|
||||
try {
|
||||
origin = theClass.newInstance();
|
||||
direction = theClass.newInstance();
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (InstantiationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Rayf(T theOrigin,
|
||||
T theDirection) {
|
||||
origin = theOrigin;
|
||||
direction = theDirection;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "origin + " + origin + " / " + " direction " + direction;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Rectangle3f
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7295490882726338294L;
|
||||
|
||||
public Vector3f origin;
|
||||
|
||||
public Vector3f scale;
|
||||
|
||||
public Rectangle3f() {
|
||||
origin = new Vector3f();
|
||||
scale = new Vector3f();
|
||||
}
|
||||
|
||||
public Rectangle3f(Vector3f theOrigin,
|
||||
Vector3f theScale) {
|
||||
origin = theOrigin;
|
||||
scale = theScale;
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* write the current rotation into the result transformation matrix.
|
||||
* if the velocity sampler is enabled the velocity will averaged
|
||||
* to avoid jerky turning.
|
||||
*/
|
||||
/**
|
||||
* @todo the sampling would be more accurate if the delta time would also be
|
||||
* taken into account when updating the sampler.
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
public class Rotation {
|
||||
|
||||
private Vector3f[] _myVelocitySampler;
|
||||
|
||||
private final Vector3f _myUpVector;
|
||||
|
||||
private final Vector3f _myCurrentAverageVelocity;
|
||||
|
||||
private final Vector3f _myAverageVelocity;
|
||||
|
||||
private int _myVelocitySamplerPosition;
|
||||
|
||||
private final Vector3f _myTempUpVector;
|
||||
|
||||
private final Vector3f _myTempSideVector;
|
||||
|
||||
private final Vector3f _myTempForwardVector;
|
||||
|
||||
public Rotation() {
|
||||
this(1);
|
||||
}
|
||||
|
||||
public Rotation(final int theVelocitySamplerSize) {
|
||||
_myVelocitySamplerPosition = 0;
|
||||
setVelocitySamplerSize(theVelocitySamplerSize);
|
||||
_myUpVector = new Vector3f(0, 0, 1);
|
||||
_myAverageVelocity = new Vector3f();
|
||||
_myCurrentAverageVelocity = new Vector3f();
|
||||
_myTempUpVector = new Vector3f();
|
||||
_myTempSideVector = new Vector3f();
|
||||
_myTempForwardVector = new Vector3f();
|
||||
}
|
||||
|
||||
public void setVelocitySamplerSize(final int theVelocitySamplerSize) {
|
||||
_myVelocitySampler = new Vector3f[theVelocitySamplerSize];
|
||||
for (int i = 0; i < _myVelocitySampler.length; ++i) {
|
||||
_myVelocitySampler[i] = new Vector3f();
|
||||
}
|
||||
}
|
||||
|
||||
public void flattenVelocitySampler(final Vector3f theVelocity) {
|
||||
for (int i = 0; i < _myVelocitySampler.length; i++) {
|
||||
add(theVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(final Vector3f theVelocity) {
|
||||
_myVelocitySamplerPosition++;
|
||||
_myVelocitySamplerPosition %= _myVelocitySampler.length;
|
||||
_myAverageVelocity.sub(_myVelocitySampler[_myVelocitySamplerPosition]);
|
||||
_myVelocitySampler[_myVelocitySamplerPosition].set(theVelocity);
|
||||
_myAverageVelocity.add(theVelocity);
|
||||
_myCurrentAverageVelocity.set(_myAverageVelocity);
|
||||
_myCurrentAverageVelocity.scale(1.0f / (float) _myVelocitySampler.length);
|
||||
}
|
||||
|
||||
public void set(final Vector3f theVelocity,
|
||||
final TransformMatrix4f theResult) {
|
||||
if (_myVelocitySampler.length == 1) {
|
||||
pointAt(theVelocity, theResult);
|
||||
} else {
|
||||
add(theVelocity);
|
||||
pointAt(_myCurrentAverageVelocity, theResult);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(final TransformMatrix4f theResult) {
|
||||
pointAt(_myCurrentAverageVelocity, theResult);
|
||||
}
|
||||
|
||||
public void set(final Matrix3f theResult) {
|
||||
pointAt(_myCurrentAverageVelocity, theResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use 'set' instead.
|
||||
* @param theVelocity Vector3f
|
||||
* @param theResult TransformMatrix4f
|
||||
*/
|
||||
public void setRotationMatrix(final Vector3f theVelocity,
|
||||
final TransformMatrix4f theResult) {
|
||||
set(theVelocity, theResult);
|
||||
}
|
||||
|
||||
public Vector3f getAverageVelocity() {
|
||||
return _myCurrentAverageVelocity;
|
||||
}
|
||||
|
||||
public void setUpVector(final Vector3f theUpVector) {
|
||||
_myUpVector.set(theUpVector);
|
||||
}
|
||||
|
||||
public void setUpVectorByAngle(final float roll) {
|
||||
/**
|
||||
* @todo this is not thought through...
|
||||
*/
|
||||
_myUpVector.x = (float) Math.sin(roll);
|
||||
_myUpVector.z = -(float) Math.cos(roll);
|
||||
_myUpVector.y = 0;
|
||||
}
|
||||
|
||||
private void pointAt(final Vector3f theForwardVector,
|
||||
final Matrix3f theResult) {
|
||||
/* get sideVector */
|
||||
_myTempSideVector.cross(_myUpVector, theForwardVector);
|
||||
_myTempSideVector.normalize();
|
||||
/* get 'real' upVector */
|
||||
_myTempUpVector.cross(_myTempSideVector, theForwardVector);
|
||||
_myTempUpVector.normalize();
|
||||
/* get forwardVector */
|
||||
_myTempForwardVector.set(theForwardVector);
|
||||
_myTempForwardVector.normalize();
|
||||
/* fill transformation matrix */
|
||||
theResult.setXAxis(_myTempForwardVector);
|
||||
theResult.setYAxis(_myTempSideVector);
|
||||
theResult.setZAxis(_myTempUpVector);
|
||||
}
|
||||
|
||||
private void pointAt(final Vector3f theForwardVector,
|
||||
final TransformMatrix4f theResult) {
|
||||
pointAt(theForwardVector, theResult.rotation);
|
||||
}
|
||||
}
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* special form of a 4x4 matrix. first of all the way we represent the matrix in
|
||||
* this class is similar to the way opengl handles the row column issue.
|
||||
*
|
||||
* transform matrix -- r = rotation, t = translation
|
||||
*
|
||||
* rxx rxy rxz 0 ryx ryy ryz 0 rzx rzy rzz 0 tx ty tz 1
|
||||
*
|
||||
* the transform matrix is special in the way that is a 3x3 matrix for rotation
|
||||
* and scale and a translation vector. the remaining four values a constants.
|
||||
*
|
||||
* this is the way opengl specifies a 4x4 matrix and also the way 'toArray'
|
||||
* returns an array.
|
||||
*
|
||||
* m[0] m[4] m[8] m[12]
|
||||
*
|
||||
* m[1] m[5] m[9] m[13]
|
||||
*
|
||||
* M=( )
|
||||
*
|
||||
* m[2] m[6] m[10] m[14]
|
||||
*
|
||||
* m[3] m[7] m[11] m[15]
|
||||
*
|
||||
*
|
||||
* here is an excerpt from the glMultMatrix man page.
|
||||
*
|
||||
* "In many computer languages 4x4 arrays are represented in row-major order.
|
||||
* The transformations just described represent these matrices in column-major
|
||||
* order. The order of the multiplication is important. For example, if the
|
||||
* current transformation is a rotation, and glMultMatrix is called with a
|
||||
* translation matrix, the translation is done directly on the coordinates to be
|
||||
* transformed, while the rotation is done on the results of that translation."
|
||||
*
|
||||
* also read 'The Matrix and Quaternions FAQ' at
|
||||
* http://www.flipcode.com/documents/matrfaq.html
|
||||
*/
|
||||
public class TransformMatrix4f
|
||||
implements Serializable {
|
||||
|
||||
public static int IDENTITY = 1;
|
||||
|
||||
public Matrix3f rotation;
|
||||
|
||||
public Vector3f translation;
|
||||
|
||||
private static final long serialVersionUID = 2946060493174800199L;
|
||||
|
||||
private static final float ZERO = 0;
|
||||
|
||||
private static final float ONE = 1;
|
||||
|
||||
private final float[] _myArrayRepresentation = new float[16];
|
||||
|
||||
public TransformMatrix4f() {
|
||||
translation = new Vector3f();
|
||||
rotation = new Matrix3f();
|
||||
}
|
||||
|
||||
public TransformMatrix4f(int theType) {
|
||||
translation = new Vector3f();
|
||||
rotation = new Matrix3f(theType);
|
||||
toArray();
|
||||
}
|
||||
|
||||
public TransformMatrix4f(TransformMatrix4f theMatrix4f) {
|
||||
this();
|
||||
set(theMatrix4f);
|
||||
toArray();
|
||||
}
|
||||
|
||||
public TransformMatrix4f(float[] theMatrixArray) {
|
||||
this();
|
||||
set(theMatrixArray);
|
||||
toArray();
|
||||
}
|
||||
|
||||
public final void setIdentity() {
|
||||
translation.set(0,
|
||||
0,
|
||||
0);
|
||||
rotation.setIdentity();
|
||||
}
|
||||
|
||||
public final void setRotationIdentity() {
|
||||
rotation.setIdentity();
|
||||
}
|
||||
|
||||
public final void setZero() {
|
||||
translation.set(0,
|
||||
0,
|
||||
0);
|
||||
rotation.setZero();
|
||||
}
|
||||
|
||||
public final float determinant() {
|
||||
float d = rotation.xx
|
||||
* ((rotation.yy * rotation.zz * ONE + rotation.yz * translation.z * ZERO
|
||||
+ translation.y * rotation.zy * ZERO)
|
||||
- translation.y * rotation.zz * ZERO - rotation.yy * translation.z * ZERO - rotation.yz
|
||||
* rotation.zy * ONE);
|
||||
d -= rotation.xy
|
||||
* ((rotation.yx * rotation.zz * ONE + rotation.yz * translation.z * ZERO
|
||||
+ translation.y * rotation.zx * ZERO)
|
||||
- translation.y * rotation.zz * ZERO - rotation.yx * translation.z * ZERO - rotation.yz
|
||||
* rotation.zx * ONE);
|
||||
d += rotation.xz
|
||||
* ((rotation.yx * rotation.zy * ONE + rotation.yy * translation.z * ZERO
|
||||
+ translation.y * rotation.zx * ZERO)
|
||||
- translation.y * rotation.zy * ZERO - rotation.yx * translation.z * ZERO - rotation.yy
|
||||
* rotation.zx * ONE);
|
||||
d -= translation.x
|
||||
* ((rotation.yx * rotation.zy * ZERO + rotation.yy * rotation.zz * ZERO + rotation.yz * rotation.zx * ZERO)
|
||||
- rotation.yz * rotation.zy * ZERO - rotation.yx * rotation.zz * ZERO - rotation.yy
|
||||
* rotation.zx * ZERO);
|
||||
return d;
|
||||
}
|
||||
|
||||
public final void set(TransformMatrix4f mat) {
|
||||
rotation.set(mat.rotation);
|
||||
translation.set(mat.translation);
|
||||
}
|
||||
|
||||
public final void set(float[] theArrayRepresentation) {
|
||||
rotation.xx = theArrayRepresentation[0];
|
||||
rotation.yx = theArrayRepresentation[1];
|
||||
rotation.zx = theArrayRepresentation[2];
|
||||
/* 3 */
|
||||
rotation.xy = theArrayRepresentation[4];
|
||||
rotation.yy = theArrayRepresentation[5];
|
||||
rotation.zy = theArrayRepresentation[6];
|
||||
/* 7 */
|
||||
rotation.xz = theArrayRepresentation[8];
|
||||
rotation.yz = theArrayRepresentation[9];
|
||||
rotation.zz = theArrayRepresentation[10];
|
||||
/* 11 */
|
||||
translation.x = theArrayRepresentation[12];
|
||||
translation.y = theArrayRepresentation[13];
|
||||
translation.z = theArrayRepresentation[14];
|
||||
/* 15 */
|
||||
}
|
||||
|
||||
public final void multiply(float theValue) {
|
||||
rotation.xx *= theValue;
|
||||
rotation.xy *= theValue;
|
||||
rotation.xz *= theValue;
|
||||
translation.x *= theValue;
|
||||
rotation.yx *= theValue;
|
||||
rotation.yy *= theValue;
|
||||
rotation.yz *= theValue;
|
||||
translation.y *= theValue;
|
||||
rotation.zx *= theValue;
|
||||
rotation.zy *= theValue;
|
||||
rotation.zz *= theValue;
|
||||
translation.z *= theValue;
|
||||
}
|
||||
|
||||
public final void multiply(float theValue,
|
||||
TransformMatrix4f theMatrix4f) {
|
||||
rotation.xx = theMatrix4f.rotation.xx * theValue;
|
||||
rotation.xy = theMatrix4f.rotation.xy * theValue;
|
||||
rotation.xz = theMatrix4f.rotation.xz * theValue;
|
||||
translation.x = theMatrix4f.translation.x * theValue;
|
||||
rotation.yx = theMatrix4f.rotation.yx * theValue;
|
||||
rotation.yy = theMatrix4f.rotation.yy * theValue;
|
||||
rotation.yz = theMatrix4f.rotation.yz * theValue;
|
||||
translation.y = theMatrix4f.translation.y * theValue;
|
||||
rotation.zx = theMatrix4f.rotation.zx * theValue;
|
||||
rotation.zy = theMatrix4f.rotation.zy * theValue;
|
||||
rotation.zz = theMatrix4f.rotation.zz * theValue;
|
||||
translation.z = theMatrix4f.translation.z * theValue;
|
||||
}
|
||||
|
||||
public final void multiply(TransformMatrix4f theMatrix4f) {
|
||||
float tmp1 = rotation.xx * theMatrix4f.rotation.xx + rotation.xy * theMatrix4f.rotation.yx
|
||||
+ rotation.xz * theMatrix4f.rotation.zx + translation.x * TransformMatrix4f.ZERO;
|
||||
float tmp2 = rotation.xx * theMatrix4f.rotation.xy + rotation.xy * theMatrix4f.rotation.yy
|
||||
+ rotation.xz * theMatrix4f.rotation.zy + translation.x * TransformMatrix4f.ZERO;
|
||||
float tmp3 = rotation.xx * theMatrix4f.rotation.xz + rotation.xy * theMatrix4f.rotation.yz
|
||||
+ rotation.xz * theMatrix4f.rotation.zz + translation.x * TransformMatrix4f.ZERO;
|
||||
float tmp4 = rotation.xx * theMatrix4f.translation.x + rotation.xy * theMatrix4f.translation.y
|
||||
+ rotation.xz * theMatrix4f.translation.z + translation.x * TransformMatrix4f.ONE;
|
||||
|
||||
float tmp5 = rotation.yx * theMatrix4f.rotation.xx + rotation.yy * theMatrix4f.rotation.yx
|
||||
+ rotation.yz * theMatrix4f.rotation.zx + translation.y * TransformMatrix4f.ZERO;
|
||||
float tmp6 = rotation.yx * theMatrix4f.rotation.xy + rotation.yy * theMatrix4f.rotation.yy
|
||||
+ rotation.yz * theMatrix4f.rotation.zy + translation.y * TransformMatrix4f.ZERO;
|
||||
float tmp7 = rotation.yx * theMatrix4f.rotation.xz + rotation.yy * theMatrix4f.rotation.yz
|
||||
+ rotation.yz * theMatrix4f.rotation.zz + translation.y * TransformMatrix4f.ZERO;
|
||||
float tmp8 = rotation.yx * theMatrix4f.translation.x + rotation.yy * theMatrix4f.translation.y
|
||||
+ rotation.yz * theMatrix4f.translation.z + translation.y * TransformMatrix4f.ONE;
|
||||
|
||||
float tmp9 = rotation.zx * theMatrix4f.rotation.xx + rotation.zy * theMatrix4f.rotation.yx
|
||||
+ rotation.zz * theMatrix4f.rotation.zx + translation.z * TransformMatrix4f.ZERO;
|
||||
float tmp10 = rotation.zx * theMatrix4f.rotation.xy + rotation.zy * theMatrix4f.rotation.yy
|
||||
+ rotation.zz * theMatrix4f.rotation.zy + translation.z * TransformMatrix4f.ZERO;
|
||||
float tmp11 = rotation.zx * theMatrix4f.rotation.xz + rotation.zy * theMatrix4f.rotation.yz
|
||||
+ rotation.zz * theMatrix4f.rotation.zz + translation.z * TransformMatrix4f.ZERO;
|
||||
float tmp12 = rotation.zx * theMatrix4f.translation.x + rotation.zy * theMatrix4f.translation.y
|
||||
+ rotation.zz * theMatrix4f.translation.z + translation.z * TransformMatrix4f.ONE;
|
||||
|
||||
/*
|
||||
float temp13 = m30 * in2.m00 +
|
||||
m31 * in2.m10 +
|
||||
m32 * in2.m20 +
|
||||
m33 * in2.m30;
|
||||
float temp14 = m30 * in2.m01 +
|
||||
m31 * in2.m11 +
|
||||
m32 * in2.m21 +
|
||||
m33 * in2.m31;
|
||||
float temp15 = m30 * in2.m02 +
|
||||
m31 * in2.m12 +
|
||||
m32 * in2.m22 +
|
||||
m33 * in2.m32;
|
||||
float temp16 = m30 * in2.m03 +
|
||||
m31 * in2.m13 +
|
||||
m32 * in2.m23 +
|
||||
m33 * in2.m33;
|
||||
*/
|
||||
|
||||
rotation.xx = tmp1;
|
||||
rotation.xy = tmp2;
|
||||
rotation.xz = tmp3;
|
||||
translation.x = tmp4;
|
||||
rotation.yx = tmp5;
|
||||
rotation.yy = tmp6;
|
||||
rotation.yz = tmp7;
|
||||
translation.y = tmp8;
|
||||
rotation.zx = tmp9;
|
||||
rotation.zy = tmp10;
|
||||
rotation.zz = tmp11;
|
||||
translation.z = tmp12;
|
||||
}
|
||||
|
||||
public final void transform(Vector3f theResult) {
|
||||
/**
|
||||
* @todo check if this is right...
|
||||
*/
|
||||
theResult.set(rotation.xx * theResult.x
|
||||
+ rotation.xy * theResult.y
|
||||
+ rotation.xz * theResult.z
|
||||
+ translation.x,
|
||||
rotation.yx * theResult.x
|
||||
+ rotation.yy * theResult.y
|
||||
+ rotation.yz * theResult.z
|
||||
+ translation.y,
|
||||
rotation.zx * theResult.x
|
||||
+ rotation.zy * theResult.y
|
||||
+ rotation.zz * theResult.z
|
||||
+ translation.z);
|
||||
}
|
||||
|
||||
public final float[] toArray() {
|
||||
/* so that opengl can understand it */
|
||||
_myArrayRepresentation[0] = rotation.xx;
|
||||
_myArrayRepresentation[1] = rotation.yx;
|
||||
_myArrayRepresentation[2] = rotation.zx;
|
||||
_myArrayRepresentation[3] = ZERO;
|
||||
_myArrayRepresentation[4] = rotation.xy;
|
||||
_myArrayRepresentation[5] = rotation.yy;
|
||||
_myArrayRepresentation[6] = rotation.zy;
|
||||
_myArrayRepresentation[7] = ZERO;
|
||||
_myArrayRepresentation[8] = rotation.xz;
|
||||
_myArrayRepresentation[9] = rotation.yz;
|
||||
_myArrayRepresentation[10] = rotation.zz;
|
||||
_myArrayRepresentation[11] = ZERO;
|
||||
_myArrayRepresentation[12] = translation.x;
|
||||
_myArrayRepresentation[13] = translation.y;
|
||||
_myArrayRepresentation[14] = translation.z;
|
||||
_myArrayRepresentation[15] = ONE;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return rotation.xx + ", " + rotation.yx + ", " + rotation.zx + ", " + "0.0" + "\n" + rotation.xy + ", "
|
||||
+ rotation.yy + ", " + rotation.zy + ", " + "0.0" + "\n" + rotation.xz + ", " + rotation.yz + ", "
|
||||
+ rotation.zz + ", " + "0.0" + "\n" + translation.x + ", " + translation.y + ", " + translation.z
|
||||
+ ", " + "1.0";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/* multiplying matrices */
|
||||
TransformMatrix4f myScaleMatrix = new TransformMatrix4f(TransformMatrix4f.IDENTITY);
|
||||
myScaleMatrix.rotation.setXAxis(new Vector3f(2, 0, 0));
|
||||
myScaleMatrix.rotation.setYAxis(new Vector3f(0, 2, 0));
|
||||
myScaleMatrix.rotation.setZAxis(new Vector3f(0, 0, 2));
|
||||
|
||||
TransformMatrix4f myTranslateMatrix = new TransformMatrix4f(TransformMatrix4f.IDENTITY);
|
||||
myTranslateMatrix.translation.set(2,
|
||||
3,
|
||||
4);
|
||||
|
||||
myScaleMatrix.multiply(myScaleMatrix);
|
||||
myScaleMatrix.multiply(myTranslateMatrix);
|
||||
System.out.println(myScaleMatrix);
|
||||
|
||||
/* transform position */
|
||||
System.out.println("\n### translate");
|
||||
System.out.println(myTranslateMatrix);
|
||||
System.out.println();
|
||||
Vector3f myVector = new Vector3f(10, 5, 7);
|
||||
myTranslateMatrix.transform(myVector);
|
||||
System.out.println(myVector);
|
||||
}
|
||||
}
|
||||
+931
@@ -0,0 +1,931 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* a loose collection of linear algebra methods that are not connected to a
|
||||
* specific class.
|
||||
*
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
public static final Vector3f AXIS_X = new Vector3f(1, 0, 0);
|
||||
|
||||
public static final Vector3f AXIS_Y = new Vector3f(0, 1, 0);
|
||||
|
||||
public static final Vector3f AXIS_Z = new Vector3f(0, 0, 1);
|
||||
|
||||
public static final float areaTriangle(final Vector3f v0,
|
||||
final Vector3f v1,
|
||||
final Vector3f v2) {
|
||||
final Vector3f myAB = sub(v1, v0);
|
||||
final Vector3f myAC = sub(v2, v0);
|
||||
final Vector3f myCross = cross(myAB, myAC);
|
||||
return 0.5f * myCross.magnitude();
|
||||
}
|
||||
|
||||
public float length(Vector3f theVector3f) {
|
||||
return theVector3f.length();
|
||||
}
|
||||
|
||||
public static final boolean isPointInTriangle(final Vector3f v0,
|
||||
final Vector3f v1,
|
||||
final Vector3f v2,
|
||||
final Vector3f thePoint) {
|
||||
// // Compute vectors
|
||||
// v0 = C - A
|
||||
// v1 = B - A
|
||||
// v2 = P - A
|
||||
|
||||
Vector3f v00 = new Vector3f(v2);
|
||||
v00.sub(v0);
|
||||
|
||||
Vector3f v01 = new Vector3f(v1);
|
||||
v01.sub(v0);
|
||||
|
||||
Vector3f v02 = new Vector3f(thePoint);
|
||||
v02.sub(v0);
|
||||
|
||||
// Compute dot products
|
||||
|
||||
float dot00 = v00.dot(v00);
|
||||
float dot01 = v00.dot(v01);
|
||||
float dot02 = v00.dot(v02);
|
||||
float dot11 = v01.dot(v01);
|
||||
float dot12 = v01.dot(v02);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
||||
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
|
||||
// Check if point is in triangle
|
||||
return (u > 0) && (v > 0) && (u + v < 1);
|
||||
}
|
||||
|
||||
|
||||
/* contain */
|
||||
public static final boolean contains(final Vector3f thePosition,
|
||||
final WorldAxisAlignedBoundingBox theWorldAlignedBox) {
|
||||
return (contains(thePosition.x, theWorldAlignedBox.position.x, theWorldAlignedBox.scale.x)
|
||||
&& contains(thePosition.y, theWorldAlignedBox.position.y, theWorldAlignedBox.scale.y)
|
||||
&& contains(thePosition.z, theWorldAlignedBox.position.z, theWorldAlignedBox.scale.z));
|
||||
}
|
||||
|
||||
public static final boolean contains(final float theTestValue,
|
||||
final float theContainerValue,
|
||||
final float theRange) {
|
||||
return (theTestValue > theContainerValue - theRange * 0.5f
|
||||
&& theTestValue < theContainerValue + theRange * 0.5f);
|
||||
}
|
||||
|
||||
public static boolean insidePolygon(Vector2f thePoint, Vector2f[] thePolygon) {
|
||||
float x = thePoint.x;
|
||||
float y = thePoint.y;
|
||||
|
||||
int c = 0;
|
||||
for (int i = 0, j = thePolygon.length - 1; i < thePolygon.length; j = i++) {
|
||||
if ((((thePolygon[i].y <= y) && (y < thePolygon[j].y))
|
||||
|| ((thePolygon[j].y <= y) && (y < thePolygon[i].y)))
|
||||
&& (x < (thePolygon[j].x - thePolygon[i].x) * (y - thePolygon[i].y)
|
||||
/ (thePolygon[j].y - thePolygon[i].y) + thePolygon[i].x)) {
|
||||
c = (c + 1) % 2;
|
||||
}
|
||||
}
|
||||
return c == 1;
|
||||
}
|
||||
|
||||
public static final boolean insidePolygon(final Vector2f thePoint, final Vector<Vector2f> thePolygon) {
|
||||
float x = thePoint.x;
|
||||
float y = thePoint.y;
|
||||
|
||||
int c = 0;
|
||||
for (int i = 0, j = thePolygon.size() - 1; i < thePolygon.size(); j = i++) {
|
||||
if ((((thePolygon.get(i).y <= y) && (y < thePolygon.get(j).y))
|
||||
|| ((thePolygon.get(j).y <= y) && (y < thePolygon.get(i).y)))
|
||||
&& (x < (thePolygon.get(j).x - thePolygon.get(i).x) * (y - thePolygon.get(i).y)
|
||||
/ (thePolygon.get(j).y - thePolygon.get(i).y) + thePolygon.get(i).x)) {
|
||||
c = (c + 1) % 2;
|
||||
}
|
||||
}
|
||||
return c == 1;
|
||||
}
|
||||
|
||||
public static final boolean inside2DPolygon(final Vector3f thePoint, final Vector<Vector3f> thePolygon) {
|
||||
float x = thePoint.x;
|
||||
float y = thePoint.y;
|
||||
|
||||
int c = 0;
|
||||
for (int i = 0, j = thePolygon.size() - 1; i < thePolygon.size(); j = i++) {
|
||||
if ((((thePolygon.get(i).y <= y) && (y < thePolygon.get(j).y))
|
||||
|| ((thePolygon.get(j).y <= y) && (y < thePolygon.get(i).y)))
|
||||
&& (x < (thePolygon.get(j).x - thePolygon.get(i).x) * (y - thePolygon.get(i).y)
|
||||
/ (thePolygon.get(j).y - thePolygon.get(i).y) + thePolygon.get(i).x)) {
|
||||
c = (c + 1) % 2;
|
||||
}
|
||||
}
|
||||
return c == 1;
|
||||
}
|
||||
private static final Vector3f _myTempMin = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempMax = new Vector3f();
|
||||
|
||||
public static void updateBoundingBox(final WorldAxisAlignedBoundingBox theWorldAxisAlignedBoundingBox,
|
||||
final Vector3f[] myVectors) {
|
||||
|
||||
if (myVectors == null || myVectors.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get minimum and maximum */
|
||||
_myTempMin.set(myVectors[0]);
|
||||
_myTempMax.set(myVectors[0]);
|
||||
|
||||
for (int i = 1; i < myVectors.length; i++) {
|
||||
/* minimum */
|
||||
if (_myTempMin.x > myVectors[i].x) {
|
||||
_myTempMin.x = myVectors[i].x;
|
||||
}
|
||||
if (_myTempMin.y > myVectors[i].y) {
|
||||
_myTempMin.y = myVectors[i].y;
|
||||
}
|
||||
if (_myTempMin.z > myVectors[i].z) {
|
||||
_myTempMin.z = myVectors[i].z;
|
||||
}
|
||||
/* maximum */
|
||||
if (_myTempMax.x < myVectors[i].x) {
|
||||
_myTempMax.x = myVectors[i].x;
|
||||
}
|
||||
if (_myTempMax.y < myVectors[i].y) {
|
||||
_myTempMax.y = myVectors[i].y;
|
||||
}
|
||||
if (_myTempMax.z < myVectors[i].z) {
|
||||
_myTempMax.z = myVectors[i].z;
|
||||
}
|
||||
}
|
||||
|
||||
/* create world aligned boundingbox */
|
||||
/* bb position */
|
||||
theWorldAxisAlignedBoundingBox.position.sub(_myTempMax, _myTempMin);
|
||||
theWorldAxisAlignedBoundingBox.position.scale(0.5f);
|
||||
theWorldAxisAlignedBoundingBox.position.add(_myTempMin);
|
||||
/* bb scale */
|
||||
theWorldAxisAlignedBoundingBox.scale.sub(_myTempMax, _myTempMin);
|
||||
theWorldAxisAlignedBoundingBox.scale.x = Math.abs(theWorldAxisAlignedBoundingBox.scale.x);
|
||||
theWorldAxisAlignedBoundingBox.scale.y = Math.abs(theWorldAxisAlignedBoundingBox.scale.y);
|
||||
theWorldAxisAlignedBoundingBox.scale.z = Math.abs(theWorldAxisAlignedBoundingBox.scale.z);
|
||||
}
|
||||
/* transforms */
|
||||
private static final Vector3f _myTempForwardVector = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempSideVector = new Vector3f();
|
||||
|
||||
private static final Vector3f _myTempUpVector = new Vector3f();
|
||||
|
||||
public static void pointAt(final TransformMatrix4f theResult,
|
||||
final Vector3f theUpVector,
|
||||
final Vector3f thePointAtPosition) {
|
||||
|
||||
pointAt(theResult,
|
||||
theResult.translation,
|
||||
theUpVector,
|
||||
thePointAtPosition);
|
||||
|
||||
// /* forward */
|
||||
// _myTempForwardVector.sub(theResult.translation, thePointAtPosition);
|
||||
// _myTempForwardVector.normalize();
|
||||
//
|
||||
// /* side */
|
||||
// _myTempSideVector.cross(theUpVector, _myTempForwardVector);
|
||||
// _myTempSideVector.normalize();
|
||||
//
|
||||
// /* up */
|
||||
// _myTempUpVector.cross(_myTempForwardVector, _myTempSideVector);
|
||||
// _myTempUpVector.normalize();
|
||||
//
|
||||
// if (!_myTempSideVector.isNaN() &&
|
||||
// !_myTempUpVector.isNaN() &&
|
||||
// !_myTempForwardVector.isNaN()) {
|
||||
// theResult.rotation.setXAxis(_myTempSideVector);
|
||||
// theResult.rotation.setYAxis(_myTempUpVector);
|
||||
// theResult.rotation.setZAxis(_myTempForwardVector);
|
||||
// }
|
||||
}
|
||||
|
||||
public static void pointAt(final TransformMatrix4f theResult,
|
||||
final Vector3f thePosition,
|
||||
final Vector3f theUpVector,
|
||||
final Vector3f thePointAtPosition) {
|
||||
/* forward */
|
||||
_myTempForwardVector.sub(thePosition, thePointAtPosition);
|
||||
_myTempForwardVector.normalize();
|
||||
|
||||
/* side */
|
||||
_myTempSideVector.cross(theUpVector, _myTempForwardVector);
|
||||
_myTempSideVector.normalize();
|
||||
|
||||
/* up */
|
||||
_myTempUpVector.cross(_myTempForwardVector, _myTempSideVector);
|
||||
_myTempUpVector.normalize();
|
||||
|
||||
if (!_myTempSideVector.isNaN()
|
||||
&& !_myTempUpVector.isNaN()
|
||||
&& !_myTempForwardVector.isNaN()) {
|
||||
theResult.rotation.setXAxis(_myTempSideVector);
|
||||
theResult.rotation.setYAxis(_myTempUpVector);
|
||||
theResult.rotation.setZAxis(_myTempForwardVector);
|
||||
}
|
||||
}
|
||||
|
||||
public static void pointAlong(final TransformMatrix4f theResult,
|
||||
final Vector3f theForwardVector,
|
||||
final Vector3f theUpVector) {
|
||||
/* forward */
|
||||
_myTempForwardVector.set(theForwardVector);
|
||||
_myTempForwardVector.normalize();
|
||||
|
||||
/* side */
|
||||
_myTempSideVector.cross(theUpVector, _myTempForwardVector);
|
||||
_myTempSideVector.normalize();
|
||||
|
||||
/* up */
|
||||
_myTempUpVector.cross(_myTempForwardVector, _myTempSideVector);
|
||||
_myTempUpVector.normalize();
|
||||
|
||||
if (!_myTempSideVector.isNaN()
|
||||
&& !_myTempUpVector.isNaN()
|
||||
&& !_myTempForwardVector.isNaN()) {
|
||||
theResult.rotation.setXAxis(_myTempSideVector);
|
||||
theResult.rotation.setYAxis(_myTempUpVector);
|
||||
theResult.rotation.setZAxis(_myTempForwardVector);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void toLocalSpace(TransformMatrix4f theLocalSpace, Vector3f theLocalResult) {
|
||||
theLocalResult.sub(theLocalSpace.translation);
|
||||
theLocalSpace.rotation.transform(theLocalResult);
|
||||
}
|
||||
|
||||
public static final float bilinearInterp(final float x, final float y,
|
||||
final float q00,
|
||||
final float q10,
|
||||
final float q01,
|
||||
final float q11) {
|
||||
return q00 * (1 - x) * (1 - y)
|
||||
+ q10 * x * (1 - y)
|
||||
+ q01 * (1 - x) * y
|
||||
+ q11 * x * y;
|
||||
}
|
||||
/* normal */
|
||||
private static final Vector3f TMP_BA = new Vector3f();
|
||||
|
||||
private static final Vector3f TMP_BC = new Vector3f();
|
||||
|
||||
/**
|
||||
* calculate a normal from a set of three vectors.
|
||||
*
|
||||
* @param pointA
|
||||
* @param pointB
|
||||
* @param pointC
|
||||
* @param theResultNormal
|
||||
*/
|
||||
public static final void calculateNormal(final Vector3f pointA,
|
||||
final Vector3f pointB,
|
||||
final Vector3f pointC,
|
||||
final Vector3f theResultNormal) {
|
||||
TMP_BA.sub(pointB, pointA);
|
||||
TMP_BC.sub(pointC, pointB);
|
||||
|
||||
theResultNormal.cross(TMP_BA, TMP_BC);
|
||||
theResultNormal.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theVectorAB Vector3f
|
||||
* @param theVectorBC Vector3f
|
||||
* @param theResultNormal Vector3f
|
||||
*/
|
||||
public static void calculateNormal(final Vector3f theVectorAB,
|
||||
final Vector3f theVectorBC,
|
||||
final Vector3f theResultNormal) {
|
||||
theResultNormal.cross(theVectorAB, theVectorBC);
|
||||
theResultNormal.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pointA Vector3f
|
||||
* @param pointB Vector3f
|
||||
* @param pointC Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static Vector3f createNormal(final Vector3f pointA,
|
||||
final Vector3f pointB,
|
||||
final Vector3f pointC) {
|
||||
final Vector3f myResultNormal = new Vector3f();
|
||||
calculateNormal(pointA,
|
||||
pointB,
|
||||
pointC,
|
||||
myResultNormal);
|
||||
return myResultNormal;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theVectorAB Vector3f
|
||||
* @param theVectorBC Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static Vector3f createNormal(final Vector3f theVectorAB,
|
||||
final Vector3f theVectorBC) {
|
||||
final Vector3f myResultNormal = new Vector3f();
|
||||
calculateNormal(theVectorAB,
|
||||
theVectorBC,
|
||||
myResultNormal);
|
||||
return myResultNormal;
|
||||
}
|
||||
|
||||
public static void createNormals(float[] theVertices, float[] theNormals) {
|
||||
final int NUMBER_OF_VERTEX_COMPONENTS = 3;
|
||||
final int myNumberOfPoints = 3;
|
||||
for (int i = 0; i < theVertices.length;
|
||||
i += (myNumberOfPoints * NUMBER_OF_VERTEX_COMPONENTS)) {
|
||||
Vector3f a = new Vector3f(theVertices[i + 0], theVertices[i + 1], theVertices[i + 2]);
|
||||
Vector3f b = new Vector3f(theVertices[i + 3], theVertices[i + 4], theVertices[i + 5]);
|
||||
Vector3f c = new Vector3f(theVertices[i + 6], theVertices[i + 7], theVertices[i + 8]);
|
||||
Vector3f myNormal = new Vector3f();
|
||||
mathematik.Util.calculateNormal(a, b, c, myNormal);
|
||||
|
||||
theNormals[i + 0] = myNormal.x;
|
||||
theNormals[i + 1] = myNormal.y;
|
||||
theNormals[i + 2] = myNormal.z;
|
||||
|
||||
theNormals[i + 3] = myNormal.x;
|
||||
theNormals[i + 4] = myNormal.y;
|
||||
theNormals[i + 5] = myNormal.z;
|
||||
|
||||
theNormals[i + 6] = myNormal.x;
|
||||
theNormals[i + 7] = myNormal.y;
|
||||
theNormals[i + 8] = myNormal.z;
|
||||
}
|
||||
}
|
||||
/* distance */
|
||||
private static final Vector3f _myTempVector = new Vector3f();
|
||||
|
||||
/**
|
||||
* return the distance between to points defined by two vectors.
|
||||
*
|
||||
* @param theVectorA Vector3f
|
||||
* @param theVectorB Vector3f
|
||||
* @return float
|
||||
*/
|
||||
public static final float distance(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
_myTempVector.set(theVectorA);
|
||||
return _myTempVector.distance(theVectorB);
|
||||
}
|
||||
|
||||
|
||||
/* add */
|
||||
/**
|
||||
* add two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector4f
|
||||
* @param theVectorB Vector4f
|
||||
* @return Vector4f
|
||||
*/
|
||||
public static final Vector4f add(Vector4f theVectorA, Vector4f theVectorB) {
|
||||
return new Vector4f(theVectorA.w + theVectorB.w,
|
||||
theVectorA.x + theVectorB.x,
|
||||
theVectorA.y + theVectorB.y,
|
||||
theVectorA.z + theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* add two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector3f
|
||||
* @param theVectorB Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static final Vector3f add(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
return new Vector3f(theVectorA.x + theVectorB.x, theVectorA.y + theVectorB.y, theVectorA.z + theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* add two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector2f
|
||||
* @param theVectorB Vector2f
|
||||
* @return Vector2f
|
||||
*/
|
||||
public static final Vector2f add(Vector2f theVectorA, Vector2f theVectorB) {
|
||||
return new Vector2f(theVectorA.x + theVectorB.x,
|
||||
theVectorA.y + theVectorB.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* add two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector3i
|
||||
* @param theVectorB Vector3i
|
||||
* @return Vector3i
|
||||
*/
|
||||
public static final Vector3i add(Vector3i theVectorA, Vector3i theVectorB) {
|
||||
return new Vector3i(theVectorA.x + theVectorB.x, theVectorA.y + theVectorB.y, theVectorA.z + theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* add two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector2i
|
||||
* @param theVectorB Vector2i
|
||||
* @return Vector2i
|
||||
*/
|
||||
public static final Vector2i add(Vector2i theVectorA, Vector2i theVectorB) {
|
||||
return new Vector2i(theVectorA.x + theVectorB.x, theVectorA.y + theVectorB.y);
|
||||
}
|
||||
|
||||
|
||||
/* sub */
|
||||
/**
|
||||
* subtract two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector4f
|
||||
* @param theVectorB Vector4f
|
||||
* @return Vector4f
|
||||
*/
|
||||
public static final Vector4f sub(Vector4f theVectorA, Vector4f theVectorB) {
|
||||
return new Vector4f(theVectorA.w - theVectorB.w, theVectorA.x - theVectorB.x, theVectorA.y - theVectorB.y,
|
||||
theVectorA.z - theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* subtract two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector3f
|
||||
* @param theVectorB Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static final Vector3f sub(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
return new Vector3f(theVectorA.x - theVectorB.x, theVectorA.y - theVectorB.y, theVectorA.z - theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* subtract two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector2f
|
||||
* @param theVectorB Vector2f
|
||||
* @return Vector2f
|
||||
*/
|
||||
public static final Vector2f sub(Vector2f theVectorA, Vector2f theVectorB) {
|
||||
return new Vector2f(theVectorA.x - theVectorB.x, theVectorA.y - theVectorB.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* subtract two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector3i
|
||||
* @param theVectorB Vector3i
|
||||
* @return Vector3i
|
||||
*/
|
||||
public static final Vector3i sub(Vector3i theVectorA, Vector3i theVectorB) {
|
||||
return new Vector3i(theVectorA.x - theVectorB.x,
|
||||
theVectorA.y - theVectorB.y,
|
||||
theVectorA.z - theVectorB.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* subtract two vectors and return the result in a new instance.
|
||||
*
|
||||
* @param theVectorA Vector2i
|
||||
* @param theVectorB Vector2i
|
||||
* @return Vector2i
|
||||
*/
|
||||
public static final Vector2i sub(Vector2i theVectorA, Vector2i theVectorB) {
|
||||
return new Vector2i(theVectorA.x - theVectorB.x,
|
||||
theVectorA.y - theVectorB.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the cross between two vectors in a new vector.
|
||||
*
|
||||
* @param theVectorA Vector3f
|
||||
* @param theVectorB Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static final Vector3f cross(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
final Vector3f myVector = new Vector3f();
|
||||
myVector.cross(theVectorA, theVectorB);
|
||||
return myVector;
|
||||
}
|
||||
|
||||
/**
|
||||
* return a normalized vector in a new vector.
|
||||
*
|
||||
* @param theVector Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static final Vector3f normalized(Vector3f theVector) {
|
||||
final Vector3f myVector = new Vector3f(theVector);
|
||||
myVector.normalize();
|
||||
return myVector;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theVectorA Vector2f
|
||||
* @param theValue float
|
||||
* @return Vector2f
|
||||
*/
|
||||
public static final Vector2f scale(Vector2f theVectorA, float theValue) {
|
||||
return new Vector2f(theVectorA.x * theValue,
|
||||
theVectorA.y * theValue);
|
||||
}
|
||||
|
||||
public static final Vector3f scale(Vector3f theVectorA, float theValue) {
|
||||
return new Vector3f(theVectorA.x * theValue,
|
||||
theVectorA.y * theValue,
|
||||
theVectorA.z * theValue);
|
||||
}
|
||||
|
||||
public static final Vector3f scale(Vector3f theVectorA, Vector3f theValue) {
|
||||
return new Vector3f(theVectorA.x * theValue.x,
|
||||
theVectorA.y * theValue.y,
|
||||
theVectorA.z * theValue.z);
|
||||
}
|
||||
|
||||
public static final Vector4f scale(Vector4f theVectorA, float theValue) {
|
||||
return new Vector4f(theVectorA.x * theValue,
|
||||
theVectorA.y * theValue,
|
||||
theVectorA.z * theValue,
|
||||
theVectorA.w * theValue);
|
||||
}
|
||||
|
||||
public static final float clamp(float theValue, float theMin, float theMax) {
|
||||
if (theValue > theMax) {
|
||||
theValue = theMax;
|
||||
}
|
||||
if (theValue < theMin) {
|
||||
theValue = theMin;
|
||||
}
|
||||
return theValue;
|
||||
}
|
||||
|
||||
public static final float normalize(float theValue, float theStart, float theEnd) {
|
||||
return (theValue - theStart) / (theEnd - theStart);
|
||||
}
|
||||
|
||||
public static final float map(float theValue, float theInStart, float theInEnd, float theOutStart, float theOutEnd) {
|
||||
return theOutStart + (theOutEnd - theOutStart) * ((theValue - theInStart) / (theInEnd - theInStart));
|
||||
}
|
||||
|
||||
public static Vector2f parseVector2f(String theString) {
|
||||
String splitter;
|
||||
if (contains(theString, ",")) {
|
||||
splitter = ",";
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
String[] coords = theString.split(splitter);
|
||||
return new Vector2f(Float.parseFloat(coords[0]),
|
||||
Float.parseFloat(coords[1]));
|
||||
}
|
||||
|
||||
public static Vector3f parseVector3f(String theString) {
|
||||
String splitter;
|
||||
if (contains(theString, ",")) {
|
||||
splitter = ",";
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
String[] coords = theString.split(splitter);
|
||||
return new Vector3f(Float.parseFloat(coords[0]),
|
||||
Float.parseFloat(coords[1]),
|
||||
Float.parseFloat(coords[2]));
|
||||
}
|
||||
|
||||
public static boolean contains(String theString, CharSequence theContainedString) {
|
||||
return theString.indexOf(theContainedString.toString()) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* the following point rotation methods are from the famous paul bourke.
|
||||
* read more on his website at
|
||||
*
|
||||
* http://local.wasp.uwa.edu.au/~pbourke/geometry/rotate/
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Rotate a point p by angle theta around an arbitrary axis r Return the
|
||||
* rotated point. Positive angles are anticlockwise looking down the axis
|
||||
* towards the origin. Assume right hand coordinate system.
|
||||
*
|
||||
* @param p Vector3f
|
||||
* @param theta double
|
||||
* @param theAxis Vector3f
|
||||
* @return Vector3f
|
||||
*/
|
||||
public static Vector3f rotatePoint(Vector3f p,
|
||||
double theta,
|
||||
Vector3f theAxis) {
|
||||
Vector3f myR = new Vector3f();
|
||||
Vector3f q = new Vector3f();
|
||||
double costheta, sintheta;
|
||||
|
||||
myR.normalize(theAxis);
|
||||
|
||||
costheta = Math.cos(theta);
|
||||
sintheta = Math.sin(theta);
|
||||
|
||||
q.x += (costheta + (1 - costheta) * myR.x * myR.x) * p.x;
|
||||
q.x += ((1 - costheta) * myR.x * myR.y - myR.z * sintheta) * p.y;
|
||||
q.x += ((1 - costheta) * myR.x * myR.z + myR.y * sintheta) * p.z;
|
||||
|
||||
q.y += ((1 - costheta) * myR.x * myR.y + myR.z * sintheta) * p.x;
|
||||
q.y += (costheta + (1 - costheta) * myR.y * myR.y) * p.y;
|
||||
q.y += ((1 - costheta) * myR.y * myR.z - myR.x * sintheta) * p.z;
|
||||
|
||||
q.z += ((1 - costheta) * myR.x * myR.z - myR.y * sintheta) * p.x;
|
||||
q.z += ((1 - costheta) * myR.y * myR.z + myR.x * sintheta) * p.y;
|
||||
q.z += (costheta + (1 - costheta) * myR.z * myR.z) * p.z;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rotate a point p by angle theta around an arbitrary line segment p1-p2
|
||||
* Return the rotated point.
|
||||
* Positive angles are anticlockwise looking down the axis towards the origin.
|
||||
* Assume right hand coordinate system.
|
||||
*/
|
||||
public static Vector3f rotatePoint(Vector3f p,
|
||||
double theta,
|
||||
Vector3f p1,
|
||||
Vector3f p2) {
|
||||
Vector3f r = new Vector3f();
|
||||
Vector3f q = new Vector3f();
|
||||
Vector3f myP = new Vector3f();
|
||||
double costheta, sintheta;
|
||||
|
||||
myP.set(p);
|
||||
|
||||
r.x = p2.x - p1.x;
|
||||
r.y = p2.y - p1.y;
|
||||
r.z = p2.z - p1.z;
|
||||
myP.x -= p1.x;
|
||||
myP.y -= p1.y;
|
||||
myP.z -= p1.z;
|
||||
|
||||
r.normalize();
|
||||
|
||||
costheta = Math.cos(theta);
|
||||
sintheta = Math.sin(theta);
|
||||
|
||||
q.x += (costheta + (1 - costheta) * r.x * r.x) * myP.x;
|
||||
q.x += ((1 - costheta) * r.x * r.y - r.z * sintheta) * myP.y;
|
||||
q.x += ((1 - costheta) * r.x * r.z + r.y * sintheta) * myP.z;
|
||||
|
||||
q.y += ((1 - costheta) * r.x * r.y + r.z * sintheta) * myP.x;
|
||||
q.y += (costheta + (1 - costheta) * r.y * r.y) * myP.y;
|
||||
q.y += ((1 - costheta) * r.y * r.z - r.x * sintheta) * myP.z;
|
||||
|
||||
q.z += ((1 - costheta) * r.x * r.z - r.y * sintheta) * myP.x;
|
||||
q.z += ((1 - costheta) * r.y * r.z + r.x * sintheta) * myP.y;
|
||||
q.z += (costheta + (1 - costheta) * r.z * r.z) * myP.z;
|
||||
|
||||
q.x += p1.x;
|
||||
q.y += p1.y;
|
||||
q.z += p1.z;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* DistancePointLine Unit Test Copyright (c) 2002, All rights reserved
|
||||
*
|
||||
* Damian Coventry Tuesday, 16 July 2002
|
||||
*
|
||||
* Implementation of theory by Paul Bourke
|
||||
*
|
||||
* @param thePoint Vector3f
|
||||
* @param theLineStart Vector3f
|
||||
* @param theLineEnd Vector3f
|
||||
* @return float
|
||||
*/
|
||||
public static float distancePointLineSegment(final Vector3f thePoint,
|
||||
final Vector3f theLineStart,
|
||||
final Vector3f theLineEnd) {
|
||||
final float u = distancePointLineU(thePoint, theLineStart, theLineEnd);
|
||||
|
||||
if (u < 0.0f || u > 1.0f) {
|
||||
return -1; // closest point does not fall within the line segment
|
||||
}
|
||||
|
||||
final Vector3f myIntersection = new Vector3f();
|
||||
myIntersection.x = theLineStart.x + u * (theLineEnd.x - theLineStart.x);
|
||||
myIntersection.y = theLineStart.y + u * (theLineEnd.y - theLineStart.y);
|
||||
myIntersection.z = theLineStart.z + u * (theLineEnd.z - theLineStart.z);
|
||||
|
||||
return thePoint.distance(myIntersection);
|
||||
}
|
||||
|
||||
public static float distancePointLine(final Vector3f thePoint,
|
||||
final Vector3f theLineStart,
|
||||
final Vector3f theLineEnd) {
|
||||
final float u = distancePointLineU(thePoint, theLineStart, theLineEnd);
|
||||
final Vector3f myIntersection = new Vector3f();
|
||||
myIntersection.x = theLineStart.x + u * (theLineEnd.x - theLineStart.x);
|
||||
myIntersection.y = theLineStart.y + u * (theLineEnd.y - theLineStart.y);
|
||||
myIntersection.z = theLineStart.z + u * (theLineEnd.z - theLineStart.z);
|
||||
|
||||
return thePoint.distance(myIntersection);
|
||||
}
|
||||
|
||||
public static float distancePointLineU(final Vector3f thePoint,
|
||||
final Vector3f theLineStart,
|
||||
final Vector3f theLineEnd) {
|
||||
final float myLineMagnitude = theLineStart.distance(theLineEnd);
|
||||
final float u = (((thePoint.x - theLineStart.x) * (theLineEnd.x - theLineStart.x))
|
||||
+ ((thePoint.y - theLineStart.y) * (theLineEnd.y - theLineStart.y))
|
||||
+ ((thePoint.z - theLineStart.z) * (theLineEnd.z - theLineStart.z)))
|
||||
/ (myLineMagnitude * myLineMagnitude);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
public static float random(float theStart,
|
||||
float theEnd) {
|
||||
final float myDiff = theEnd - theStart;
|
||||
final float myRandomValue = (float) Math.random() * myDiff;
|
||||
return myRandomValue + theStart;
|
||||
}
|
||||
public static final int CLOCKWISE = 1;
|
||||
|
||||
public static final int COUNTERCLOCKWISE = -1;
|
||||
|
||||
/**
|
||||
* adapted from genius paul bourke
|
||||
* http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/clockwise.htm
|
||||
*
|
||||
* Return the clockwise status of a curve, clockwise or counterclockwise n
|
||||
* vertices making up curve p return 0 for incomputables eg: colinear points
|
||||
* CLOCKWISE == 1 COUNTERCLOCKWISE == -1 It is assumed that - the polygon is
|
||||
* closed - the last point is not repeated. - the polygon is simple (does
|
||||
* not intersect itself or have holes)
|
||||
*/
|
||||
public static int isClockWise(final Vector<Vector2f> mPoints) {
|
||||
|
||||
if (mPoints.size() < 3) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
int mCount = 0;
|
||||
for (int i = 0; i < mPoints.size(); i++) {
|
||||
final Vector2f p1 = mPoints.get(i);
|
||||
final Vector2f p2 = mPoints.get((i + 1) % mPoints.size());
|
||||
final Vector2f p3 = mPoints.get((i + 2) % mPoints.size());
|
||||
float z;
|
||||
z = (p2.x - p1.x) * (p3.y - p2.y);
|
||||
z -= (p2.y - p1.y) * (p3.x - p2.x);
|
||||
if (z < 0) {
|
||||
mCount--;
|
||||
} else if (z > 0) {
|
||||
mCount++;
|
||||
}
|
||||
}
|
||||
if (mCount > 0) {
|
||||
return (COUNTERCLOCKWISE);
|
||||
} else if (mCount < 0) {
|
||||
return (CLOCKWISE);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
public static int isClockWise2D(final Vector<Vector3f> mPoints) {
|
||||
|
||||
if (mPoints.size() < 3) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
int mCount = 0;
|
||||
for (int i = 0; i < mPoints.size(); i++) {
|
||||
final Vector3f p1 = mPoints.get(i);
|
||||
final Vector3f p2 = mPoints.get((i + 1) % mPoints.size());
|
||||
final Vector3f p3 = mPoints.get((i + 2) % mPoints.size());
|
||||
float z;
|
||||
z = (p2.x - p1.x) * (p3.y - p2.y);
|
||||
z -= (p2.y - p1.y) * (p3.x - p2.x);
|
||||
if (z < 0) {
|
||||
mCount--;
|
||||
} else if (z > 0) {
|
||||
mCount++;
|
||||
}
|
||||
}
|
||||
if (mCount > 0) {
|
||||
return (COUNTERCLOCKWISE);
|
||||
} else if (mCount < 0) {
|
||||
return (CLOCKWISE);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
public static final int CONVEX = 1;
|
||||
|
||||
public static final int CONCAVE = -1;
|
||||
|
||||
/**
|
||||
* adapted from genius paul bourke
|
||||
* http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/clockwise.htm
|
||||
*
|
||||
* Return whether a polygon in 2D is concave or convex return 0 for
|
||||
* incomputables eg: colinear points CONVEX == 1 CONCAVE == -1 It is assumed
|
||||
* that the polygon is simple (does not intersect itself or have holes)
|
||||
*/
|
||||
public static int isConvex(final Vector<Vector2f> mPoints) {
|
||||
int flag = 0;
|
||||
double z;
|
||||
|
||||
if (mPoints.size() < 3) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mPoints.size(); i++) {
|
||||
final Vector2f p1 = mPoints.get(i);
|
||||
final Vector2f p2 = mPoints.get((i + 1) % mPoints.size());
|
||||
final Vector2f p3 = mPoints.get((i + 2) % mPoints.size());
|
||||
z = (p2.x - p1.x) * (p3.y - p2.y);
|
||||
z -= (p2.y - p1.y) * (p3.x - p2.x);
|
||||
if (z < 0) {
|
||||
flag |= 1;
|
||||
} else if (z > 0) {
|
||||
flag |= 2;
|
||||
}
|
||||
if (flag == 3) {
|
||||
return (CONCAVE);
|
||||
}
|
||||
}
|
||||
if (flag != 0) {
|
||||
return (CONVEX);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
public static int isConvex2D(final Vector<Vector3f> mPoints) {
|
||||
int flag = 0;
|
||||
double z;
|
||||
|
||||
if (mPoints.size() < 3) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mPoints.size(); i++) {
|
||||
final Vector3f p1 = mPoints.get(i);
|
||||
final Vector3f p2 = mPoints.get((i + 1) % mPoints.size());
|
||||
final Vector3f p3 = mPoints.get((i + 2) % mPoints.size());
|
||||
z = (p2.x - p1.x) * (p3.y - p2.y);
|
||||
z -= (p2.y - p1.y) * (p3.x - p2.x);
|
||||
if (z < 0) {
|
||||
flag |= 1;
|
||||
} else if (z > 0) {
|
||||
flag |= 2;
|
||||
}
|
||||
if (flag == 3) {
|
||||
return (CONCAVE);
|
||||
}
|
||||
}
|
||||
if (flag != 0) {
|
||||
return (CONVEX);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Vector2f
|
||||
implements Serializable, Vectorf {
|
||||
|
||||
private static final long serialVersionUID = -4652533170291767614L;
|
||||
|
||||
public float x;
|
||||
|
||||
public float y;
|
||||
|
||||
// private float[] _myArrayRepresentation = new float[2];
|
||||
private static final float ALMOST_THRESHOLD = 0.001f;
|
||||
|
||||
public Vector2f() {
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
}
|
||||
|
||||
public Vector2f(float theX,
|
||||
float theY) {
|
||||
set(theX,
|
||||
theY);
|
||||
}
|
||||
|
||||
public Vector2f(double theX,
|
||||
double theY) {
|
||||
set(theX,
|
||||
theY);
|
||||
}
|
||||
|
||||
public Vector2f(float[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector2f(double[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector2f(int[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector2f(Vector2f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector2f(Vector3f theVector) {
|
||||
set(theVector.x, theVector.y);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return cloneVector();
|
||||
}
|
||||
|
||||
public Vector2f cloneVector() {
|
||||
return new Vector2f(x, y);
|
||||
}
|
||||
|
||||
public final Vector2f set(float theX,
|
||||
float theY) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector2f set(double theX,
|
||||
double theY) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector2f set(float[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector2f set(double[] theVector) {
|
||||
x = (float) theVector[0];
|
||||
y = (float) theVector[1];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector2f set(int[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector2f set(Vector2f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f add(Vector2f theVectorA,
|
||||
Vector2f theVectorB) {
|
||||
x = theVectorA.x + theVectorB.x;
|
||||
y = theVectorA.y + theVectorB.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f add(final int theX, final int theY) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f add(final float theX, final float theY) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f add(final double theX, final double theY) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f add(Vector2f theVector) {
|
||||
x += theVector.x;
|
||||
y += theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f sub(Vector2f theVectorA,
|
||||
Vector2f theVectorB) {
|
||||
x = theVectorA.x - theVectorB.x;
|
||||
y = theVectorA.y - theVectorB.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f sub(Vector2f theVector) {
|
||||
x -= theVector.x;
|
||||
y -= theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f sub(float theX, float theY) {
|
||||
x -= theX;
|
||||
y -= theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f scale(float theScalar,
|
||||
Vector2f theVector) {
|
||||
x = theScalar * theVector.x;
|
||||
y = theScalar * theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f scale(float theScalar) {
|
||||
x *= theScalar;
|
||||
y *= theScalar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f scale(Vector2f theVector) {
|
||||
x *= theVector.x;
|
||||
y *= theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f scale(float theXScalar, float theYScalar) {
|
||||
x *= theXScalar;
|
||||
y *= theYScalar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float direction() {
|
||||
return (float) Math.atan2(y, x);
|
||||
}
|
||||
|
||||
public float dot(Vector2f theVector) {
|
||||
return x * theVector.x + y * theVector.y;
|
||||
}
|
||||
|
||||
public Vector2f cross(Vector2f theVector) {
|
||||
x = theVector.y;
|
||||
y = -theVector.x;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f cross() {
|
||||
final float myX = y;
|
||||
y = -x;
|
||||
x = myX;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float length() {
|
||||
return (float) Math.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
public float lengthSquared() {
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
public Vector2f normalize(Vector2f theVector) {
|
||||
float inverseMag = 1.0f / (float) Math.sqrt(theVector.x * theVector.x + theVector.y * theVector.y);
|
||||
x = theVector.x * inverseMag;
|
||||
y = theVector.y * inverseMag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector2f normalize() {
|
||||
float inverseMag = 1.0f / (float) Math.sqrt(x * x + y * y);
|
||||
x *= inverseMag;
|
||||
y *= inverseMag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float angle(Vector2f theVector) {
|
||||
float d = dot(theVector) / (length() * theVector.length());
|
||||
if (d < -1.0f) {
|
||||
d = -1.0f;
|
||||
}
|
||||
if (d > 1.0f) {
|
||||
d = 1.0f;
|
||||
}
|
||||
return (float) Math.acos(d);
|
||||
}
|
||||
|
||||
public Vector2f rotate(float theRadians) {
|
||||
final float myX = (float) (x * Math.cos(theRadians) - y * Math.sin(theRadians));
|
||||
final float myY = (float) (y * Math.cos(theRadians) + x * Math.sin(theRadians));
|
||||
x = myX;
|
||||
y = myY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final float distanceSquared(Vector2f thePoint) {
|
||||
float dx = x - thePoint.x;
|
||||
float dy = y - thePoint.y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
public float distance(Vector2f thePoint) {
|
||||
float dx = x - thePoint.x;
|
||||
float dy = y - thePoint.y;
|
||||
return (float) Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
public float[] toArray() {
|
||||
final float[] _myArrayRepresentation = new float[2];
|
||||
_myArrayRepresentation[0] = x;
|
||||
_myArrayRepresentation[1] = y;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public boolean isNaN() {
|
||||
if (Float.isNaN(x) || Float.isNaN(y)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Vector2f theVector) {
|
||||
if (x == theVector.x && y == theVector.y) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 73 * hash + Float.floatToIntBits(this.x);
|
||||
hash = 73 * hash + Float.floatToIntBits(this.y);
|
||||
return hash;
|
||||
}
|
||||
|
||||
public boolean equals(final Object theVector) {
|
||||
if (!(theVector instanceof Vector2f)) {
|
||||
return false;
|
||||
}
|
||||
return equals((Vector2f) theVector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both x and y are zero
|
||||
*
|
||||
* @return boolean, true if the vector is zero
|
||||
*/
|
||||
public boolean equalsZero() {
|
||||
return x == 0 && y == 0;
|
||||
}
|
||||
|
||||
public boolean almost(Vector2f theVector) {
|
||||
if (Math.abs(x - theVector.x) < ALMOST_THRESHOLD
|
||||
&& Math.abs(y - theVector.y) < ALMOST_THRESHOLD) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ")";
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Vector2i
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1578087698419866994L;
|
||||
|
||||
public int x;
|
||||
|
||||
public int y;
|
||||
|
||||
public Vector2i() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
public Vector2i(int theX,
|
||||
int theY) {
|
||||
set(theX,
|
||||
theY);
|
||||
}
|
||||
|
||||
public Vector2i(Vector2i theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector2i(int[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public void set(int theX,
|
||||
int theY) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
}
|
||||
|
||||
public void set(Vector2i theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
}
|
||||
|
||||
public void set(int[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
}
|
||||
|
||||
public final void sub(final Vector2i theVectorA,
|
||||
final Vector2i theVectorB) {
|
||||
x = theVectorA.x - theVectorB.x;
|
||||
y = theVectorA.y - theVectorB.y;
|
||||
}
|
||||
|
||||
public final void sub(final Vector2i theVector) {
|
||||
x -= theVector.x;
|
||||
y -= theVector.y;
|
||||
}
|
||||
|
||||
public final void sub(final int theX, final int theY) {
|
||||
x -= theX;
|
||||
y -= theY;
|
||||
}
|
||||
|
||||
public final void add(final Vector2i theVectorA,
|
||||
final Vector2i theVectorB) {
|
||||
x = theVectorA.x + theVectorB.x;
|
||||
y = theVectorA.y + theVectorB.y;
|
||||
}
|
||||
|
||||
public final void add(final Vector2i theVector) {
|
||||
x += theVector.x;
|
||||
y += theVector.y;
|
||||
}
|
||||
|
||||
public final void add(final int theX, final int theY) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
}
|
||||
|
||||
public final void scale(float theScalar,
|
||||
Vector2i theVector) {
|
||||
x = (int) (theScalar * theVector.x);
|
||||
y = (int) (theScalar * theVector.y);
|
||||
}
|
||||
|
||||
public final void scale(float theScalar) {
|
||||
x *= theScalar;
|
||||
y *= theScalar;
|
||||
}
|
||||
|
||||
public final void scale(Vector2i theVector) {
|
||||
x *= theVector.x;
|
||||
y *= theVector.y;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return "(" + x + ", " + y + ")";
|
||||
}
|
||||
}
|
||||
+629
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class Vector3f
|
||||
implements Cloneable, Serializable, Comparable<Vector3f>, Vectorf {
|
||||
|
||||
private static final long serialVersionUID = -1021495605082676516L;
|
||||
|
||||
/**
|
||||
* Utility for random
|
||||
*/
|
||||
static final Random generator = new Random();
|
||||
|
||||
/**
|
||||
* The x coordinate of the vector
|
||||
*/
|
||||
public float x;
|
||||
|
||||
/**
|
||||
* The y coordinate of the vector
|
||||
*/
|
||||
public float y;
|
||||
|
||||
/**
|
||||
* The z coordinate of the vector
|
||||
*/
|
||||
public float z;
|
||||
|
||||
// /**
|
||||
// * float array for returning an array representation of the vector
|
||||
// */
|
||||
// private float[] _myArrayRepresentation = new float[3];
|
||||
/**
|
||||
* threshold to maintain the minimal difference between two vectors before
|
||||
* they are almost the same
|
||||
*/
|
||||
private static final float ALMOST_THRESHOLD = 0.001f;
|
||||
|
||||
/**
|
||||
* Initializes a new vector. x, y, and z are set to zero.
|
||||
*/
|
||||
public Vector3f() {
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new vector with the given coordinates. Inserted double values
|
||||
* are casted to floats
|
||||
*
|
||||
* @param theX int, float or double: x coord of the new vector
|
||||
* @param theY int, float or double: y coord of the new vector
|
||||
* @param theZ int, float or double: z coord of the new vector
|
||||
*/
|
||||
public Vector3f(float theX, float theY, float theZ) {
|
||||
set(theX, theY, theZ);
|
||||
}
|
||||
|
||||
public Vector3f(double theX, double theY, double theZ) {
|
||||
set(theX, theY, theZ);
|
||||
}
|
||||
|
||||
public Vector3f(float theX, float theY) {
|
||||
set(theX, theY);
|
||||
}
|
||||
|
||||
public Vector3f(double theX, double theY) {
|
||||
set(theX, theY);
|
||||
}
|
||||
|
||||
public Vector3f(float[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(double[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(int[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(Vector3f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(Vector2f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(Vector3i theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(Vector2i theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3f(String theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public final Vector3f set(float theX, float theY, float theZ) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
z = theZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(double theX, double theY, double theZ) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
z = (float) theZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(float theX, float theY) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(double theX, double theY) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(float[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
z = theVector[2];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(double[] theVector) {
|
||||
x = (float) theVector[0];
|
||||
y = (float) theVector[1];
|
||||
z = (float) theVector[2];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(int[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
z = theVector[2];
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(Vector3f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
z = theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(Vector2f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(Vector3i theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
z = theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(Vector2i theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Vector3f set(String theVectorString) {
|
||||
theVectorString = theVectorString.replace("(", "");
|
||||
theVectorString = theVectorString.replace(")", "");
|
||||
theVectorString = theVectorString.replaceAll(" ", "");
|
||||
String[] myComponents = theVectorString.split(",");
|
||||
|
||||
try {
|
||||
x = Float.parseFloat(myComponents[0]);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
try {
|
||||
y = Float.parseFloat(myComponents[1]);
|
||||
} catch (Exception ex1) {
|
||||
}
|
||||
try {
|
||||
z = Float.parseFloat(myComponents[2]);
|
||||
} catch (Exception ex2) {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
x = theVectorA.x + theVectorB.x;
|
||||
y = theVectorA.y + theVectorB.y;
|
||||
z = theVectorA.z + theVectorB.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(Vector3f theVector) {
|
||||
x += theVector.x;
|
||||
y += theVector.y;
|
||||
z += theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(float theX, float theY) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(float theX, float theY, float theZ) {
|
||||
x += theX;
|
||||
y += theY;
|
||||
z += theZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f sub(Vector3f theVectorA, Vector3f theVectorB) {
|
||||
x = theVectorA.x - theVectorB.x;
|
||||
y = theVectorA.y - theVectorB.y;
|
||||
z = theVectorA.z - theVectorB.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f sub(Vector3f theVector) {
|
||||
x -= theVector.x;
|
||||
y -= theVector.y;
|
||||
z -= theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to negate a vector. The result of the negation is vector
|
||||
* with the same magnitude but opposite direction. Mathematically the
|
||||
* negation is the additive inverse of the vector. The sum of a value and
|
||||
* its additive inerse is always zero.
|
||||
*
|
||||
* @shortdesc Use this method to negate a vector.
|
||||
* @related scale ( )
|
||||
*/
|
||||
public Vector3f negate() {
|
||||
scale(-1);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to scale a vector. To scale a vector each of its
|
||||
* coordinates is multiplied with the given scalar. The result is a vector
|
||||
* that is parallel with its origin, with a different length and possibly
|
||||
* opposite direction.<br>
|
||||
* You can also scale a vector with another vector, in this case each coord
|
||||
* of the vector is multiplied with related coord of the given vector.<br>
|
||||
* Another possibillity is to set and scale the vector, this means the
|
||||
* vector is set to the given vector multiplied with the given scalar.
|
||||
*
|
||||
* @param theScalar float or int: the value the vector is scaled with
|
||||
* @related divide ( )
|
||||
* @related negate ( )
|
||||
*/
|
||||
public Vector3f scale(final float theScalar) {
|
||||
x *= theScalar;
|
||||
y *= theScalar;
|
||||
z *= theScalar;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theVector Vector3f: vector with the value each coord is scaled
|
||||
* with
|
||||
*/
|
||||
public Vector3f scale(final Vector3f theVector) {
|
||||
x *= theVector.x;
|
||||
y *= theVector.y;
|
||||
z *= theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theX float
|
||||
* @param theY float
|
||||
* @param theZ float
|
||||
*/
|
||||
public Vector3f scale(float theX, float theY, float theZ) {
|
||||
x *= theX;
|
||||
y *= theY;
|
||||
z *= theZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theScalar float or int: value the given vector is scaled with
|
||||
* @param theVector Vector3f: vector the vector is set to
|
||||
*/
|
||||
public Vector3f scale(final float theScalar, final Vector3f theVector) {
|
||||
x = theScalar * theVector.x;
|
||||
y = theScalar * theVector.y;
|
||||
z = theScalar * theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dividing is nearly the the same as scaling, except
|
||||
*
|
||||
* @param theDivisor
|
||||
*/
|
||||
public Vector3f divide(final float theDivisor) {
|
||||
x /= theDivisor;
|
||||
y /= theDivisor;
|
||||
z /= theDivisor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f divide(final Vector3f theVector) {
|
||||
x /= theVector.x;
|
||||
y /= theVector.y;
|
||||
z /= theVector.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float lengthSquared() {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to calculate the length of a vector, the length of a
|
||||
* vector is also known as its magnitude. Vectors have a magnitude and a
|
||||
* direction. These values are not explicitly expressed in the vector so
|
||||
* they have to be computed.
|
||||
*
|
||||
* @return float: the length of the vector
|
||||
* @shortdesc Calculates the length of the vector.
|
||||
*/
|
||||
public float length() {
|
||||
return (float) Math.sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
public float magnitude() {
|
||||
return length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this vector to the cross product of two given vectors. The cross
|
||||
* product returns a vector standing vertical on the two vectors.
|
||||
*
|
||||
* @param theVectorA
|
||||
* @param theVectorB
|
||||
*/
|
||||
public Vector3f cross(final Vector3f theVectorA, final Vector3f theVectorB) {
|
||||
return set(theVectorA.cross(theVectorB));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cross product of two vectors. The cross product returns a
|
||||
* vector standing vertical on the two vectors.
|
||||
*
|
||||
* @param i_vector the other vector
|
||||
* @return the cross product
|
||||
*/
|
||||
public Vector3f cross(final Vector3f theVector) {
|
||||
return new Vector3f(y * theVector.z - z * theVector.y,
|
||||
z * theVector.x - x * theVector.z,
|
||||
x * theVector.y - y * theVector.x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dot product of two vectors. The dot product is the cosinus of
|
||||
* the angle between two vectors
|
||||
*
|
||||
* @param theVector, the other vector
|
||||
* @return float, dot product of two vectors
|
||||
*/
|
||||
public float dot(Vector3f theVector) {
|
||||
return x * theVector.x + y * theVector.y + z * theVector.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the vector to the given one and norms it to the length of 1
|
||||
*
|
||||
*/
|
||||
public Vector3f normalize(Vector3f theVector) {
|
||||
set(theVector);
|
||||
normalize();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Norms the vector to the length of 1
|
||||
*
|
||||
*/
|
||||
public Vector3f normalize() {
|
||||
float inverseMag = 1.0f / (float) Math.sqrt(x * x + y * y + z * z);
|
||||
x *= inverseMag;
|
||||
y *= inverseMag;
|
||||
z *= inverseMag;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates between this vector and the given vector by a given blend
|
||||
* value. The blend value has to be between 0 and 1. A blend value 0 would
|
||||
* change nothing, a blend value 1 would set this vector to the given one.
|
||||
*
|
||||
* @param blend float, blend value for interpolation
|
||||
* @param i_vector Vector3f, other vector for interpolation
|
||||
*/
|
||||
public void interpolate(final float blend, final Vector3f i_vector) {
|
||||
x = x + blend * (i_vector.x - x);
|
||||
y = y + blend * (i_vector.y - y);
|
||||
z = z + blend * (i_vector.z - z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a position randomly distributed inside a sphere of unit radius
|
||||
* centered at the origin. Orientation will be random and length will range
|
||||
* between 0 and 1
|
||||
*/
|
||||
public void randomize() {
|
||||
x = generator.nextFloat() * 2.0F - 1.0F;
|
||||
y = generator.nextFloat() * 2.0F - 1.0F;
|
||||
z = generator.nextFloat() * 2.0F - 1.0F;
|
||||
normalize();
|
||||
}
|
||||
|
||||
public float angle(Vector3f theVector) {
|
||||
float d = dot(theVector) / (length() * theVector.length());
|
||||
/**
|
||||
* @todo check these lines.
|
||||
*/
|
||||
if (d < -1.0f) {
|
||||
d = -1.0f;
|
||||
}
|
||||
if (d > 1.0f) {
|
||||
d = 1.0f;
|
||||
}
|
||||
return (float) Math.acos(d);
|
||||
}
|
||||
|
||||
public float distanceSquared(Vector3f thePoint) {
|
||||
float dx = x - thePoint.x;
|
||||
float dy = y - thePoint.y;
|
||||
float dz = z - thePoint.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
public float distance(Vector3f thePoint) {
|
||||
float dx = x - thePoint.x;
|
||||
float dy = y - thePoint.y;
|
||||
float dz = z - thePoint.z;
|
||||
return (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
public float distanceL1(Vector3f thePoint) {
|
||||
return Math.abs(x - thePoint.x) + Math.abs(y - thePoint.y)
|
||||
+ Math.abs(z - thePoint.z);
|
||||
}
|
||||
|
||||
public Vector3f min(Vector3f theMin) {
|
||||
if (x < theMin.x) {
|
||||
x = theMin.x;
|
||||
}
|
||||
if (y < theMin.y) {
|
||||
y = theMin.y;
|
||||
}
|
||||
if (z < theMin.z) {
|
||||
z = theMin.z;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f min(float theX, float theY, float theZ) {
|
||||
if (x < theX) {
|
||||
x = theX;
|
||||
}
|
||||
if (y < theY) {
|
||||
y = theY;
|
||||
}
|
||||
if (z < theZ) {
|
||||
z = theZ;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f max(Vector3f theMax) {
|
||||
if (x > theMax.x) {
|
||||
x = theMax.x;
|
||||
}
|
||||
if (y > theMax.y) {
|
||||
y = theMax.y;
|
||||
}
|
||||
if (z > theMax.z) {
|
||||
z = theMax.z;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f max(float theX, float theY, float theZ) {
|
||||
if (x > theX) {
|
||||
x = theX;
|
||||
}
|
||||
if (y > theY) {
|
||||
y = theY;
|
||||
}
|
||||
if (z > theZ) {
|
||||
z = theZ;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public float[] toArray() {
|
||||
final float[] _myArrayRepresentation = new float[3];
|
||||
_myArrayRepresentation[0] = x;
|
||||
_myArrayRepresentation[1] = y;
|
||||
_myArrayRepresentation[2] = z;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public boolean isNaN() {
|
||||
if (Float.isNaN(x) || Float.isNaN(y) || Float.isNaN(z)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(final Vector3f theVector) {
|
||||
if (x == theVector.x && y == theVector.y && z == theVector.z) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + Float.floatToIntBits(this.x);
|
||||
hash = 17 * hash + Float.floatToIntBits(this.y);
|
||||
hash = 17 * hash + Float.floatToIntBits(this.z);
|
||||
return hash;
|
||||
}
|
||||
|
||||
public boolean equals(final Object theVector) {
|
||||
if (!(theVector instanceof Vector3f)) {
|
||||
return false;
|
||||
}
|
||||
return equals((Vector3f) theVector);
|
||||
}
|
||||
|
||||
public boolean almost(final Vector3f theVector) {
|
||||
if (Math.abs(x - theVector.x) < ALMOST_THRESHOLD
|
||||
&& Math.abs(y - theVector.y) < ALMOST_THRESHOLD
|
||||
&& Math.abs(z - theVector.z) < ALMOST_THRESHOLD) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// this shouldn t happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
}
|
||||
public static final int X = 0;
|
||||
|
||||
public static final int Y = 1;
|
||||
|
||||
public static final int Z = 2;
|
||||
|
||||
public static final int LENGTH = 3;
|
||||
|
||||
public static int COMPARE_TYPE = LENGTH;
|
||||
|
||||
public int compareTo(Vector3f theVector3f) {
|
||||
if (COMPARE_TYPE == LENGTH) {
|
||||
final float myLengthSquared = lengthSquared();
|
||||
final float myOtherLengthSquared = theVector3f.lengthSquared();
|
||||
return myLengthSquared > myOtherLengthSquared ? 1 : (myLengthSquared < myOtherLengthSquared ? -1 : 0);
|
||||
} else if (COMPARE_TYPE == X) {
|
||||
return x > theVector3f.x ? 1 : (x < theVector3f.x ? -1 : 0);
|
||||
} else if (COMPARE_TYPE == Y) {
|
||||
return y > theVector3f.y ? 1 : (y < theVector3f.y ? -1 : 0);
|
||||
} else if (COMPARE_TYPE == Z) {
|
||||
return z > theVector3f.z ? 1 : (z < theVector3f.z ? -1 : 0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Vector3i
|
||||
implements Serializable, Comparable<Vector3i> {
|
||||
|
||||
private static final long serialVersionUID = -1207335169644019377L;
|
||||
|
||||
public int x;
|
||||
|
||||
public int y;
|
||||
|
||||
public int z;
|
||||
|
||||
public Vector3i() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
public Vector3i(int theX, int theY, int theZ) {
|
||||
set(theX, theY, theZ);
|
||||
}
|
||||
|
||||
public Vector3i(Vector3i theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector3i(int[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public void set(int theX, int theY, int theZ) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
z = theZ;
|
||||
}
|
||||
|
||||
public void set(Vector3i theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
z = theVector.z;
|
||||
}
|
||||
|
||||
public void set(int[] theVector) {
|
||||
x = theVector[0];
|
||||
y = theVector[1];
|
||||
z = theVector[2];
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
}
|
||||
|
||||
public final float lengthSquared() {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
public int compareTo(Vector3i theVector3i) {
|
||||
return (int) (lengthSquared() - theVector3i.lengthSquared());
|
||||
}
|
||||
}
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Vector4f
|
||||
implements Serializable, Vectorf {
|
||||
|
||||
private static final long serialVersionUID = 5083919691492230155L;
|
||||
|
||||
public float w;
|
||||
|
||||
public float x;
|
||||
|
||||
public float y;
|
||||
|
||||
public float z;
|
||||
|
||||
private static final float ALMOST_THRESHOLD = 0.001f;
|
||||
|
||||
public Vector4f() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
w = 0;
|
||||
}
|
||||
|
||||
public Vector4f(float theX,
|
||||
float theY,
|
||||
float theZ,
|
||||
float theW) {
|
||||
set(theX,
|
||||
theY,
|
||||
theZ,
|
||||
theW);
|
||||
}
|
||||
|
||||
public Vector4f(double theX,
|
||||
double theY,
|
||||
double theZ,
|
||||
double theW) {
|
||||
set(theX,
|
||||
theY,
|
||||
theZ,
|
||||
theW);
|
||||
}
|
||||
|
||||
public Vector4f(float theX,
|
||||
float theY,
|
||||
float theZ) {
|
||||
set(theX,
|
||||
theY,
|
||||
theZ);
|
||||
}
|
||||
|
||||
public Vector4f(double theX,
|
||||
double theY,
|
||||
double theZ) {
|
||||
set(theX,
|
||||
theY,
|
||||
theZ);
|
||||
}
|
||||
|
||||
public Vector4f(float theX,
|
||||
float theY) {
|
||||
set(theX,
|
||||
theY);
|
||||
}
|
||||
|
||||
public Vector4f(double theX,
|
||||
double theY) {
|
||||
set(theX,
|
||||
theY);
|
||||
}
|
||||
|
||||
public Vector4f(float[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector4f(double[] theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector4f(Vector4f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector4f(Vector3f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public Vector4f(Vector2f theVector) {
|
||||
set(theVector);
|
||||
}
|
||||
|
||||
public final void set(float theX,
|
||||
float theY,
|
||||
float theZ,
|
||||
float theW) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
z = theZ;
|
||||
w = theW;
|
||||
}
|
||||
|
||||
public final void set(double theX,
|
||||
double theY,
|
||||
double theZ,
|
||||
double theW) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
z = (float) theZ;
|
||||
w = (float) theW;
|
||||
}
|
||||
|
||||
public final void set(float theX,
|
||||
float theY,
|
||||
float theZ) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
z = theZ;
|
||||
}
|
||||
|
||||
public final void set(double theX,
|
||||
double theY,
|
||||
double theZ) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
z = (float) theZ;
|
||||
}
|
||||
|
||||
public final void set(float theX,
|
||||
float theY) {
|
||||
x = theX;
|
||||
y = theY;
|
||||
}
|
||||
|
||||
public final void set(double theX,
|
||||
double theY) {
|
||||
x = (float) theX;
|
||||
y = (float) theY;
|
||||
}
|
||||
|
||||
public final void set(float[] theVector) {
|
||||
w = theVector[0];
|
||||
x = theVector[1];
|
||||
y = theVector[2];
|
||||
z = theVector[3];
|
||||
}
|
||||
|
||||
public final void set(double[] theVector) {
|
||||
w = (float) theVector[0];
|
||||
x = (float) theVector[1];
|
||||
y = (float) theVector[2];
|
||||
z = (float) theVector[3];
|
||||
}
|
||||
|
||||
public final void set(Vector4f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
z = theVector.z;
|
||||
w = theVector.w;
|
||||
}
|
||||
|
||||
public final void set(Vector3f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
z = theVector.z;
|
||||
}
|
||||
|
||||
public final void set(Vector2f theVector) {
|
||||
x = theVector.x;
|
||||
y = theVector.y;
|
||||
}
|
||||
|
||||
public final void add(Vector4f theVectorA,
|
||||
Vector4f theVectorB) {
|
||||
w = theVectorA.w + theVectorB.w;
|
||||
x = theVectorA.x + theVectorB.x;
|
||||
y = theVectorA.y + theVectorB.y;
|
||||
z = theVectorA.z + theVectorB.z;
|
||||
}
|
||||
|
||||
public final void add(Vector4f theVector) {
|
||||
w += theVector.w;
|
||||
x += theVector.x;
|
||||
y += theVector.y;
|
||||
z += theVector.z;
|
||||
}
|
||||
|
||||
public final void sub(Vector4f theVectorA,
|
||||
Vector4f theVectorB) {
|
||||
w = theVectorA.w - theVectorB.w;
|
||||
x = theVectorA.x - theVectorB.x;
|
||||
y = theVectorA.y - theVectorB.y;
|
||||
z = theVectorA.z - theVectorB.z;
|
||||
}
|
||||
|
||||
public final void sub(Vector4f theVector) {
|
||||
w -= theVector.w;
|
||||
x -= theVector.x;
|
||||
y -= theVector.y;
|
||||
z -= theVector.z;
|
||||
}
|
||||
|
||||
public final void scale(float theScalar,
|
||||
Vector4f theVector) {
|
||||
w = theScalar * theVector.w;
|
||||
x = theScalar * theVector.x;
|
||||
y = theScalar * theVector.y;
|
||||
z = theScalar * theVector.z;
|
||||
}
|
||||
|
||||
public final void scale(float theScalar) {
|
||||
w *= theScalar;
|
||||
x *= theScalar;
|
||||
y *= theScalar;
|
||||
z *= theScalar;
|
||||
}
|
||||
|
||||
public final float lengthSquared() {
|
||||
return w * w + x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
public final float length() {
|
||||
return (float) Math.sqrt(w * w + x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
public final float dot(Vector4f theVector) {
|
||||
return x * theVector.x + y * theVector.y + z * theVector.z + w * theVector.w;
|
||||
}
|
||||
|
||||
public void normalize(Vector4f theVector) {
|
||||
set(theVector);
|
||||
normalize();
|
||||
}
|
||||
|
||||
public final void normalize() {
|
||||
final float d = 1 / length();
|
||||
x *= d;
|
||||
y *= d;
|
||||
z *= d;
|
||||
w *= d;
|
||||
}
|
||||
|
||||
public final float[] toArray() {
|
||||
final float[] _myArrayRepresentation = new float[4];
|
||||
_myArrayRepresentation[0] = x;
|
||||
_myArrayRepresentation[1] = y;
|
||||
_myArrayRepresentation[2] = z;
|
||||
_myArrayRepresentation[3] = w;
|
||||
return _myArrayRepresentation;
|
||||
}
|
||||
|
||||
public final boolean isNaN() {
|
||||
if (Float.isNaN(x) || Float.isNaN(y) || Float.isNaN(z) || Float.isNaN(w)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean equals(Vector4f theVector) {
|
||||
if (w == theVector.w && x == theVector.x && y == theVector.y && z == theVector.z) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean almost(Vector4f theVector) {
|
||||
if (Math.abs(w) - Math.abs(theVector.w) < ALMOST_THRESHOLD
|
||||
&& Math.abs(x) - Math.abs(theVector.x) < ALMOST_THRESHOLD
|
||||
&& Math.abs(y) - Math.abs(theVector.y) < ALMOST_THRESHOLD
|
||||
&& Math.abs(z) - Math.abs(theVector.z) < ALMOST_THRESHOLD) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return "(" + x + ", " + y + ", " + z + ", " + w + ")";
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
public interface Vectorf {
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Mathematik
|
||||
*
|
||||
* Copyright (C) 2012 Patrick Kochlik + Dennis Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* {@link http://www.gnu.org/licenses/lgpl.html}
|
||||
*
|
||||
*/
|
||||
package mathematik;
|
||||
|
||||
|
||||
public class WorldAxisAlignedBoundingBox {
|
||||
|
||||
/**
|
||||
* center of bounding box
|
||||
*/
|
||||
public Vector3f position = new Vector3f();
|
||||
|
||||
/**
|
||||
* scale around the center
|
||||
*/
|
||||
public Vector3f scale = new Vector3f();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user