Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

help with vector maths, ballistic solution computation

Thanto Usitnov
Lord Byron wannabe
Join date: 4 Aug 2006
Posts: 68
01-11-2009 10:53
I would like some help with the math involved in ballistic solution computation.

Given:
Vp0 = projectile's initial position vector
Vp1 = projectile's velocity vector
Vt0 = target's initial position vector
Vt1 = target's velocity vector
t = time


Vp0, Vt0, Vt1 are known. Basically, I need to find Vp1. Magnitude of Vp1 should be 40.

I know that
Vp0 + (Vp1 * t) = Vt0 + (Vt1 * t)

and I can solve for Vp1:

Vt0 + (Vt1 * t) - Vp0
------------------------ = Vp1
t



but since I don't know what t is, this doesn't tell me anything useful. Any ideas?
Plastic Spoonhammer
Registered User
Join date: 9 Feb 2006
Posts: 20
01-12-2009 09:23
From: Thanto Usitnov
I would like some help with the math involved in ballistic solution computation.

Given:
Vp0 = projectile's initial position vector
Vp1 = projectile's velocity vector
Vt0 = target's initial position vector
Vt1 = target's velocity vector
t = time


Vp0, Vt0, Vt1 are known. Basically, I need to find Vp1. Magnitude of Vp1 should be 40.

I know that
Vp0 + (Vp1 * t) = Vt0 + (Vt1 * t)

and I can solve for Vp1:

Vt0 + (Vt1 * t) - Vp0
------------------------ = Vp1
t



but since I don't know what t is, this doesn't tell me anything useful. Any ideas?


So you're trying to figure out what initial velocity to impart such that your projectile will collide with the target, assuming the target does not change velocity?

The way to approach this depends on exactly what sort of projectile you're working on. If the projectile is relatively slow-moving (such as a mortar shell), then I would suggest picking a reasonable value of t representing how long you want the shell in the air, and using it to calculate your initial velocity. As long as t is suitably large, the velocity will remain under 250 m/s (the limit allowed by the physics system). Don't forget to take gravity into account, of course!

If, on the other hand, you're working on a bullet, then you want instead to fix the initial velocity's magnitude at 250 m/s and solve a system of equations to get the initial velocity's components:

Let P=<px,py,pz> and V=<vx,vy,vz> be the projectile's initial position and velocity
Let P'=<px',py',pz'> and V'=<vx',vy',vz'> be the target's initial position and velocity
We assume the force of gravity has been negated using llSetBuoyancy() or some other method.

As you already stated, V = (P'-P)/t + V'. Broken into components:
vx = (px' - px)/t + vx'
vy = ...
vz = ...

We have the additional constraint that the velocity be maximized:
||V|| = 250
=> vx^2 + vy^2 + vz^2 = 250^2
=> ((px'-px)/t+vx')^2 + (...)^2 + (...)^2 = 250^2
... (check my work - I did this quickly and I may have made a mistake)
=> (250^2-vx'^2)t^2 - 2vx'(px'-px)t = px'^2-2px'px+px^2

t is the only unknown, we complete the square to solve. To keep it legible, we define:
a = (250^2-vx'^2) b = - 2vx'(px'-px) c = px'^2-2px'px+px^2
so now we have:
at^2 + bt = c
=> t^2 + (b/a)t = c/a
... (completing the square)
=> t = +/- sqrt(c/a + (v^2)/(4a^2) - b/a)

You've got two solutions for t. If both are positive, take the smaller, otherwise take the positive one. Then plug your t into the expressions for the components of V, and you're all set.

Having worked through all of that, if you're trying to make a bullet that consistently hits its target, this is a bad idea =) The limitations and imprecision inherent in the scripting and physics systems (to say nothing of the dubious assumption that your target's velocity will remain constant) make this sort of thing very unreliable. My advice? Get the target's key with a sensor, use a non-physical object to home in on the target, and when you get within 10m start rezzing physical prims that do damage. If the target's moving quickly you might want to rez the damage prims slightly in front of it to increase the likelihood of a hit.
_____________________
P. Spoonhammer
Thanto Usitnov
Lord Byron wannabe
Join date: 4 Aug 2006
Posts: 68
01-12-2009 22:43
Well, I can't use non-phys prims like that, because that would be cheating.



Alright, so that looks good. I hope Mono can handle it efficiently.


The next bit is that I want to make the rezzer somewhat inaccurate by applying a slightly random vector to it such that it will generate a cone of fire. I obviously can't just increase one of the components by some random amount. Basically, I'd have to generate a vector that is orthogonal to the other one, where the magnitude is some random amount within a set limit. So, basically a unit vector orthogonal to the generated one multiplied by some random magnitude. I'm thinking I could generate a unit vector in the y/z plane, and then rotate it using a rotation generated from the previously generated vector. I'm not sure if it's possible to generate a rotation based on a vector, though. I know the reverse is possible with llRot2Fwd, but I don't think there's a reverse analogue.
Plastic Spoonhammer
Registered User
Join date: 9 Feb 2006
Posts: 20
01-13-2009 07:11
From: Thanto Usitnov
The next bit is that I want to make the rezzer somewhat inaccurate by applying a slightly random vector to it such that it will generate a cone of fire. I obviously can't just increase one of the components by some random amount. Basically, I'd have to generate a vector that is orthogonal to the other one, where the magnitude is some random amount within a set limit. So, basically a unit vector orthogonal to the generated one multiplied by some random magnitude. I'm thinking I could generate a unit vector in the y/z plane, and then rotate it using a rotation generated from the previously generated vector. I'm not sure if it's possible to generate a rotation based on a vector, though. I know the reverse is possible with llRot2Fwd, but I don't think there's a reverse analogue.


That sounds about right. A little trig will give you the maximum "random magnitude" corresponding to the size cone you want. As for the rotations:

Assume that when the turret is at <0,0,0> rotation its barrel points in the positive x axis. First, to get the rotation you need, you do

rotation theta = llRotBetween(<1,0,0>,llVecNorm(V)).

Incidentally, you can then use llSetRot(theta) to make your turret point in the direction the projectile is to be fired (again, assuming the barrel points down the positive x axis). To get your cone of fire, take the vector:

vector wobble = <0,1,0>*(rand_val);

rotate it a random angle around the x axis, and then rotate it to be orthogonal to V:

wobble = (wobble*llEuler2Rot(<llFrand(2*PI),0,0>;))*theta;

and finally add it into V:

V = V + wobble;
_____________________
P. Spoonhammer
Thanto Usitnov
Lord Byron wannabe
Join date: 4 Aug 2006
Posts: 68
01-13-2009 09:46
llRotBetween! That's what I was looking for. Thanks