views:

552

answers:

2

I need to implement a little bit of Ai that can apply an impulse to a rigid body in order to hit a target. Like a cannon ball being fired from a cannon. I'm using Chipmunk Dynamics for the physics engine.

My maths is terrible, as is my physics, but i've been reading up, and with a little help from SO and the following from this wikipedia entry, I got this

float x = target.x = launchPos.x;
float y = target.y = launchPos.y;
float g = 9.8;
float v = 100;
float angle1, angle2;

float tmp = pow(v, 4) - g * (g * pow(x, 2) + 2 * y * pow(v, 2));

if(tmp < 0){
NSLog(@"No Firing Solution");
}else{
angle1 = atan2(pow(v, 2) + sqrt(tmp), g * x);
angle2 = atan2(pow(v, 2) - sqrt(tmp), g * x);
}

// Split the velocities
float vVel = v * sin(angle2);
//NSLog(@"Vertical Velocity: %f", vVel);

float hVel = v / cos(angle2);
//NSLog(@"Horizontal Velocity: %f", hVel);

CGPoint force = cpv(hVel, vVel);

Which should give me the angle, from which I can calculate the horizontal and vertical velocities needed to launch the projectile.

However, it's not working, which doesn't surprise me at all for a number of reasons. Firstly because I'm terrible at Maths and Physics, but also because I'm confused by a couple of other things.

  1. This method doesn't seem to take mass into account. Should it? I would have thought that was quite important? But then, I studied art at college, so I might be wrong about that.

  2. Box2d has PTM_RATIO, but I can't find anything like that in chipmunk, so how do my values correspond to the space coordinates in chipmunk?

  3. I know of radians and how they differ to degrees, and how to convert between the two. But which should I be using here? should I be converting angle1 and angle2 to degrees? Even if I do, It still doesn't work.

In summary, there's a lot about physics and chipmunk that I don't understand. So I'm here, asking for help.

Is there something in chipmunk that I can use to figure this out, or if anyone has had to figure this out themselves, I'd really appreciate some help.

+1  A: 

For one, I would think that horizontal velocity should be:

float hVel = v * cos(angle2);

And also, you are right that you need to take mass into consideration. It looks like you are deriving the force vector directly from velocity, and that's not correct.

I've never used Chipmunk, but I am guessing that you can't directly apply a velocity to an object? You have to apply a force, which accelerates an object to a particular velocity. The equation for Force is simple:

F = ma

Since we are accelerating this projectile from zero velocity to v, acceleration would be equal to v. However, you need to multiply this acceleration by the object's mass in order to get the correct force required.

CGPoint force = cpv(hVel, vVel) * projectileMass;
Andrew Garrison
You're right about cos(angle). Im also guessing that it's cpv(hVel * pmass, vVel * pMass). This makes sense, but i'm still not getting the desired result. I think gravity might be the problem, I'm assuming chipmunk simulates gravity as 9.8i.
gargantaun
A: 

Ok. The problem is (Besides the typo of v*cos(angle)) that you are confusing force with impulse.

Applying a force with an angle does not make the object's velocity have the required angle and magnitude. You must either:

  • Set the velocity to the required velocity by manually changing the velocity using the cpBodySetVel(cpBody *body, cpFloat Vel) setter, or
  • Assuming the initial velocity is 0, apply an impulse to the object.

I can't stress this enough, a Force is not the same as an Impulse:

  • If you apply a constant force to an object, the velocity will change continuously in time, from 0 velocity to an infinite velocity... not at all what you want.
  • If you apply a one time impulse to an object, the velocity will change immediately from v0 to v0+impulse/mass.

I don't think Chipmunk allows applying impulses. But you can probably simulate an impulse by dividing the force by the time step of the algorithm, applying the force for one time step and removing the force afterwards. But it is probably better to stick to setting the velocity using the setter.

If you really must apply a constant force to the body to arrive to the target, then the equations are not the ones you found in wikipedia.

Ezequiel
Sorry, I read Chipmunk and assumed C++'s Chipmunk :) Still, the physics advise is the same: the formula in wikipedia is for the angle of the velocity when you don't apply any force to the object (Only force is gravity).
Ezequiel
i see what you're saying. Perhaps my variable name was a bad choice. by 'force' I mean 'force of the impulse'. Perhaps it's not a good idea to mix the terminology, but it's what made sense to me at the time. Chipmunk does allow you to apply an impulse.
gargantaun
It would be nice to have some debugging information, can you apply the impluse and get the velocities? Also, I would like an example of the data you use: initial position of the projectile, position of the target.I hope that's not too much to ask. I'm a physicist and I've used chipmunk's python extensions so I think I can help you.
Ezequiel