Aiming spaceship turrets

Blitz3D Forums/Blitz3D Programming/Aiming spaceship turrets

JKP(Posted 2004) [#1]
Hi, I am working on a space combat game in Blitz but I am having problems aiming the turrets on ships. The turrets are made of 2 components, one can change its yaw, the other can change its pitch. I can make the turrets point correctly towards a stationary target when the ship itself is also stationary and if the turret fires a projectile it will hit the target OK. However, if the ship and/or the target are moving it's much more complicated because the projectile will already have a velocity to start with. If the target is moving very quickly too, then aiming the turret at the target's current position won't work, because the target will have moved by the time the projectile gets there.
So I was hoping someone might be able to help me with the maths needed to hit a fast moving target. I'm not too bothered about compensating for acceleration etc.

Here's what I am doing to aim the components of the turret:
(Hope I remembered it correctly)

TFormPoint tx,ty,tz,0,yawcomp
;where tx,ty,tz is the target's position
;yawcomp is the part of the turret that changes its yaw

yawchange = ATan2(TFormedZ(),TFormedX()) - 90
TurnEntity yawcomp,0,yawchange,0,False

I use a similar thing for aiming the pitch, but with the y and z values instead of the x and z values

One other thing: how can I change the amount of smoothing used on meshes in Blitz? After exporting my space ship models from Milkshape they always end up with darkened patches where there are steep angles between triangles.

Thanks for any help...


jfk EO-11110(Posted 2004) [#2]
I have no code, but an idea. Simply calculate the time your projectile takes to travel to the target. Then calculate where the target is going to be after this amount of time (based on the targets speed), then aim to that position and fire. Of course, this is not totally accurate because the current distance from your ship to the target is less (or diffrent) than the distance to the target at the time of the impact. However, you can try to equalize this be recalculating distance to expected target position and flight-time several times.
Hmm - i feel there must be an easier solution, just can't see it right now :o)


Stevie G(Posted 2004) [#3]
The commands DELTAPITCH and DELTAYAW are great for this kind of thing.

I use something like this ...

Global Pivot = CreatePivot()

;=====================================
;=====================================
;=====================================

Function AIMat( x#, y#, z#, Turret, Smooth# )

	PositionEntity Pivot,x,y,z
	DP# = LIMIT( DeltaPitch( Turret, Pivot) , -Smooth, Smooth )
	DY# = LIMIT( DeltaYaw( Turret, Pivot ) , -Smooth, Smooth )
	TurnEntity Pivot,DP,DY,0
	
End Function

;=====================================
;=====================================
;=====================================

Function LIMIT#( q#, lo#, hi# )

	If q < lo q = lo
	If q > hi q = hi
	
	Return q
	
End Function



Where Smooth is the turn speed of the turret. To anticipate where the target will be by the time the bullet gets there I kind of do something similar to Jfk.

This makes it a bit more random ...

time# = TargetDistance / BulletSpeed
ox# = TargetSpeed * time
oz# = TargetSpeed * time
PositionEntity Pivot, x + Rnd(-ox,ox) , y , z+ Rnd(-oz,oz)

Might not work for you but may help.

Stevie


sswift(Posted 2004) [#4]
I think you need to solve two equations at the same time...

You have one equation that reprents the line along which the space ship is currently traveling.

You have another equation that represents the turret's line of sight.

The turret's line of sight equation is full of unknowns since you don't know where this line should point.

There are also two additional values that come into play. The speed of the ship, and the speed of the bullet.

Now when I sketch this out on paper, it becomes apparent that I could hit the ship at any number of locations along it's line of travel. We have to choose a location to hit. I guess the ideal location to hit would be the location where the ship has to travel the shortest distance.

Hm...

What you want is you want to:

A) Take ship-line and calculate turret-line such that intersection point of turret line is equal to how far the bullet would travel if fired at this moment.

Ie, the more perpendicular the two lines are, the less time it will take for the bullet to reach the target point.

Boy this is tough to explain... Especially when I don't know what I'm doing myself. :-)

Okay we know the player's ship line is fixed.

Now, for each point along that line, it is associated with a certain time in the future.

That time is the time at which the player's ship will arrive there if it remains on it's current course.

Aha...

So, our goal is to find a point where the turret line of sight intersects the ship line.... And this point has to have the same time on both lines.

We know these:
Ship_X#
Ship_Y#
Ship_Z#

ShipVector_Nx#
ShipVector_Ny#
ShipVector_Nz#

Turret_X#
Turret_Y#
Turret_Z#

TurretBullet_Speed#
Ship_Speed#

We do not know these:
TurretVector_Nx#
TurretVector_Ny#
TurretVector_Nz#

ShipVector_IntersectionDistance#
TurretVector_IntersectionDistance#



IntersectionDistance# is the world distance from the start of the vector to the point of intersection.

Speed# is a value which tells us what distance along the vector is equal to what amount of time.

For example, if Speed# is 2.0, then traveling one unit along the vector takes 2 seconds.


Now, we need to find a point along the ship's line where:

ShipVector_IntersectionDistance#*Ship_Speed# = TurretVector_IntersectionDistance#*TurretBullet_Speed#

It turns out there are lots of such points.

Hm...

You know, there are much easier ways of doing this. :-) Like for example, simply dtermining when the ship is within a certain distance of the turret, and firing in it's general direction. :-)


Paul "Taiphoz"(Posted 2004) [#5]
there is a way to do it - any maths.

What I would do is create a pivot on each ship. call this the target pivot.

then as the ship moves, you move it out in front of its parent by a set amount based on the ships seed.

You then have your gun turret aim at a ships target pivot and not the ship, as the pivot is always out away from the ship depending on what speed its doing your turret will aim in the right place.

it might take a tweak or two to get the distance right based on the bullet speed...

but this would require less maths and would probably be quicker as well and easier to use.


sswift(Posted 2004) [#6]
Yavin:
If you don't move that pivot further away from the ship based on the ship's speed though, then if the ship is moving slowly, the turret will overcompensate and the shots will miss.

Also I don't think that will work if the distance between ship and turret varies. What is a good enough lead distance when the ship is near the turret is not good enough when the ship is far from it.


Paul "Taiphoz"(Posted 2004) [#7]
Also I don't think that will work if the distance between ship and turret varies. What is a good enough lead distance when the ship is near the turret is not good enough when the ship is far from it


Trust me m8 it works, Iv done it.

And yes it does, because the distance the Pivot is from the ships is based on how fast the ship is moving. So if you show where the pivot is the bullet will hit the ship every time, unless of course the ship changes speed or direction after you fire the shot.

For example.

[]
SP PV
If the box is the Player Turret, SP is the Ship, and PV is the ships pivot, its well out in front cos the ship is moving fast, In this case the Turret will shoot in front of the ship but the ship will fly into the bullet, THUS getting the kill.

This doeas of course go with the understanding of the speed of the turrets bullet.

What I did was get it so that it NEVER missed. I then just flung in some random values to make it miss every now and then.


sswift(Posted 2004) [#8]
Ah, I failed to notice this line:
"you move it out in front of its parent by a set amount based on the ships s(p)eed."


WolRon(Posted 2004) [#9]
Yavin's idea doesn't take into account the distance of the turret to the target, which will affect the time it takes to get to the target. You might have to add a variable in there that transforms the target area out in front of the pivot based on distance to the target.


sswift(Posted 2004) [#10]
I agree... I forgot I mentioned that bit.

Yeah... so you have to multiply the distance of the pivot from teh front of the ship by the speed of the ship AND the distance of the ship from the turret. But before you do that you have to scale those values by some amount. Well, scale the turrent to ship distance anyway. I think.

Actually... if the ship is moving away from the turret, then wouldn't this give you a point some distance in front of the ship, even though the point you should be aiming for in that case is the ship itself? I wonder if this would not be a bit innacurate if the ship was traveling at a 45 degree angle to the turret.


jfk EO-11110(Posted 2004) [#11]
there are stilla lot of unknown values, eg. the multiplycation factor for those relations.

I'd rather say there is an easy math solution using radial intersection. Imagine there's a line the target will fly along. We know how long the projectile will travel to the current position of the target, We also know if the distance to the target is increasing or decreasing. Based on the angle of the targets flight we guess a radius that is big enough to hit the target somewhere on its line of flight.

Now we only have to draw a virtual cricle with that radius and where the circle intersects with the targets line of flight will be our aiming point.


Matty(Posted 2004) [#12]
Fairly simple, though not optimal method of working out the direction to aim the turret:

Own ship's turret currently has position X0,Y0,Z0 with velocity dx0,dy0,dz0.

Enemy Ship has position at X1,Y1,Z1 with velocities dx1,dy1,dz1.

Bullet has velocity VBullet

Assume that your bullets have a lifetime called "BulletLifeTime" which is the number of frames after firing that the bullet exists for.

Then perform this loop:
(use floats rather than ints for accuracy)
For StepNum=1 to BulletLifeTime
;calculate the enemy ship's position at each step
X1=X1+dx1
Y1=Y1+dy1
Z1=Z1+dz1
;calculate our own ship's position at each step
X0=X0+dx0
y0=y0+dy0
z0=z0+dz0

;calculate the distance from the turret to the enemy ship
Dist=Sqr((X1-X0)^2+(Y1-Y0)^2+(Z1-Z0)^2)

;check if this distance is greater than the distance a bullet could travel in the time taken so far:
IF Dist>VBullet*StepNum then
;do nothing - ie if we fired here then the bullet would miss
else
;if we fire at X1,Y1,Z1 now then the bullet should (may be slightly inaccurate - this check could be improved) hit the target

AIM AT X1,Y1,Z1 / Place targeting reticule etc at X1,Y1,Z1
exit ;because we have found the target point
endif

next