This is a rather interesting problem because of its specificity.
Making a ball bounce in a programming language is easy. Like this example .
But it’s clear that your question is not “making it work”; you need explicit control over the coordinates and angles so that you can change them for whatever purpose you had in mind.
Since I'm pretty vulnerable to nerd sniping , I cleaned up my geometric skills and came up with the following snippet of pseudocode (I did this from scratch to make sure I have full control):
Intuition


pseudo code
theta = starting angle a = current x-coordinate of ball b = current y-coordinate of ball quadrant = quadrant-direction to which ball is moving /> Determine number between 1 and 360: theta /> Calculate quadrant .> 0-90 : quadrant 1: horizontal: 90-a vertical: b alpha: 90 - theta .> 90-180: quadrant 4: horizontal: 90-a vertical: 30-b alpha: theta - 90 .> 180-270: quadrant 3: horizontal: a vertical: 30-b alpha: 270 - theta .> 270-360: quadrant 2: horizontal: a vertical: b alpha: theta - 270 /> Calculate distance to side | /> Calculate distance to top/bottom | .> to side: n(alpha) = horizontal/cos(alpha) .> to top/bottom: m(alpha) = vertical /sin(alpha) /> Determine where ball is going to hit (n = side, m = top/bottom) .> n >= m : bounces at top/bottom .> m >= n : bounces at side .> switch (quadrant) .> 1 : n = right side m = top .> 2 : n = left side m = top .> 3 : n = left side m = bottom .> 4 : n = right side m = bottom /> Calculate coordinates of hit /> Define new angle // Normally, angle of impact = angle of reflection // Let define the angle of impact with respect to the origin (0,0) .> switch (quadrant) .> 1 : .> n >= m (at top/bottom) : x = a + vertical*tan(alpha) y = 0 theta = 180-theta .> m >= n (at side) : x = 90 y = b - horizontal*tan(alpha) theta = 270+alpha .> 2 : .> n >= m (at top/bottom) : x = a - vertical/tan(alpha) y = 0 theta = 270-alpha .> m >= n (at side) : x = 0 y = b - horizontal*tan(alpha) theta = 90-alpha .> 3 : .> n >= m (at top/bottom) : x = a - vertical/tan(alpha) y = 30 theta = 270+alpha .> m >= n (at side) : x = 0 y = b + horizontal*tan(alpha) theta = 90+alpha .> 4 : .> n >= m (at top/bottom) : x = a + vertical/tan(alpha) y = 30 theta = 90-alpha .> m >= n (at side) : x = 90 y = b + horizontal*tan(alpha) theta = 270-alpha /> Define new coordinates (for reusage of function) .> a = x .> b = y .> (optional) if you would like the angles to differ, enter extra term here: .> extra = ... .> theta = theta + extra
Implementing this code will allow you to work with ease of degrees and still be able to determine the coordinates.
It works as follows:
First determine the initial position of the ball (a, b) and its initial direction (theta)
Now the program will calculate:
- If the ball hits the target
- What are the coordinates of the ball on impact
- What is the new angle of reflection (this is the part you want to change).
And then it starts again to calculate a new hit.
In JavaScript, the code would look like this:
code
var width = 500; var height = 200; var extra = 0; var a; var b; var x; var y; var angle; var n; var m; var quadrant; var horizontal; var vertical; var alpha; var side; var topbottom; var sides; var i = 1; var txt=document.getElementById("info"); txt.innerHTML="x: "+a+"<br>y: "+b+"<br>angle: "+angle+"<br>quadrant: "+quadrant; function buttonClick() { if (i == 1) { a = 75; b = 75; //determine first angle randonmly angle = Math.floor((Math.random()*360)+1);; } else { a = xcoord(); b = ycoord(); } var oldAngle = angle; angle = findNewCoordinate(a, b, angle); sides = hitWhere(); var txt=document.getElementById("info"); txt.innerHTML="x: "+a+"<br>y: "+b+"<br>horizontal: "+horizontal+"<br>vertical: "+vertical+"<br>n: "+n+"<br>m: "+m+"<br>angle: "+oldAngle+"<br>alpha: "+alpha+"<br>quadrant: "+quadrant+"<br>side: "+topbottom+side+"<br>"+sides+"<br>"+i; i++; } function findNewCoordinate(a, b, angle) { if (angle >= 0 && angle < 90) { quadrant = 1; horizontal = width-a; vertical = b; alpha = (90 - angle); } else if (angle >= 90 && angle < 180) { quadrant = 4; horizontal = width-a; vertical = height-b; alpha = (angle-90); } else if (angle >= 180 && angle < 270) { quadrant = 3; horizontal = a; vertical = height-b; alpha = (270-angle); } else if (angle >= 270 && angle <= 360) { quadrant = 2; horizontal = a; vertical = b; alpha = (angle-270); } var cosa = Math.cos(alpha * Math.PI / 180); var sina = Math.sin(alpha * Math.PI / 180); var tana = Math.tan(alpha * Math.PI / 180); var tant = Math.tan(angle * Math.PI / 180); n = horizontal/cosa; m = vertical/sina; switch (quadrant) { case 1: if (m >= n) //hit at side { y = b - horizontal*tana; x = width; angle = 270+alpha; } else { y = 0; x = a + vertical*tant; angle = 180-angle; } side = "right side"; topbottom = "top"; break; case 2: if (m >= n) //hit at side { y = b-horizontal*tana; x = 0; angle = 90-alpha; } else { y = 0; x = a - vertical/tana; angle = 270-alpha; } side = "left side"; topbottom = "top"; break; case 3: side = "left side"; topbottom = "bottom"; if (m >= n) //hit at side { x = 0; y = b + tana*horizontal; angle = 90+alpha; } else { y = height; x = a - vertical/tana; angle = 270+alpha; } break; case 4: side = "right side"; topbottom = "bottom"; if (m >= n) //hit at side { y = b+horizontal*tana; x = width; angle = 270-alpha; } else { y = height; x = a + vertical/tana; angle = 90-alpha; } break; } //add extra degrees to the angle (optional) angle += extra; context.beginPath(); context.arc(a, b, 5, 0, Math.PI*2, true); context.stroke(); context.closePath(); context.fill(); drawLine(a,b,x,y); return angle; }
Attention!
Please note that there are many more ways to make a bounce program. But, since I solved the problem geometrically and without "shortcuts" , the unique characteristics of my program make it very easy for you to change your wishes:
- You can give an extra angle at a bounce angle (use
var extra ). - You can change the movement of the ball at any time (during a rebound, after a rebound, etc.).
- You have explicit access to the coordinates of the ball
- All devices are ordinary (in degrees and coordinates, so they are easy to understand and intuitive).
Also note that I did not make the program very concise, because that is simply not my goal. I wanted to create a program for a bouncing ball, which, although long, is an accurate realization of geometric intuition behind it.
You can find a demo of my program in this JSFiddle . Please note that the starting angle is determined randomly. Therefore, restarting the program will give a different angle.

Well, what about that.
Good luck building the rest of your program!