Arrow Bow Physics - Help!

Now your getting further away.

Projectiles move in a perfect parabola due to the gravity, if gravity did not exist, the projectile would travel in a straight line in the angle you shoot.

Gravity will push down on the projectile, causing it to move in a parabola.

and to pjt33, not sure what a flatter path is, quick google search didn’t return me anything useful, due to air resistance, it will not be perfect as the horizontal component will slow down, causing the flight path to not follow a parabola that is worked out without the the effect of air resistance.

Except lasers.

In the simplest model, air resistance directly opposes direction of motion, so it affects the vertical component too. I once did some work on finding suitable air resistance parameters to fit known shell ranges and predict ranges for other shells for a historical warfare game, but I don’t remember the values which I came up with.

For arrows the gyroscopic effect is likely to be quite significant in preventing the arrow from curving away from the straight line it would naturally follow. (Of course, it’s never that simple: there’s also precession to take into account…)

“The Mathematics of Projectiles in Sport” by Neville de Mestre might be worth getting hold of for people who are interested in realistic simulations.

PS HeroesGraveDev, stop digging.

I think for an arrow, the gyroscopic effect can be simulated fairly accurately by using an augmented version of gravity - say 7 instead of 9.81 (not that I tend to use 9.81 anyway (not using metres for the scene and seconds for the delta and all) but you get the point).

Lasers are light which is still effected by gravity (why black holes are black), so they do still follow a parabolic path, its just they leave the noticeable effects of Earth’s gravity before it can have any noticeable effect on it. See monkey and hunter.

Yeah, light goes too fast to see effects in Earth. But farther out in space, like near a black hole, light and time can both be affected noticably.

Yeah, light goes too fast to see effects in Earth. But farther out in space, like near a black hole, light and time can both be affected noticably.

True, but I’m pretty sure that when time itself is being warped by a black hole, it is hard to predict exactly what parabolic path an arrow would take. Probably best not to set an sonicesque archer game anywhere near a black hole. Unless it was directly between two black holes where they cancelled each other out, and the catch is that they are pulling themselves towards each other and crushing you so if you don’t complete the game before the black holes arrived then you get compressed down into nothing.

(Has revelation for game about quantum effects, realizes most people aren’t nerdy enough to play it)

True, but I’m pretty sure that when time itself is being warped by a black hole, it is hard to predict exactly what parabolic path an arrow would take. Probably best not to set an sonicesque archer game anywhere near a black hole. Unless it was directly between two black holes where they cancelled each other out, and the catch is that they are pulling themselves towards each other and crushing you so if you don’t complete the game before the black holes arrived then you get compressed down into nothing.

(Has revelation for game about quantum effects, realizes most people aren’t nerdy enough to play it)

Well, under a black hole, we can’t really tell what will happen at all… After all, after a certain point, you can’t see light anymore.

How did you get from arrows to black holes?
Anyway, basically you can do it like this.

class Arrow {
    double x, y,
           speedX, speedy;
    
    double gravity = 10;
    
    void setSpeedAndAngle(double speed, double theta) {
        speedX = Math.cos(theta) * speed;
        speedY = Math.sin(theta) * speed;
    }
    
    //dt = delta time
    void update(double dt) {
        y += speedY * dt + 0.5 * gravity * dt * dt;
        speedY += gravity * dt;
        x += speedX * dt;
    }
}

Well, under a black hole, we can’t really tell what will happen at all… After all, after a certain point, you can’t see light anymore.

How did you get from arrows to black holes?
Anyway, basically you can do it like this.

class Arrow {
    double x, y,
           speedX, speedy;
    
    double gravity = 10;
    
    void setSpeedAndAngle(double speed, double theta) {
        speedX = Math.cos(theta) * speed;
        speedY = Math.sin(theta) * speed;
    }
    
    //dt = delta time
    void update(double dt) {
        y += speedY * dt + 0.5 * gravity * dt * dt;
        speedY += gravity * dt;
        x += speedX * dt;
    }
}

The Squared/cubed/further and extra X functions for velocity/gravity and similar is used to represent time/total.

Which would mean that you can get away with far simpler math if you keep track of the totals yourself(Location, Velocity, and Acceleration). In this case your real velocity because you’re dealing with speed.

So to simulate an arrow going off You’re going to add a large amount to X-Velocity and Y-Velocity. Then each game tick you going to add X-Velocity and Y-Velocity to your arrow location X-Location/Y-Location(assume that all values can and will be negative).

To draw your Arrows tail you’re you’re going to base your angle on the new location and your old location for drawing. Going to take trig and maybe some linear math depending if you’re not drawing a sphere.

The fun part now is simulating acceleration. For this we’re going to have the variable X-Acceleration and Y-Acceleration, and we’re going to add them to velocity each tick. In the case of gravity we’re going to have a Positive Y-Acceleration(assuming 0,0 is the top left corner).

Now if we’re going to add friction this also becomes pretty simple to simulation, each tick we’re going take X-Velocity and Y-Velocity closer to 0(with simple addition/subtraction after we’ve found wither velocity is negative/Positive).

Believe or not that logic above is the logic behind calculus since you’re using derivatives there, Though I’m Sure It’ll piss off someone who takes math seriously(and forgot that it only exists for communication).


The next thing we need to consider is force/acceleration in a direction that isn’t 90 degrees.

For a pet project I want to to graph 360 points, with Sin as the X values and Cos as the Y values(Make sure you multiply by 20 or 30 or you’ll just get a useless point).

You should notice that You ended up drawing a Circle. Now with a bit of logic you’ll realize that A) All the points are the same distance from the center(the 20 or 30 you multiplied by) B) that at the 0/90/180/270 angles that that you’re going to have one value of X/Y be the 20 or 30 you multiplied by and the other value be 0(which is a restatement of A).

Which means that with some code wrangling you logical way to create a force/acceleration value(for adding) in any direction/angle.


EDIT: of course to work with this you’re going to want a fixed tick(delta) if you have anything that is multiplicative, and you can not lose ANY time in your game loop

The Squared/cubed/further and extra X functions for velocity/gravity and similar is used to represent time/total.

Which would mean that you can get away with far simpler math if you keep track of the totals yourself(Location, Velocity, and Acceleration). In this case your real velocity because you’re dealing with speed.

So to simulate an arrow going off You’re going to add a large amount to X-Velocity and Y-Velocity. Then each game tick you going to add X-Velocity and Y-Velocity to your arrow location X-Location/Y-Location(assume that all values can and will be negative).

To draw your Arrows tail you’re you’re going to base your angle on the new location and your old location for drawing. Going to take trig and maybe some linear math depending if you’re not drawing a sphere.

The fun part now is simulating acceleration. For this we’re going to have the variable X-Acceleration and Y-Acceleration, and we’re going to add them to velocity each tick. In the case of gravity we’re going to have a Positive Y-Acceleration(assuming 0,0 is the top left corner).

Now if we’re going to add friction this also becomes pretty simple to simulation, each tick we’re going take X-Velocity and Y-Velocity closer to 0(with simple addition/subtraction after we’ve found wither velocity is negative/Positive).

Believe or not that logic above is the logic behind calculus since you’re using derivatives there, Though I’m Sure It’ll piss off someone who takes math seriously(and forgot that it only exists for communication).


The next thing we need to consider is force/acceleration in a direction that isn’t 90 degrees.

For a pet project I want to to graph 360 points, with Sin as the X values and Cos as the Y values(Make sure you multiply by 20 or 30 or you’ll just get a useless point).

You should notice that You ended up drawing a Circle. Now with a bit of logic you’ll realize that A) All the points are the same distance from the center(the 20 or 30 you multiplied by) B) that at the 0/90/180/270 angles that that you’re going to have one value of X/Y be the 20 or 30 you multiplied by and the other value be 0(which is a restatement of A).

Which means that with some code wrangling you logical way to create a force/acceleration value(for adding) in any direction/angle.


EDIT: of course to work with this you’re going to want a fixed tick(delta) if you have anything that is multiplicative, and you can not lose ANY time in your game loop

G’day Andre,

I recently toyed with a program that involved a ship in orbit around multiple planets. The motion was taking into account gravity, thrust, and ultimately atmospheric drag (although I didn’t get around to that). It was all a bit overwhelming at the start, but it became ridiculously simple when using vector math.

So my suggestion is read up on simple vector math if you need to, and then roll your own 2D vector class. Then instead of worrying about parabolas and all that business, it just becomes a case of adding, normalising and multiplying a few vectors (which can be easily contained in a few methods of your vector class).

Then your update loop will essentially be:

  1. sum all the acceleration vectors in effect: acceleration = gravity + drag; [if you are modelling drag, which itself is dependant on velocity, otherwise acceleration = gravity and doesn’t change].
  2. apply the net acceleration vector to the velocity vector: velocity = velocity + acceleration * deltaTime;
  3. apply the velocity vector to your arrow’s position: position = position + velocity * deltaTime;
  4. repeat in the next loop.

In the above acceleration, gravity, drag and velocity are vectors. deltaTime is a scalar, and position could be treated as a point. It will result in the arrow taking the nice parabolic path that you are looking for.

You just need to set your initial velocity vector prior to launch, which will be influenced by the direction the arrow is pointing in, and its total initial velocity. You would:

  1. Normalise the direction vector (i.e. make it a vector in the same direction, but with a total length of 1; done by dividing both x and y by the length).
  2. Multiply the normalised vector by the total initial velocity (i.e. It might have a launch velocity of 60m/s, depending on how far back the bowstring is drawn).

Anyway, hope it makes a bit of sense, I’m not the best at explaining things. But if you look into vectors a bit, you should find they make life a lot easier. Let me know if you’ve got any questions, or want me to dig some code out.

nerb.

G’day Andre,

I recently toyed with a program that involved a ship in orbit around multiple planets. The motion was taking into account gravity, thrust, and ultimately atmospheric drag (although I didn’t get around to that). It was all a bit overwhelming at the start, but it became ridiculously simple when using vector math.

So my suggestion is read up on simple vector math if you need to, and then roll your own 2D vector class. Then instead of worrying about parabolas and all that business, it just becomes a case of adding, normalising and multiplying a few vectors (which can be easily contained in a few methods of your vector class).

Then your update loop will essentially be:

  1. sum all the acceleration vectors in effect: acceleration = gravity + drag; [if you are modelling drag, which itself is dependant on velocity, otherwise acceleration = gravity and doesn’t change].
  2. apply the net acceleration vector to the velocity vector: velocity = velocity + acceleration * deltaTime;
  3. apply the velocity vector to your arrow’s position: position = position + velocity * deltaTime;
  4. repeat in the next loop.

In the above acceleration, gravity, drag and velocity are vectors. deltaTime is a scalar, and position could be treated as a point. It will result in the arrow taking the nice parabolic path that you are looking for.

You just need to set your initial velocity vector prior to launch, which will be influenced by the direction the arrow is pointing in, and its total initial velocity. You would:

  1. Normalise the direction vector (i.e. make it a vector in the same direction, but with a total length of 1; done by dividing both x and y by the length).
  2. Multiply the normalised vector by the total initial velocity (i.e. It might have a launch velocity of 60m/s, depending on how far back the bowstring is drawn).

Anyway, hope it makes a bit of sense, I’m not the best at explaining things. But if you look into vectors a bit, you should find they make life a lot easier. Let me know if you’ve got any questions, or want me to dig some code out.

nerb.