// Copyright (c) 2008 James A. Wilson All rights reserved. Use is // subject to license terms. // This file is part of CruiseSaver. // // CruiseSaver is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // CruiseSaver 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with CruiseSaver; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA package status.collisions; import vector.V; import vector.Vector2D; /** * * @author Nate H. Young, James Wilson * */ public class Orb { public double x; public double y; public Vector2D v; public double mass; public int pulsePosition = 0; public boolean collided; public Orb(double x, double y, Vector2D velocity, double mass) { this.x = x; this.y = y; this.v = velocity; this.mass = mass; } public Vector2D normal(Orb orb) { return normal(this, orb); } public Vector2D tangent(Orb orb) { return tangent(this, orb); } public void collide(Orb orb) { Vector2D[] result = collide(this, orb); this.v = result[0]; orb.v = result[1]; this.collided = true; orb.collided = true; } public boolean isIntersecting(Orb orb, double radius) { return intersecting(this, orb, radius); } public static Vector2D normal(Orb orb1, Orb orb2) { Vector2D norm = new Vector2D(); norm.x = orb1.x - orb2.x; norm.y = orb1.y - orb2.y; return norm; } public static Vector2D tangent(Orb orb1, Orb orb2) { Vector2D tangent = normal(orb1, orb2); double x = tangent.x; tangent.x = -1 * tangent.y; tangent.y = x; return tangent; } public static boolean intersecting(Orb orb1, Orb orb2, double radius) { double distance = V.magnitude(Orb.normal(orb1, orb2)); return (distance <= radius); } // //in this version of collide, we just worry about getting the // //directions of the resultant vectors right, not the proper direction of velocity // public static Vector2D[] collide(Orb orb1, Orb orb2) { // Vector2D normal = V.unitOf(Orb.normal(orb1, orb2)); // Vector2D tangent = V.unitOf(Orb.tangent(orb1, orb2)); // // Vector2D combined = V.unitOf(V.add(normal, tangent)); // // double v1prime = elasticCollision(orb1.mass, V.magnitude(orb1.v), orb2.mass, V.magnitude(orb2.v)); // double v2prime = elasticCollision(orb2.mass, V.magnitude(orb2.v), orb1.mass, V.magnitude(orb1.v)); // // Vector2D v1final = V.mult(v1prime, combined); // Vector2D v2final = V.mult(v2prime, V.mult(-1, normal)); // // return new Vector2D[] { v1final, v2final }; // } public static Vector2D[] collide(Orb orb1, Orb orb2) { double v1x = elasticCollision(orb1.mass, orb1.v.x, orb2.mass, orb2.v.x); double v2x = elasticCollision(orb2.mass, orb2.v.x, orb1.mass, orb1.v.x); //get the signs right if(v1x > 0 && orb2.v.x < 0 || v1x < 0 && orb2.v.x > 0) v1x *= -1.0; if(v2x > 0 && orb1.v.x < 0 || v2x < 0 && orb1.v.x > 0) v2x *= -1.0; double v1y = elasticCollision(orb1.mass, orb1.v.y, orb2.mass, orb2.v.y); double v2y = elasticCollision(orb2.mass, orb2.v.y, orb1.mass, orb1.v.y); //get the signs right if(v1y > 0 && orb2.v.y < 0 || v1y < 0 && orb2.v.y > 0) v1y *= -1.0; if(v2y > 0 && orb1.v.y < 0 || v2y < 0 && orb1.v.y > 0) v2y *= -1.0; return new Vector2D[] { new Vector2D(v1x, v1y), new Vector2D(v2x, v2y) }; } // //returns the resultant vectors of the orbs after collision // public static Vector2D[] fullElasticCollision(Orb orb1, Orb orb2) { // //calculate unit normal and tangent vectors // Vector2D normal = V.unitOf(Orb.normal(orb1, orb2)); // Vector2D tangent = V.unitOf(Orb.tangent(orb1, orb2)); // // //break the orb's velocity vectors into scalar normal and tangential components // double v1n = V.dot(orb1.v, normal); // double v1t = V.dot(orb1.v, tangent); // double v2n = V.dot(orb2.v, normal); // double v2t = V.dot(orb2.v, tangent); // // //calculate scalar velocity in normal direction after collision // v1n = elasticCollision(orb1.mass, v1n, orb2.mass, v2n); // v2n = elasticCollision(orb2.mass, v2n, orb1.mass, v1n); // // //calculate normal component of final velocity vector // Vector2D v1norm = V.mult(v1n, normal); // Vector2D v2norm = V.mult(v2n, normal); // // //calculate tangential component of final velocity vector // Vector2D v1tang = V.mult(v1t, tangent); // Vector2D v2tang = V.mult(v2t, tangent); // // //combine normal and tangential components to get final velocity vector // Vector2D v1final = V.add(v1norm, v1tang); // Vector2D v2final = V.add(v2norm, v2tang); // // return new Vector2D[] { v1final, v2final }; // } public static double elasticCollision(double mass1, double velo1, double mass2, double velo2) { return ((velo1 * (mass1 - mass2)) + 2 * mass2 * velo2) / (mass1 + mass2); } }