day3 (german!) libs

This commit is contained in:
gauthiier
2015-03-04 09:41:41 +01:00
parent 6b37eb529e
commit e772172cbc
133 changed files with 18241 additions and 0 deletions
Binary file not shown.
+89
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}