# How to reflect the ball at an angle?

• JavaScript
• shivajikobardan
In summary, the ball should be reflected with an angle, how do I do it?To change the trajectory angle, for every change in 'Y', add (or subtract) a small amount to the 'X' position.If reflecting in the horizontal direction, Swap the 'X' and 'Y' in the above statement.For intermediate (diagonal) directions, apply a smaller addition (subtraction) to both 'X' and 'Y' positions; probably based on the sine and cosine of the trajectory angle.Thank you, Tom, for providing a summary of this content.f

#### shivajikobardan

TL;DR Summary
reflect ball at angle
Here's the full code:

When a ball collides with bat or walls, I want the ball to be reflected with an angle, how do I do it?
I suspect there's lots of physics to it. So, should I stop this project here? I'd have to probably build a part of game engine…Can anyone help here?

Your animation, just needs to change the position of the ball during each page refresh. When the x or y coordinate of the ball exceeds a boundary then you reverse the x or y velocity value.

some pseudo code
Code:
vx=3; vy=1; // pixel x,y velocity increments

while true {
// wall boundaries test
if x<0 or x>maxx then vx=-vx
if y<0 or y>maxy then vy=-vy
x=x+vx
y=y+vy
}

Depending on where the ball hits on the bat, you need to add or subtract horizontal velocity to the ball.
In effect, that gives the bat a curved face, but it is easier than transferring the bat velocity to the ball.

Your animation, just needs to change the position of the ball during each page refresh. When the x or y coordinate of the ball exceeds a boundary then you reverse the x or y velocity value.

some pseudo code
Code:
vx=3; vy=1; // pixel x,y velocity increments

while true {
// wall boundaries test
if x<0 or x>maxx then vx=-vx
if y<0 or y>maxy then vy=-vy
x=x+vx
y=y+vy
}
I've already done it, it just gives straight path like the one currently.

To change the trajectory angle, for every change in 'Y', add (or subtract) a small amount to the 'X' position.

This works when the ball is reflecting close to vertical. If reflecting in the horizontal direction, Swap the 'X' and 'Y' in the above statement.

For intermediate (diagonal) directions, apply a smaller addition (subtraction) to both 'X' and 'Y' positions; probably based on the sine and cosine of the trajectory angle.

Cheers,
Tom

p.s. Of course if you want to get really confused, try adding the effect of gravity!

• jedishrfu
1. In your JavaScript file (script.js), create variables for the ball's x and y velocity (e.g. "velocityX" and "velocityY").
2. In your animation loop (e.g. using setInterval or requestAnimationFrame), update the ball's position based on the velocity variables (e.g. ball.style.left = ball.style.left + velocityX + "px", ball.style.top = ball.style.top + velocityY + "px").
3. Use JavaScript to detect when the ball collides with the bat or walls (e.g. using the getBoundingClientRect() method) and then update the velocity variables accordingly. For example, when the ball collides with the left wall, you could reverse the velocityX variable (e.g. velocityX = -velocityX).
You can also use trigonometry to adjust the angle of reflection. If you want to reflect the ball at a certain angle, you'll need to calculate the new velocities in the x and y direction based on the angle of incidence and angle of reflection.

It's a bit more complex, but you can use the following formulas to calculate the new velocities:

velocityX' = velocityX * cos(2 * (angle of incidence - angle of reflection)) - velocityY * sin(2 * (angle of incidence - angle of reflection)) velocityY' = velocityY * cos(2 * (angle of incidence - angle of reflection)) + velocityX * sin(2 * (angle of incidence - angle of reflection))

Note: angle of incidence is the angle of the ball's velocity vector and angle of reflection is the angle of the reflecting surface.

So here is an example of the code for .js

JavaScript:
// Variables for ball position and velocity let ball = document.getElementById("ball"); let bat = document.getElementById("bat"); let velocityX = 5; // Initial horizontal velocity (can be positive or negative) let velocityY = -5; // Initial vertical velocity (can be positive or negative) // Initial positions of the ball let ballX = parseInt(ball.style.left); let ballY = parseInt(ball.style.top); // Animation loop setInterval(function() {  // Update ball position based on velocity  ballX += velocityX;  ballY += velocityY;  ball.style.left = ballX + "px";  ball.style.top = ballY + "px";  // Check for collision with bat  let batRect = bat.getBoundingClientRect();  let ballRect = ball.getBoundingClientRect();  if (ballRect.right > batRect.left && ballRect.left < batRect.right && ballRect.bottom > batRect.top && ballRect.top < batRect.bottom) {    // Reverse vertical velocity on collision with bat    velocityY = -velocityY;    // Set new angle of reflection    let angle = 20; // 20 degrees    // Convert angle to radians    let rad = angle * (Math.PI / 180);    let newVelocityX = velocityX * Math.cos(2 * (rad - rad)) - velocityY * Math.sin(2 * (rad - rad));    let newVelocityY = velocityY * Math.cos(2 * (rad - rad)) + velocityX * Math.sin(2 * (rad - rad));    // Update velocities    velocityX = newVelocityX;    velocityY = newVelocityY;  }  // Check for collision with walls  if (ballX + ball.offsetWidth > window.innerWidth || ballX < 0) {    // Reverse horizontal velocity on collision with walls    velocityX = -velocityX;  }  if (ballY < 0) {    // Reverse vertical velocity on collision with top wall    velocityY = -velocityY;  } }, 10);

It's more fundamental than that: you need to move away from using a CSS grid otherwise you will only ever be able to show rectilinear motion (plus perhaps diagonal). I have explained this on another thread.
https://www.physicsforums.com/threa...-screen-using-javascript.1048962/post-6841287
You can use a library like Matter.js and use an example like below:

JavaScript:
const { Engine, Render, Runner, World, Bodies } = Matter;

const engine = Engine.create();
const { world } = engine;
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false,
},
});

Render.run(render);
Runner.run(Runner.create(), engine);

const ball = Bodies.circle(200, 200, 50);

// Add a boundary to the walls
const walls = [
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
Bodies.rectangle(0, 300, 50, 600, { isStatic: true }),
];
World.add(world, walls);

Although the above is very simple, you would need to add your own variables etc

• Intelligence
I'm not using css grid in this project.
Well its probably a good idea to remove
CSS:
#board {
display: grid;
grid-template-rows: repeat(18, 1fr);
grid-template-columns: repeat(18, 1fr);
}
then.

Where did you get the idea that
JavaScript:
        document.getElementById("bat").style.transform = document.getElementById("bat").style.transform + translate(${20 * batPosition.x}px,${20 * batPosition.y}px);
was a good way to change the position of an element? Why have you chosen this over a variation on
JavaScript:
batElement.style.bottom = batPosition.y;
batElement.style.left = batPosition.x;

Last edited:
• .Scott
Well its probably a good idea to remove
CSS:
#board {
display: grid;
grid-template-rows: repeat(18, 1fr);
grid-template-columns: repeat(18, 1fr);
}
then.

Where did you get the idea that
JavaScript:
        document.getElementById("bat").style.transform = document.getElementById("bat").style.transform + translate(${20 * batPosition.x}px,${20 * batPosition.y}px);
was a good way to change the position of an element? Why have you chosen this over a variation on
I'm just focused on writing code rather than good or bad code, because my level is not that high.

• Tom.G
Where did you get the idea that
JavaScript:
        document.getElementById("bat").style.transform = document.getElementById("bat").style.transform + translate(${20 * batPosition.x}px,${20 * batPosition.y}px);
was a good way to change the position of an element?
Let me expand on this.
The result of this code is that the "style" keeps on getting longer and longer - and the amount of time required to process it gets longer and longer. If you were able to play the game long enough, it would eventually start getting noticeably easier.

For example, after about 20 steps, your style would look something like this:
style="transform: translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, -20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px) translate(0px, 20px)"

With contemporary computers - this hardly makes a practical difference in this particular case. But keep an eye out for the efficiency of the code you write. If you don't, it will eventually bite you.

• pbuk