//2014-09-16
public class BouncyBall {
public static void main(String args[]){
if (args.length != 8) {
System.out.println("Error: usage is X, Y, Angle, Xl, Yl, Xr, Yr,N");
System.exit(1);
}
double x,y,xl,yl,xr,yr,angle;
int n;
x=Double.parseDouble(args[0]);
y=Double.parseDouble(args[1]);
angle=Double.parseDouble(args[2]);
xl=Double.parseDouble(args[3]);
yl=Double.parseDouble(args[4]);
xr=Double.parseDouble(args[5]);
yr=Double.parseDouble(args[6]);
n=Integer.parseInt(args[7]);
if ((x>xr || x<xl)||(y>yr || y<yl)) {
System.out.println("Error: Initial point is not within the box");
System.exit(1);
}
System.out.printf("%f, %f\n",x,y);
System.out.printf("Starting angle is %f Pi.\n", angle/Math.PI);
double startX, startY, endX, endY;
startX=x;
startY=y;
if (angle==0) {
System.out.printf("Ball bounces back and forth between (%.2f, %.2f) and (%.2f, %.2f).\n", xr,y,xl,y);
}else if (angle==Math.PI) {
System.out.printf("Ball bounces back and forth between (%.2f, %.2f) and (%.2f, %.2f).\n", xl,y,xr,y);
}else if (angle==(Math.PI/2)) {
System.out.printf("Ball bounces up and down between (%.2f, %.2f) and (%.2f,%.2f). \n", x, yr,x, yl);
}else if (angle == (3*Math.PI/2)) {
System.out.printf("Ball bounces up and down between (%.2f, %.2f) and (%.2f,%.2f). \n", x, yl,x, yr);
}else {
for (int i=0;i<n;i++) {
//declare local variables
while (angle>(2*Math.PI)) {
angle=angle-(2*Math.PI);
}while (angle<0) {
angle=angle+(2*Math.PI);
}
double distance;
if(angle>=0 && angle<(Math.PI/2)) {
//Quadrant 1
//
endX=getX(yr,startY, startX, angle);
endY=getY(xr, startY, startX, angle);
//Use the distance formula to find which one is closer
distance=getDistance(endX, endY, startX, startY, xr, yr);
//get new x, y and angle variables
if(distance==1) {
startX=endX;
startY=yr;
}else if (distance==2) {
startX=xr;
startY=endY;
}else if (distance==3){
startX=xr;
startY=yr;
}
angle=getNewAngle(distance, angle);
}else if (angle>(Math.PI/2) && angle<(Math.PI)) {
//Quadrant 2
//
endX=getX(yr,startY, startX, angle);
endY=getY(xl, startY, startX, angle);
//Use the distance formula to find which one is closer
distance=getDistance(endX, endY, startX, startY, xl, yr);
//get new x, y and angle variables
if(distance==1) {
startX=endX;
startY=yr;
}else if (distance==2) {
startX=xl;
startY=endY;
}else if (distance==3){
startX=xl;
startY=yr;
}
angle=getNewAngle(distance, angle);
}else if (angle>(Math.PI) && angle<((3*Math.PI)/2)) {
//Quadrant 3
//
endX=getX(yl,startY, startX, angle);
endY=getY(xl, startY, startX, angle);
//Use the distance formula to find which one is closer
distance=getDistance(endX, endY, startX, startY, xl, yl);
//get new x, y and angle variables
if(distance==1) {
startX=endX;
startY=yl;
}else if (distance==2) {
startX=xl;
startY=endY;
}else if (distance==3){
startX=xl;
startY=yl;
}
angle=getNewAngle(distance, angle);
}else if (angle>((3*Math.PI)/2) && angle<(2*Math.PI)) {
//Quadrant 4
//
endX=getX(yr,startY, startX, angle);
endY=getY(xl, startY, startX, angle);
//Use the distance formula to find which one is closer
distance=getDistance(endX, endY, startX, startY, xr, yl);
//get new x, y and angle variables
if(distance==1) {
startX=endX;
startY=yl;
}else if (distance==2) {
startX=xr;
startY=endY;
}else if (distance==3){
startX=xr;
startY=yl;
}
angle=getNewAngle(distance, angle);
}
System.out.printf("%2f, %2f\n", startX, startY);
System.out.printf("New angle is %f Pi\n", angle/Math.PI);
}
}
}
public static double getY(double xMax, double startY, double startX, double angle) {
double endY=(Math.tan(angle)*(xMax-startX))+startY;
return endY;
};
public static double getX(double yMax, double startY, double startX,double angle){
double endX=((yMax-startY)/Math.tan(angle))+startX;
return endX;
};
public static double getDistance(double endX, double endY, double startX, double startY, double xMax, double yMax){
double distance1=Math.sqrt(((endX-startX)*(endX-startX))+((yMax-startY)*(yMax-startY)));
double distance2=Math.sqrt(((xMax-startX)*(xMax-startX))+((endY-startY)*(endY-startY)));
if (distance1< distance2) {
return 1.0;
//hits top/bottom
}else if (Math.abs(distance1)>Math.abs(distance2)) {
return 2.0;
//hits left/right side
}
else {
return 3.0;
//hits corner
}
};
public static double getNewAngle(double distance, double angle){
double newAngle=0;
double anglePlus;
if (angle> 0 && angle<(Math.PI/2)){
//Quadrant 1
anglePlus=angle;
if(distance==1) {
newAngle=(2*Math.PI)-anglePlus;
}else if (distance==2) {
newAngle=(Math.PI)-angle;
}else if (distance == 3) {
newAngle=anglePlus+Math.PI;
}
}else if (angle> (Math.PI/2) && angle<(Math.PI)){
//Quadrant 2
anglePlus=(angle-(Math.PI/2));
if(distance==1) {
newAngle=(3*Math.PI/2)-anglePlus;
}else if (distance==2) {
newAngle=(Math.PI/2)-anglePlus;
}else if (distance == 3) {
newAngle=angle+Math.PI;
}
}if (angle> Math.PI && angle<((3*Math.PI)/2)){
//Quadrant 3
anglePlus=angle-Math.PI;
if(distance==1) {
newAngle=(Math.PI)-anglePlus;
}else if (distance==2) {
newAngle=(2*Math.PI)-anglePlus;
}else if (distance == 3) {
newAngle=angle+Math.PI;
}
}if (angle> ((3*Math.PI)/2) && angle<(2*Math.PI)){
//Quadrant 4
anglePlus=angle-((3*Math.PI)/2);
if(distance==1) {
newAngle=(Math.PI/2)-anglePlus;
}else if (distance==2) {
newAngle=(3*Math.PI/2)-anglePlus;
}else if (distance == 3) {
newAngle=angle+Math.PI;
}
}