diff options
author | Jesse Morgan <jesse@jesterpm.net> | 2011-02-18 03:41:00 +0000 |
---|---|---|
committer | Jesse Morgan <jesse@jesterpm.net> | 2011-02-18 03:41:00 +0000 |
commit | 893a4bf81d9db58ffd68782389625b2a893fcf90 (patch) | |
tree | ffffe3bb3b0f94781b3474f3a952d1efdcc3e7ce | |
parent | 1c0e514296bd1ae062961ae129d65e5d96d9c323 (diff) |
Air Drag merged.
-rw-r--r-- | src/alden/CollidableObject.java | 2 | ||||
-rw-r--r-- | src/tesseract/TesseractUI.java | 13 | ||||
-rw-r--r-- | src/tesseract/forces/AirDrag.java | 193 | ||||
-rw-r--r-- | src/tesseract/menuitems/IcosahedronMenuItem.java | 2 | ||||
-rw-r--r-- | src/tesseract/objects/PhysicalObject.java | 20 |
5 files changed, 223 insertions, 7 deletions
diff --git a/src/alden/CollidableObject.java b/src/alden/CollidableObject.java index eb3ff6a..236b731 100644 --- a/src/alden/CollidableObject.java +++ b/src/alden/CollidableObject.java @@ -103,7 +103,7 @@ public abstract class CollidableObject { clearCaches();
}
- protected ArrayList<Vector3f> getVertices() {
+ public ArrayList<Vector3f> getVertices() {
if (vertexCache == null)
vertexCache = CollisionDetector.extractVertices(node);
return vertexCache;
diff --git a/src/tesseract/TesseractUI.java b/src/tesseract/TesseractUI.java index 882f6a8..9fd91b9 100644 --- a/src/tesseract/TesseractUI.java +++ b/src/tesseract/TesseractUI.java @@ -27,6 +27,7 @@ import javax.vecmath.Point3d; import javax.vecmath.Point3f; import javax.vecmath.Vector3f; +import tesseract.forces.AirDrag; import tesseract.forces.CircularXY; import tesseract.forces.CircularXZ; import tesseract.forces.Force; @@ -40,8 +41,8 @@ import tesseract.menuitems.IcosahedronMenuItem; import tesseract.menuitems.ParticleEmitterMenuItem; import tesseract.menuitems.ParticleMenuItem; import tesseract.menuitems.PlanarPolygonMenuItem; +import tesseract.objects.Box; import tesseract.objects.ChainLink2; -import tesseract.objects.Circle; import tesseract.objects.PhysicalObject; import com.sun.j3d.utils.picking.PickCanvas; @@ -147,10 +148,16 @@ public class TesseractUI extends JFrame { // TODO: REMOVE TEST CODE // Lookie! Linked chainlinks! - myWorld.addObject(new ChainLink2(new Vector3f(0.15f, 0, 0), 1)); + //myWorld.addObject(new ChainLink2(new Vector3f(0.15f, 0, 0), 1)); ChainLink2 o = new ChainLink2(new Vector3f(), 1); o.setRotation(); - myWorld.addObject(o); + + myWorld.addForce(new AirDrag()); + + myWorld.addObject(new Box(0.18f, 0.1f, 0.25f, new Vector3f(0.1f, -0.10f, 0))); + myWorld.addObject(new Box(0.18f, 0.25f, 0.1f, new Vector3f(-0.1f, 0, 0))); + + //myWorld.addObject(o); } /** diff --git a/src/tesseract/forces/AirDrag.java b/src/tesseract/forces/AirDrag.java new file mode 100644 index 0000000..c27ec7e --- /dev/null +++ b/src/tesseract/forces/AirDrag.java @@ -0,0 +1,193 @@ +package tesseract.forces; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import javax.media.j3d.Transform3D; +import javax.vecmath.Quat4f; +import javax.vecmath.Vector2f; +import javax.vecmath.Vector3f; + +import tesseract.objects.PhysicalObject; + +public class AirDrag extends Force { + + private static final float COEFFICIENT = 20f; + + + @Override + protected Vector3f calculateForce(PhysicalObject obj) { + if (obj.isNodeNull() || obj.getVelocity().length() == 0) { + return new Vector3f(); + } + + Vector3f v = new Vector3f(obj.getVelocity()); + + Vector3f p = new Vector3f(obj.getPosition()); + p.negate(); + + Vector3f c = new Vector3f(); + c.sub(new Vector3f(0, 1, 0), v); + + Quat4f r = new Quat4f(c.x, c.y, c.z, 0); + r.normalize(); + + + Vector3f com = new Vector3f(-obj.getCenterOfMass().x, -obj.getCenterOfMass().y, -obj.getCenterOfMass().z); + com.negate(); + + Transform3D tmp = new Transform3D(); + tmp.setTranslation(com); + Transform3D tmp2 = new Transform3D(); + tmp2.setRotation(r); + com.negate(); + com.add(p); + tmp2.setTranslation(com); + tmp2.mul(tmp); + + ArrayList<Vector3f> vertices = obj.getVertices(); + ArrayList<Vector2f> points = new ArrayList<Vector2f>(); + + for (Vector3f point : vertices) { + tmp2.transform(point); + Vector2f newPoint = new Vector2f(point.x, point.z); + + // Place min y at front of arraylist if it's the minimum + if (points.size() == 0) { + points.add(newPoint); + + } else if (newPoint.y < points.get(0).y + || (newPoint.y == points.get(0).y + && newPoint.x < points.get(0).x)) { + Vector2f oldPoint = points.get(0); + points.set(0, newPoint); + points.add(oldPoint); + + } else { + points.add(newPoint); + } + } + + List<Vector2f> hull = convexHull(points); + + float surfaceArea = areaOfHull(hull); + + float force = 0.5f * v.length() * COEFFICIENT * surfaceArea; + + System.out.println(v.length()); + System.out.println(force); + + v.normalize(); + v.scale(-force); + + System.out.println(v); + + return v; + + } + + public static void main(String[] args) { + AirDrag ad = new AirDrag(); + + ArrayList<Vector2f> points = new ArrayList<Vector2f>(); + + /*points.add(new Vector2f(2, 1)); + points.add(new Vector2f(2, 3)); + points.add(new Vector2f(3, 4.5f)); + points.add(new Vector2f(4, 2)); + points.add(new Vector2f(4, 7)); + points.add(new Vector2f(1, 2)); + points.add(new Vector2f(1, 5)); + points.add(new Vector2f(1.5f, 7));*/ + + points.add(new Vector2f(0, 0)); + points.add(new Vector2f(0, 3)); + points.add(new Vector2f(3, 3)); + points.add(new Vector2f(3, 0)); + points.add(new Vector2f(1, 2)); + points.add(new Vector2f(0, 1)); + + List<Vector2f> newPoints = ad.convexHull(points); + System.out.println(newPoints); + + System.out.println(ad.areaOfHull(newPoints)); + } + + private float areaOfHull(final List<Vector2f> hull) { + float area = 0; + Vector2f p = hull.get(0); + + for (int i = 2; i < hull.size(); i++) { + // Area of triangle p0 - p(i-1) - p(i) + Vector2f ab = new Vector2f(); + Vector2f ac = new Vector2f(); + + ab.sub(hull.get(i-1), p); + ac.sub(hull.get(i), p); + + area += 0.5f * (ab.x * ac.y - ac.x * ab.y); + } + + return area; + } + + private List<Vector2f> convexHull(final ArrayList<Vector2f> points) { + Collections.sort(points, new Vector2fAngleCompare(points.get(0))); + + points.set(0, points.get(points.size() - 1)); + + int m = 2; + for (int i = 3; i < points.size(); i++) { + try { + while (i < points.size() - 1 && ccw(points.get(m - 1), points.get(m), points.get(i)) <= 0) { + if (m == 2) { + final Vector2f vec = points.get(m); + points.set(m, points.get(i)); + points.set(i, vec); + i++; + + } else { + m--; + } + } + } catch (Exception e) { + System.out.println(e); + } + + m++; + + final Vector2f vec = points.get(m); + points.set(m, points.get(i)); + points.set(i, vec); + } + + return points.subList(0, m+1); + } + + private float ccw(final Vector2f v1, final Vector2f v2, final Vector2f v3) { + return (v2.x - v1.x) * (v3.y - v1.y)- (v2.y - v1.y) * (v3.x - v1.x); + } + + + private class Vector2fAngleCompare implements Comparator<Vector2f> { + Vector2f base; + + public Vector2fAngleCompare(final Vector2f theBase) { + base = theBase; + } + + + public int compare(Vector2f o1, Vector2f o2) { + return (int) Math.signum(vecAngle(o1) - vecAngle(o2)); + } + + private float vecAngle(final Vector2f vector) { + final Vector2f v = new Vector2f(); + v.sub(vector, base); + + return v.y / (v.x * v.x + v.y * v.y); + } + } +} diff --git a/src/tesseract/menuitems/IcosahedronMenuItem.java b/src/tesseract/menuitems/IcosahedronMenuItem.java index c6b5bf1..9d4f9cb 100644 --- a/src/tesseract/menuitems/IcosahedronMenuItem.java +++ b/src/tesseract/menuitems/IcosahedronMenuItem.java @@ -54,7 +54,7 @@ public class IcosahedronMenuItem extends TesseractMenuItem { defaultButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
if (defaultButton.isSelected()) {
- myWorld.addObject(new Icosahedron(getDefaultPosition(), 10, getDefaultRadius()));
+ myWorld.addObject(new Icosahedron(getDefaultPosition(), 1, getDefaultRadius()));
params.dispose();
}
}
diff --git a/src/tesseract/objects/PhysicalObject.java b/src/tesseract/objects/PhysicalObject.java index fa69e8a..cdfca54 100644 --- a/src/tesseract/objects/PhysicalObject.java +++ b/src/tesseract/objects/PhysicalObject.java @@ -66,12 +66,12 @@ public class PhysicalObject extends CollidableObject { shape.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ); shape.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ); - for (int i = 0; i < shape.numGeometries(); i++) { + /*for (int i = 0; i < shape.numGeometries(); i++) { shape.getGeometry(i).setCapability( GeometryArray.ALLOW_COUNT_READ); shape.getGeometry(i).setCapability( GeometryArray.ALLOW_COORDINATE_READ); - } + }*/ } } @@ -122,5 +122,21 @@ public class PhysicalObject extends CollidableObject { */ public void updateTranformGroup() { super.updateTransformGroup(); + } + + public Vector3f getVelocity() { + return this.velocity; + } + + public Vector3f getCenterOfMass() { + return this.centerOfMass; + } + + public boolean isCollidable() { + return collidable; + } + + public boolean isNodeNull() { + return this.node == null; }
}
\ No newline at end of file |