2

I'm trying to create a projectile, which when fired will behave as if it was shoot from catapult. The problem is to calculate trajectory. I have starting position. Also target is the closest enemy.

I tried to implement this formula, which I found in 2d projectile trajectory?

xn = x0 + v * t * cos(theta)
yn = y0 + v * t * sin(theta)

And this is how I implemented it:

    float v = 70f;
    t += Gdx.graphics.getDeltaTime();
    angle -= 0.1f;
    float xn = originX + v* t * MathUtils.cosDeg(angle);
    float yn = originY + v* t * MathUtils.sinDeg(angle);
    position.set(x,y);

I'm trying to make projectile move along the trajectory line something like on video below, target is determined by the catapult, it's the closest enemy: https://www.youtube.com/watch?v=mwU24AuQibw

EDIT

private float g = 9.8f;
private float v = 50;

public void update()
{
    t = Gdx.graphics.getDeltaTime();

    float dx = originX - target.x;
    float dy = originY - target.y;

    double radi = Math.sqrt(Math.pow(v, 4) - g * (g * dx * dx + 2 * dy * v * v));
    double theta1 = Math.atan((v*v + radi) / (g * dx));
    double theta2 = Math.atan((v*v - radi) / (g * dx));

    float xn = originX + v * t * MathUtils.cos((float) theta1);
    float yn = originY + v * t * MathUtils.sin((float) theta2);

    position.add(xn,yn);

I did the above code, but it makes the projectile to disappear, because I used add(xn,yn), but if I use set(xn, yn), projectile doesn't move at all. I was changing v trying different numbers, it doesn't make any difference. Also theta1 and theta2 gives me a NaN value.

FINAL EDIT

I tried all ways which I could think of, of implementing these formulas and it didn't work for me. I decided to make something different instead. Thank you all for the answers. I'll keep this thread so that someone may use the formulas posted here.

Community
  • 1
  • 1
draziw
  • 321
  • 3
  • 13
  • What exactly is your problem? "I'm struggling" is not enough information. Also: do you use box2d? – noone Nov 13 '13 at 16:08
  • I'm not using box2D. I'm using just libGDX. I need to move a projectile along the lines of trajectory. Difficult to explain, but basically projectile which is fired from catapult. That's how it should behave. – draziw Nov 13 '13 at 16:15
  • Therefore I need to calculate trajectory and make projectile move to the target along the lines of this trajectory if that makes sense. – draziw Nov 13 '13 at 16:18
  • Okay, and what exactly doesn't work? – noone Nov 13 '13 at 16:26
  • From the formula I implemented, trajectory is hard coded, because I specified the angle. I need to calculate trajectory according to where catapult is targeting. – draziw Nov 13 '13 at 16:35
  • Depending on how far is the target that's how high angle will be. Therefore I think it's a good starting point to solve original problem. Any ideas how I can calculate that? – draziw Nov 13 '13 at 16:51
  • I found another example of what I'm trying to do, but it's done in cocos2D, which I'm not familiar with: http://www.raywenderlich.com/4756/how-to-make-a-catapult-shooting-game-with-cocos2d-and-box2d-part-1 – draziw Nov 13 '13 at 17:04

1 Answers1

3

Your formula is not correctly used, because you assume the speed is constant (which is not true. Try shooting vertically, the speed should be 0 at some point), and the angle changes by 0.1 something no matter the amount of time elapsed.

v is the launch speed your projectile. theta is the launch angle. (x0, y0) is the launch position.

VX = v * cos(theta)
VY = v * sin(theta)

Gives you the correct launch vertical and horizontal speed.

Now, the alteration of the speed depends on 2 factors : air friction and gravity. Lets forget about friction for now.

Vxn is not subject to gravity. Therefore, it does not change.

Vyn is subject to gravity. It's value is given as function of time :

Vyn = VY + t * G
Vxn = VX

Where G is usually ~9.8m.s-2.

Now, to measure your angle, you need to figure out where the projectile hits the ground. Thats (Xtarget, Ytarget). (Xt, Yt) is the position of the projectile after time t has elapsed:

Xt = VX * t + x0
Yt = VY * t + 0.5 * G * t * t + y0

You want Xt == Xtarget and Yt == Ytarget

Given that you know v, the launch speed of the catapulte is known, this expression now only depends on theta (and t, but t can be expressed as a function of theta).

v * cos(theta) * t + x0 == Xtarget
v * sin(theta) * t + G * t * t + y0 == Ytarget

Solving this for theta should give you 2 solutions, one above and one below 45 degrees.

I have no idea how to do that for the moment.

Edit

Found this http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29

The complete formula is

Formula

As you can see, there are 2 possible values (+-). I call dx the delta between Xtarget and x0, same goes for dy. This translates in :

radi = Math.sqrt(Math.pow(v, 4) - g * (g * dx * dx + 2 * dy * v * v));
theta1 = Math.atan((v*v + radi) / (g * dx))
theta2 = Math.atan((v*v - radi) / (g * dx))

Now, usually g = 9.8m.s-2, but it works only if dx is in m, v in m.s-1. You'll have to adjust the values of the constant if not.

Further reading, air resistance! http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Trajectory_of_a_projectile_with_air_resistance

njzk2
  • 38,969
  • 7
  • 69
  • 107
  • Thank you for your comprehensive answer. Is then Xt and Yt a current position of the projectile? Also is this Xt = VX * t + x0 a final statement to get position? – draziw Nov 13 '13 at 18:18
  • Xt = VX * t + x0 Yt = VY * t + 0.5 * G * t^2 + y0 If this is the final statement to calculate current position of the projectile, then it doesn't work. I'm getting numbers between 0.6 to 0.8 for X and between 0.002 and 0.003 for Y. It doesn't increment further. It just displays numbers between. – draziw Nov 13 '13 at 18:27
  • It's a great source, but I don't really understand maths behind it. If you could help me to put this into code, I would be grateful. – draziw Nov 13 '13 at 19:04
  • Thank you for the explanation, I'll do my best to implement what you wrote. I'll post results. With air resistance we are going to far. I wanted just to make my projectile move along the trajectory line and hit the target. And thank you for all your help. – draziw Nov 13 '13 at 19:51
  • Is dx and dy a distance between target and origin of the projectile? – draziw Nov 14 '13 at 07:40
  • Also should I put theta1 and theta2 to this formula to get position: float xn = originX + v* t * MathUtils.cos(theta1); float yn = originY + v* t * MathUtils.sin(theta2); – draziw Nov 14 '13 at 08:07
  • dx and dy : yes, that's the 2 components of the distance. theta1 and theta2 are the 2 solution of the equation. you need to choose only one. (it is a quadratic equation, and therefore has 2 solutions.) – njzk2 Nov 14 '13 at 14:11