Skip to content

Commit

Permalink
Switch from Geometry2014 to Java3D
Browse files Browse the repository at this point in the history
The only things that were implemented in the previous version and are
not in this commit are probably drawing the walls and the ability to
shoot. The latter will likely come in the next commit. Happy New Year!
  • Loading branch information
bmccutchon committed Jan 1, 2015
1 parent a8e6362 commit 52c39a7
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 533 deletions.
1 change: 0 additions & 1 deletion Pool3D/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry combineaccessrules="false" kind="src" path="/Geometry2014"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/Java SE 8 [1.8.0_40]"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Java3D-1.5.2"/>
Expand Down
14 changes: 6 additions & 8 deletions Pool3D/src/com/brianmccutchon/pool3d/Controller.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.brianmccutchon.pool3d;

import static java.awt.event.KeyEvent.*;
import geometry.Point3D;

import java.awt.Component;
import java.awt.event.KeyAdapter;
Expand All @@ -15,7 +14,7 @@
public class Controller {
private static final double MOVE_SPEED = 0.5;

private static final double ROT_SPEED = 0.05;
private static final double ROT_SPEED = 0.02;

/** Holds the keys that are currently being pressed. **/
private HashSet<Integer> keysDown = new HashSet<>();
Expand Down Expand Up @@ -97,17 +96,17 @@ void switchMode() {
pool.shooting = !pool.shooting;

if (pool.shooting) {
//Point3D p = Physics.balls[0].center;
//Point3d p = Physics.balls[0].center;
//camTransform.lookAt(new Point3d(p.x, p.y, p.z+4),
// new Point3d(p.x, p.y, p.z), new Vector3d(0, 1, 0));
// p, new Vector3d(0, 1, 0));
camTransform.lookAt(new Point3d(0, 0, -4),
new Point3d(0, 0, 0), new Vector3d(0, 1, 0));
cam.setTransform(camTransform);
}
}

void shoot() {

// TODO Write method Controller.shoot()
}

void moveForward() {
Expand Down Expand Up @@ -202,9 +201,7 @@ void rotateAroundCue(Matrix3d rot) {
camTransform.get(translateVec);

// Subtract from it the position of the cue ball
//Point3d cue = new Point3d(Physics.balls[0].center.x,
// Physics.balls[0].center.y, Physics.balls[0].center.z);
//translateVec.sub(cue);
//translateVec.sub(Physics.balls[0].center);

// Rotate the vector
vecMatMult(rot, translateVec);
Expand Down Expand Up @@ -232,6 +229,7 @@ void rotateUpShooting() {
rotateUpShooting(ROT_SPEED);
}

// FIXME Doesn't work
void rotateUpShooting(double angle) {
Vector3d translateVec = new Vector3d();
camTransform.get(translateVec);
Expand Down
89 changes: 26 additions & 63 deletions Pool3D/src/com/brianmccutchon/pool3d/Physics.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.brianmccutchon.pool3d;

import geometry.Point3D;
import javax.vecmath.*;

/**
* This is a purely static class containing information related to the physics
Expand All @@ -18,16 +18,16 @@ public class Physics {
public static final double EPSILON = Math.pow(10.0, -15);

/** A unit vector along the x axis. **/
static final Point3D X_UNIT_VEC = new Point3D(1, 0, 0);
static final Vector3d X_UNIT_VEC = new Vector3d(1, 0, 0);

/** A unit vector along the y axis. **/
static final Point3D Y_UNIT_VEC = new Point3D(0, 1, 0);
static final Vector3d Y_UNIT_VEC = new Vector3d(0, 1, 0);

/** A unit vector along the y axis. **/
static final Point3D Z_UNIT_VEC = new Point3D(0, 0, 1);
static final Vector3d Z_UNIT_VEC = new Vector3d(0, 0, 1);

/** The origin of the coordinate system: (0, 0, 0) **/
static final Point3D ORIGIN = new Point3D(0, 0, 0);
static final Point3d ORIGIN = new Point3d(0, 0, 0);

// TODO Get rid of global variables like this one.
// Maybe make Physics instantiable? or create a new class.
Expand Down Expand Up @@ -100,49 +100,39 @@ static void transposeSquareMat(double[][] m) {
}
}

/**
* Normalizes a vector in place. This means that the vector will be
* converted into a unit vector with the same direction as the original.
* @param p The vector to nomalize.
*/
private static void normalize(Point3D p) {
double norm = p.dist(new Point3D(0, 0, 0));
p.x /= norm;
p.y /= norm;
p.z /= norm;
}

/**
* Computes the rotation matrix that, if the balls are translated so that
* ball1 is at (0, 0, 0) and the matrix is applied to the locations of the
* two balls, ball2's x and y coordinates will equal 0. Also, ball2's x
* coordinate should then be greater than ball1's x coordinate.
*
* @param ball1 A pool ball.
* @param ball2 Another pool ball.
* @param center A pool ball.
* @param center2 Another pool ball.
* @return The collision rotation matrix.
*/
static double[][] findCollisionRotationMat(
Point3D ball1, Point3D ball2) {
Point3D ball2loc = ball2.subtract(ball1);
normalize(ball2loc);
Point3d center, Point3d center2) {
Vector3d ball2loc = new Vector3d();
ball2loc.sub(center2, center);
ball2loc.normalize();

// Vector representing the axis of rotation
Point3D a = ball2loc.cross(X_UNIT_VEC);
Vector3d a = new Vector3d();
a.cross(ball2loc, X_UNIT_VEC);

// Since ball2Loc and X_UNIT_VEC are unit vectors, the following hold:

// Their dot product is the cos of the angle between them
double cos = ball2loc.dot(X_UNIT_VEC);

// The magnitude of their cross product is the sin of the rotation angle
double sin = a.dist(ORIGIN);
double sin = a.length();

// The matrix below only works if the axis is a unit vector
if (almostEq(a.dist(ORIGIN), 0)) {
if (almostEq(sin, 0)) {
a = Y_UNIT_VEC;
} else {
normalize(a);
a.normalize();
}

// Rotation matrix given an axis and an angle. Source:
Expand All @@ -156,14 +146,14 @@ static double[][] findCollisionRotationMat(

/**
* Rotates a vector using a provided rotation matrix.
* @param v The vector to rotate.
* @param velocity The vector to rotate.
* @param m The 3x3 rotation matrix.
*/
static void rotateVec(Point3D v, double[][] m) {
v.setLocation(
v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2],
v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2]);
static void rotateVec(Vector3d velocity, double[][] m) {
velocity.set(
velocity.x * m[0][0] + velocity.y * m[0][1] + velocity.z * m[0][2],
velocity.x * m[1][0] + velocity.y * m[1][1] + velocity.z * m[1][2],
velocity.x * m[2][0] + velocity.y * m[2][1] + velocity.z * m[2][2]);
}

/**
Expand All @@ -173,12 +163,12 @@ public static void nextFrame() {
ballsAreMoving = false;

for (PoolBall b : balls) {
if (almostEq(b.velocity, ORIGIN, Physics.MOVEMENT_EPSILON)) {
if (b.velocity.epsilonEquals(ORIGIN, MOVEMENT_EPSILON)) {
// "Close enough" to (0, 0, 0).
b.velocity.setLocation(0, 0, 0);
b.velocity.set(0, 0, 0);
} else {
ballsAreMoving = true; // We found a ball that is moving
b.center = b.center.add(b.velocity);
b.center.add(b.velocity);
doAirResistance(b.velocity);
}
}
Expand Down Expand Up @@ -221,33 +211,6 @@ static boolean almostEq(double d1, double d2) {
return Math.abs(d1 - d2) < EPSILON;
}

/**
* Checks whether two points are almost equal in each of their three
* components. That is, within {@link Physics#EPSILON}.
* @param p1 A point to compare.
* @param p2 A point to compare.
* @return {@code true} iff they are almost equal.
*/
private static boolean almostEq(Point3D p1, Point3D p2) {
return almostEq(p1.x, p2.x) &&
almostEq(p1.y, p2.y) &&
almostEq(p1.z, p2.z);
}

/**
* Checks whether two points are almost equal in each of their three
* components.
* @param p1 A point to compare.
* @param p2 A point to compare.
* @param epsilon The maximum allowed difference.
* @return {@code true} iff they are almost equal.
*/
private static boolean almostEq(Point3D p1, Point3D p2, double epsilon) {
return almostEq(p1.x, p2.x, epsilon) &&
almostEq(p1.y, p2.y, epsilon) &&
almostEq(p1.z, p2.z, epsilon);
}

/**
* Checks whether two numbers are almost equal to each other. That is,
* within {@link Physics#EPSILON}.
Expand All @@ -263,7 +226,7 @@ private static boolean almostEq(double x, double n, double epsilon) {
* Computes linear "air resistance" on a ball's velocity.
* @param p The ball's velocity.
*/
private static void doAirResistance(Point3D p) {
private static void doAirResistance(Vector3d p) {
p.x = Math.signum(p.x) * Math.max(0, Math.abs(p.x) - AIR_RESISTANCE);
p.y = Math.signum(p.y) * Math.max(0, Math.abs(p.y) - AIR_RESISTANCE);
p.z = Math.signum(p.z) * Math.max(0, Math.abs(p.z) - AIR_RESISTANCE);
Expand Down
Loading

0 comments on commit 52c39a7

Please sign in to comment.