0
101 May 29, 2012 at 14:57

I need to figure out some way to give a projectile an initial speed in order to reach point pf, starting from point pi, with a velocity in the direction of dir.

The equation for motion is:
pf = pi + vt + .5at\^2

I can solve for v:
v = (pf-pi-.5at\^2)/t

I can even solve for the speed
speed*dir = (pf-pi-.5at\^2)/t
speed = (pf-pi-.5at\^2)/(t*dir)

but the problem is that the new equation expects a time input. Time should not matter in this equation, as I can not know from beforehand how much time the trajectory will take.
How should I solve this? and what does it mean to divide a vector by a vector (as given by the new equation)?

thanks

#### 9 Replies

0
165 May 29, 2012 at 17:16

I would try setting this up as simultaneous equations for t and speed. Take your equation “speed*dir = (pf-pi-.5at\^2)/t” and split it into x and y components; that will give you two equations in two unknowns, which should be soluble. (I’m assuming this is in 2D. If in 3D, dir and pf - pi must be in the same plane, so you could transform into coordinates where this plane is the xy plane, or similar.)

0
101 May 29, 2012 at 17:28

@Reedbeta

I would try setting this up as simultaneous equations for t and speed. Take your equation “speed*dir = (pf-pi-.5at\^2)/t” and split it into x and y components; that will give you two equations in two unknowns, which should be soluble.

Sorry, forgot to mention this is 3D.
Do you mean apply substitution?
In that case, I’m not sure how to solve for t. I get stuck because one is quadratic and the other is linear:

vt = pf-pi-.5at\^2
vt+.5at\^2=pf-pi
t(v+.5at) = pf-pi

I’m stuck there. What to do now?

0
175 May 29, 2012 at 19:46

Time is important because it dictates how fast the projectile will reach its target, which thus influences the initial velocity. You can’t ignore time because time determines how the projectile is shot in the first place. Shooting something at the speed of light would be a direct line of sight. Shooting something at an angle with a lower velocity will increase the amount of time for the projectile to reach its target. There’s an infinite number of solutions to this problem.

I’m not sure of the rules you are bound to, but I would establish some reasonable initial velocities (or times) and work out the rest from there. I would keep my projectiles limited to 2 dimensions. Find out how to get from (x,y) to (x1,y1), and then determine what angle you must shoot at so that the projectile flowing upwards and downwards along the Z-axis doesn’t hit the ground prematurely.

0
101 May 29, 2012 at 20:23

The angle must be fixed. If the equation has no solution then the function just returns false.

Also, you can reach nearly any position that is in the same plane with a fixed angle (\~direction), if the speed is allowed to vary. As long as the position is in front of the target and it’s height at x,y is less than the height at x,y determined by the ray of the direction. So there must be a solution.

I’m not ignoring time. I’m just saying that the equation should find out itself how much time is needed, because if the projectile is only allowed to travel a certain time, with a fixed angle, it surely can’t reach many positions.

0
165 May 29, 2012 at 21:10

I think he has a fixed launch direction and only wants to solve for the launch speed. In that case there should be a unique solution.

0
165 May 29, 2012 at 21:53

Here’s what I got. In 2D, assuming a is the acceleration, d is the direction, p is the inital point and q is the final point:

speed * d_x = (q_x - p_x - 0.5 a_x t\^2) / t
speed * d_y = (q_y - p_y - 0.5 a_y t\^2) / t

Solve the y-equation for speed: speed = (q_y - p_y - 0.5 a_y t\^2) / (t d_y)
Sub into the x-equation, cancel the ‘t’ in the denominator and multiply by d_y: (q_y - p_y - 0.5 a_y t\^2) * dx = (q_x - p_x - 0.5 a_x t\^2) * d_y
Solve for t: t = sqrt((q_y - p_y) * d_x - (q_x - p_x) * d_y) / (0.5 * (a_y * d_x - a_x * d_y)))

Then plug that t value back into the speed equation to get the speed.

I note that the expressions like (a_y * d_x - a_x * d_y) look rather like the z-component of a vector cross product, so perhaps there is a way you can generalize this to full 3D easily by using magnitudes of cross products of the vectors involved, rather than having to project / rotate it into 2D.

0
101 May 30, 2012 at 00:49

I think I understand your equations, but I’m still not sure why I need to convert the problem to 2D?
I mean, doesn’t vector math apply to any number of dimensions?

Yes, if you assume that acceleration will always go downwards, then they will have to be in the same plane in order to reach the target, but (for the lolz of it) let’s assume an acceleration that is parallel to the ground and perpendicular to the direction vector, what would happen then? :)

Thanks for the help :)

0
165 May 30, 2012 at 00:56

The reason it’s a 2D problem is that you can only hit the point if the launch direction, the vector from the initial to final point, and the acceleration are all in the same plane. If they aren’t *exactly* in the same plane, there is no solution whatever. Yes, vector math applies in any number of dimensions, but your problem is inherently 2D because it only has 2D solutions. :)

0
101 May 30, 2012 at 14:47

Hmm… I implemented this method, but at some angles it seems to fail… (too much speed)<br />
Any ideas what might be the cause of that?

EDIT: nvm found, the mistake. it was the NxVec3 front = targetpos-startpos. I should have ignored the y coeff there.

bool BasicProjectile::ComputeSpeedForTrajectory(float* speedOUT, float* timeOUT, float downwardsAccel, const NxVec3& dir, const NxVec3& startpos, const NxVec3& targetpos)
{
NxVec3 up = NxVec3(0.0f,1.0f,0.0f);
NxVec3 front= targetpos-startpos;
front.normalize();
NxVec3 right = up.cross(front);
right.normalize();

float rdd = right.dot(dir);
if(rdd > 0.01f || rdd < -0.01f) {
return false;
}

D3DXVECTOR2 dir2(dir.dot(front), dir.dot(up));
D3DXVec2Normalize(&dir2, &dir2);

float dirX = dir2.x;
float dirY = dir2.y;

float startX = startpos.dot(front);
float startY = startpos.dot(up);

float endX = targetpos.dot(front);
float endY = targetpos.dot(up);

float accelX = 0.0f;
float accelY = -downwardsAccel;

float t = (((endY-startY)*dirX) - ((endX-startX)*dirY)) / (0.5f*((accelY*dirX) - (accelX*dirY)));
if(t <= 0) {
return false;
}
t = sqrt(t);

*timeOUT = t;
*speedOUT = (endY-startY-(0.5f*accelY*t*t)) / (t*dirY);

return true;
};