Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.geom.Point2D;
- import java.util.Random;
- public class Robutton {
- final static int radius = 10;
- private double directionDegree;
- private double directionX;
- private double directionY;
- Point2D.Double pos;
- private Coin coin = null;
- private boolean collisionDetected = false;
- private double collisionTime = 2.0;
- private double nextDegree;
- private Point2D.Double nextPos;
- private Coin nextCoin = null;
- public Robutton(Point2D.Double pos) {
- this.pos = pos;
- }
- public double distance(Robutton rob) {
- return pos.distance(rob.getPos())-radius*2;
- }
- public void setDirectionDegree(double degree) {
- directionDegree = degree % 360;
- directionX = Math.cos(Math.toRadians(directionDegree));
- directionY = -Math.sin(Math.toRadians(directionDegree));
- }
- public void move(double time) {
- pos.x += directionX*time;
- pos.y += directionY*time;
- if (coin != null) {
- coin.pos.x = this.pos.x;
- coin.pos.y = this.pos.y;
- }
- if (collisionTime == time) {
- this.setDirectionDegree(nextDegree);
- // System.out.println("nextDegree set to " + nextDegree);
- this.coin = nextCoin;
- }
- collisionTime = 2.0;
- if (pos.x > 190 || pos.y > 190)
- System.out.println("fail6");
- }
- public void moveSimple() {
- pos.x += directionX;
- pos.y += directionY;
- if (coin != null) {
- coin.pos.x = this.pos.x;
- coin.pos.y = this.pos.y;
- }
- }
- public void moveSimple(double xdelta, double ydelta) {
- pos.x += xdelta;
- pos.y += ydelta;
- if (coin != null) {
- coin.pos.x = this.pos.x;
- coin.pos.y = this.pos.y;
- }
- }
- // public void collideBound(int x, int y) {
- // if (pos.x - radius < 0) {
- // setDirectionDegree((360 - directionDegree + 180));
- //// directionX = -directionX;
- // }
- // else if (pos.x + radius > x) {
- // setDirectionDegree((360 - directionDegree + 180));
- //// directionX = -directionX;
- // }
- // if (pos.y - radius < 0) {
- // setDirectionDegree(360 - directionDegree);
- //// directionY = -directionY;
- // }
- // else if (pos.y + radius > y) {
- // setDirectionDegree(360 - directionDegree );
- //// directionY = -directionY;
- // }
- // }
- public double collideBound(int x, int y, double time) {
- double nextX = pos.x + directionX * time;
- double nextY = pos.y + directionY * time;
- double collisionTimeX = 2.0, collisionTimeY = 2.0;
- if (nextX - radius < 0) {
- collisionTimeX = (pos.x - radius) / (-directionX);
- nextDegree = 360 - directionDegree + 180;
- }
- else if (nextX + radius > x) {
- collisionTimeX = (x - radius - pos.x) / (directionX);
- nextDegree = 360 - directionDegree + 180;
- }
- if (nextY - radius < 0) {
- collisionTimeY = (pos.y - radius) / (-directionY);
- nextDegree = 360 - directionDegree;
- }
- else if (nextY+ radius > y) {
- collisionTimeY = (y - radius - pos.y) / (directionY);
- nextDegree = 360 - directionDegree;
- }
- collisionTime = Math.min (collisionTimeX, collisionTimeY);
- // System.out.println("time: " + collisionTime);
- if (time < 0)
- System.out.println("fail4");
- if ((this.pos.x + directionX * collisionTime > 190 || this.pos.y + directionY * collisionTime > 190) && collisionTime < 2.0) {
- System.out.println((this.pos.x + directionX * collisionTime) + " " + (this.pos.y + directionY * collisionTime));
- System.out.println("fail5");
- }
- return collisionTime;
- }
- public void collideBoundSimple(int x, int y) {
- if (pos.x - radius < 0) {
- nextDegree = 360 - directionDegree + 180;
- }
- else if (pos.x + radius > x) {
- nextDegree = 360 - directionDegree + 180;
- }
- if (pos.y - radius < 0) {
- nextDegree = 360 - directionDegree;
- }
- else if (pos.y+ radius > y) {
- nextDegree = 360 - directionDegree;
- }
- setDirectionDegree(nextDegree);
- }
- public double collideRobutton(Robutton rob, double time) {
- double currDistance = this.distance(rob);
- if (currDistance > 2) return time;
- Point2D.Double thisNextPos = new Point2D.Double (this.pos.x + this.directionX * time, this.pos.y + this.directionY * time);
- Point2D.Double robNextPos = new Point2D.Double (rob.pos.x + rob.directionX * time, rob.pos.y + rob.directionY * time);
- double nextDistance = thisNextPos.distance(robNextPos)-radius*2;
- // System.out.println("curr: " + currDistance);
- // System.out.println("next: " + nextDistance);
- if (currDistance < -(1e-6) || currDistance > 400)
- System.out.println("fail2");
- if (nextDistance < (1e-6d)) {
- double beta, gamma;
- // double tmp = (currDistance/(currDistance-nextDistance))*0.99;
- double tmp = movingSphereIntersectsMovingSphere(this.pos.x, this.pos.y, this.directionX, this.directionY, radius,
- rob.pos.x, rob.pos.y, rob.directionX, rob.directionY, radius)*0.99;
- if (tmp <= 0) return time;
- rob.collisionTime = tmp;
- this.collisionTime = tmp;
- Random rnd = new Random();
- Point2D.Double thisNextRealPos = new Point2D.Double (this.pos.x + this.directionX * tmp, this.pos.y + this.directionY * tmp);
- Point2D.Double robNextRealPos = new Point2D.Double (rob.pos.x + rob.directionX * tmp, rob.pos.y + rob.directionY * tmp);
- do {
- this.nextDegree = (directionDegree+180+rnd.nextInt(180)-90)%360;
- rob.nextDegree = (rob.directionDegree+180+rnd.nextInt(180)-90)%360;
- double alpha = Math.toDegrees(Math.atan2(thisNextRealPos.y-robNextRealPos.y, robNextRealPos.x-thisNextRealPos.x));
- if (alpha < 0) alpha+=360;
- gamma = this.nextDegree - alpha;
- beta = rob.nextDegree - alpha;
- if (gamma < 0) gamma = 360-gamma;
- if (beta < 0) beta = 360-beta;
- beta %= 360;
- gamma %= 360;
- } while(!(beta < gamma || beta > 360-gamma));
- System.out.println("new time: " + tmp);
- if (tmp < 0)
- System.out.println("fail");
- return tmp;
- }
- return time;
- }
- public void collideRobuttonSimple(Robutton rob) {
- double xdistance = this.pos.x - rob.pos.x;
- double ydistance = this.pos.y - rob.pos.y;
- double distance = Math.sqrt(xdistance*xdistance + ydistance*ydistance);
- if (distance < this.radius*2) {
- double xtrans = xdistance * (20-distance)/(distance);
- double ytrans = ydistance * (20-distance)/(distance);
- this.pos.x += xtrans*0.5;
- rob.pos.x -= xtrans*0.5;
- this.pos.y += ytrans*0.5;
- rob.pos.y -= ytrans*0.5;
- Random rnd = new Random();
- double beta, gamma;
- do {
- this.nextDegree = (directionDegree+180+rnd.nextInt(180)-90)%360;
- rob.nextDegree = (rob.directionDegree+180+rnd.nextInt(180)-90)%360;
- double alpha = Math.toDegrees(Math.atan2(this.pos.y-rob.pos.y, rob.pos.x-this.pos.x));
- if (alpha < 0) alpha+=360;
- gamma = this.nextDegree - alpha;
- beta = rob.nextDegree - alpha;
- if (gamma < 0) gamma = 360-gamma;
- if (beta < 0) beta = 360-beta;
- beta %= 360;
- gamma %= 360;
- } while(!(beta < gamma || beta > 360-gamma));
- }
- this.setDirectionDegree(this.nextDegree);
- rob.setDirectionDegree(rob.nextDegree);
- }
- private double movingSphereIntersectsMovingSphere(double center1X,
- double center1Y, double speed1X, double speed1Y, double radius1,
- double center2X, double center2Y, double speed2X, double speed2Y,
- double radius2) {
- // Rearrange the parameters
- double centerX = center1X - center2X;
- double centerY = center1Y - center2Y;
- double speedX = speed1X - speed2X;
- double speedY = speed1Y - speed2Y;
- double radius = radius1 + radius2;
- double radiusSq = radius * radius;
- double speedXSq = speedX * speedX;
- double speedYSq = speedY * speedY;
- double centerXSq = centerX * centerX;
- double centerYSq = centerY * centerY;
- double termBsq4ac = (radiusSq - centerYSq) * speedXSq + (radiusSq - centerXSq)
- * speedYSq + 2.0 * speedX * speedY * centerX * centerY;
- double termMinusB = -speedX * centerX - speedY * centerY;
- double term2a = speedXSq + speedYSq;
- if (termBsq4ac < 0) {
- // No intersection
- // Moving spheres may cross at different times, or move in parallel.
- return -1;
- } else {
- // Discard negative t (hit if moving backwards)
- // If two positive t, accept the smallest. The larger hits at the
- // opposite side.
- termBsq4ac = Math.sqrt(termBsq4ac);
- double sol1 = (termMinusB + termBsq4ac) / term2a;
- double sol2 = (termMinusB - termBsq4ac) / term2a;
- // Check solution
- if (sol1 > 0 && sol2 > 0) {
- return Math.min(sol1, sol2);
- } else if (sol1 > 0) {
- return sol1;
- } else if (sol2 > 0) {
- return sol2;
- } else {
- return -1; // both solutions negative
- }
- }
- }
- public double collideCoin(Coin coin, double time) {
- Point2D.Double thisNextPos = new Point2D.Double (this.pos.x + this.directionX * time, this.pos.y + this.directionY * time);
- if (thisNextPos.distance(coin.pos) < Robutton.radius + Coin.radius) {
- double tmp = movingSphereIntersectsMovingSphere(this.pos.x, this.pos.y, this.directionX, this.directionY, radius,
- coin.pos.x, coin.pos.y, 0, 0, Coin.radius)*0.99;
- this.collisionTime = tmp;
- this.nextCoin = coin;
- return tmp;
- }
- return time;
- }
- public void collideCoinSimple(Coin coin) {
- if (this.pos.distance(coin.pos) < this.radius + coin.radius) {
- this.coin = coin;
- }
- }
- public void setAfterCollisionDirection() {
- this.setDirectionDegree(nextDegree);
- }
- public Point2D.Double getPos() {
- return pos;
- }
- public int getXInt() {
- return (int) pos.x;
- }
- public int getYInt() {
- return (int) pos.y;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement