I'm trying to simulate a ball coming at the screen with a projectile motion arc in 2d space. Is there a set of equations to deal with this. I would imagine the equation would need to take in the initial vertical and horizontal angles of the projectile as well as it's initial velocity and the desired start and end scale of the projectile.


The basic implementation of projectile physics doesn't require any trigonometry.

First of all, you need to model the movement of your object with a velocity vector. A velocity vector is a structure which stores the velocity of an object on the x-axis and y-axis as spearate values. To move the object by a velocity vector, add the x- and y-value to its x- and y- position every logic-tick.

Gravity is then added to the simulation by subtracting the gravity from the y-axis of the velocity vector every logic-tick.

You didn't mention any programming language in your question, so here is a simple pseudo-code implementation in two dimensions which can be easily adapted for 3d by adding a z-coordinate which behaves like the x-coordinate:

// ball position:
float ball.x = [horizontal start position]
float ball.y = [vertical start position]
float ball.z = [depth start position]
// ball velocity vector:
float ball_velocity.x = [intial horizontal speed]
float ball_velocity.y = [initial vertical speed]
float ball_velocity.z = [initial depth speed]
// gravity constant:
const float gravity = [desited gravity constant]

function tick() {
      ball_velocity.y -= gravity;
      ball.x += ball_velocity.x;
      ball.y += ball_velocity.y;
      ball.z += ball_velocity.z;

To add perspective scaling to the simulation, simply divide the size of the ball by the distance to the camera. Assuming your camera is on z = 0, your draw function would look somehting like this:

function draw() {
     float ballDrawSize = ball.radius / ball.z;
     graphics.drawBall(ball.x, ball.y, ballDrawSize);

You could start with the 2d equation for the arc of the projectile, represented by some function of time:

function getPosition(time) {
    return {
        x: xInitial + xInitialVelocity * time,
        y: yInitial + yInitialVelocity * time + 0.5 * gravity * time * time

Then to create the 2.5D effect, map the position by multiplying the x position by the cosine of some angle. This angle represents the angle around the y-axis, to make it appear like a projectile is going in or out of the screen. Assuming xInitialVelocity > 0, an angle of 0 represents the projectile going to the right of screen. An angle of 90 -> projectile coming straight out of the screen. 180 -> left of screen and 270 -> away from screen.

function getPositionPsuedo3D(time, angle) {
    position = getPosition(time);
    return {
        x: position.x * cos(angle),
        y: position.y

You would also need to set the scale of the ball so it appears to be getting larger or smaller based on the time and angle:

function getScale(time, angle) {
    return 1 + sin(angle) * someScaleFactor * time;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.