Computer Science Canada

Determining direction of object

Author:  cavetroll [ Wed Apr 09, 2008 7:07 pm ]
Post subject:  Determining direction of object

Not sure if this is the right forum to post this in. If it is not the correct forum please move this topic.

I am building a Tower Defense. My question deals with finding the direction of the bullet.

I know the speed and the direction of the unit, and I know the speed of the bullet. How do I determine what direction the bullet should be moving in so it collides directly with the unit? I have asked others but they told me I didn't have enough data. I hoped they were wrong and just didn't understand the problem.

I hope I will not have to resort to brute force. Not my style Cool.

P.S. I don't need code just the equation.

Author:  Saad [ Wed Apr 09, 2008 7:14 pm ]
Post subject:  Re: Determining direction of object

You can use either Trig or use Vectors.

Trig Solution:

1. Get the angle between the bullet and the enemy.
2. Now that we have an angle, we can make the velocity a direction
velocity.x = speed * cos (angle)
velocity.y = speed * sin (angle)

Vector Solution

1. Get the vector from the bullet and the enemy
2. Make that vector a unit vector (ie A length of one)
So something like
direction.x = (enemy.x - bullet.x) / distance
direction.y = (enemy.y - bullet.y) / distance
3. Knowing the direction
velocity = direction * speed


Saad

Author:  cavetroll [ Wed Apr 09, 2008 7:38 pm ]
Post subject:  RE:Determining direction of object

Thanks for the reply.

Ok, my bad, I worded it badly. I know how to do what you described. What I need to find out is where the unit will be in X number of frames and what direction the bullet has to move in to be there as well (i.e. a collision).

Author:  OneOffDriveByPoster [ Wed Apr 09, 2008 7:40 pm ]
Post subject:  Re: RE:Determining direction of object

cavetroll @ Wed Apr 09, 2008 7:38 pm wrote:
Thanks for the reply.

Ok, my bad, I worded it badly. I know how to do what you described. What I need to find out is where the unit will be in X number of frames and what direction the bullet has to move in to be there as well (i.e. a collision).
Not your fault I think. I understood just fine; answer coming soon.
tower at (0, 0)

target at (x0, y0) at t = 0
target speed = s
target direction = (dx0, dy0)
(dx, dy) = s * unit_vec(dx0, dy0)
target_pos(t) = (x0 + t*dx, y0 + t*dy)

bullet speed = S
bullet_pos at time t:
x ^ 2 + y ^ 2 - (S * t) ^ 2 = 0

Consider:
(x0 + t*dx) ^ 2 + (y0 + t*dy) ^ 2 - (S * t) ^ 2 = 0

Hopefully you can solve for t and know how many frames it will take.
Substitute the specific value for t into target_pos(t) and you will know where the bullet has to be.

Author:  Saad [ Wed Apr 09, 2008 7:43 pm ]
Post subject:  Re: Determining direction of object

That would depend on what type of collision are you doing, eg Using circles for collisions for the detection would be much different then say having 2 boxes for finding the frames till the collision


Saad

Author:  OneOffDriveByPoster [ Wed Apr 09, 2008 8:02 pm ]
Post subject:  Re: Determining direction of object

Hopefully correct for when the target and the bullet are points:
code:
    x0^2 + 2*x0*t*dx + t^2*dx^2
+   y0^2 + 2*y0*t*dy + t^2*dy^2
- ( S^2  + 2*S*t     + t^2      )
=  0

A*t^2 = t^2*dx^2 + t^2*dy^2 - t^2
      = (dx^2 + dy^2 - 1) * t^2

B*t   = 2*x0*t*dx + 2*y0*t*dy - 2*S*t
      = 2*(x0*dx + y0*dy - S) * t

C     = x0^2 + y0^2 - S^2

Need to know the shape of the objects to do more.

Author:  r691175002 [ Wed Apr 09, 2008 10:49 pm ]
Post subject:  Re: Determining direction of object

http://jobemakar.blogspot.com/
Newest post should have what you want.

Author:  A.J [ Wed Apr 09, 2008 11:32 pm ]
Post subject:  Re: Determining direction of object

if you're just making a simple tower defense, then just use a pathfinding algorithm (like the A* perhaps, wink wink nudge nudge)
to make your 'creeps' (or bullets) to follow you. I can help u with the pathfinding if u need help.
try to look at fishtastic's turing tower defense in the turing submission forum, as its pretty good

but if you're doing something else, just ignore me Very Happy

(hope this helps)

Author:  OneOffDriveByPoster [ Wed Apr 09, 2008 11:51 pm ]
Post subject:  Re: Determining direction of object

Okay; I copied the equation wrong between steps Sad.

Anyhow, I hope you understand how I derived the equations...

code:
    x0^2 + 2*x0*t*dx + t^2*dx^2
+   y0^2 + 2*y0*t*dy + t^2*dy^2
-                      S^2*t^2
=  0

A*t^2 = t^2*dx^2 + t^2*dy^2 - S^2*t^2
      = (dx^2 + dy^2 - S^2) * t^2

B*t   = 2*x0*t*dx + 2*y0*t*dy
      = 2*(x0*dx + y0*dy) * t

C     = x0^2 + y0^2


My first Turing program that is not a compiler testcase (is not sufficient to steal wholesale):
Turing:
import GUI
setscreen ("graphics:  500; 500, offscreenonly, nobuttonbar")

var bgcolor : int := 255;
Draw.FillBox (0, 0, 500, 500, bgcolor)
View.Update

%%%%% config

var x0, y0 : int
var dx, dy, s, sp : real

x0 := 0
y0 := -200
dx := 1
dy := 1

s := 2
sp := 5

%%%%% end config

%%%%% calculate the hittime and which direction to shoot in

var b_dx, b_dy, hittime : real

loop
    const lend : real := sqrt (dx ** 2 + dy ** 2)

    dx := dx * s / lend
    dy := dy * s / lend

    const A : real := dx ** 2 + dy ** 2 - sp ** 2
    const B : real := 2 * (x0 * dx + y0 * dy)
    const C : real := x0 ** 2 + y0 ** 2

    const dis : real := B ** 2 - 4 * A * C

    if dis < 0 then
        put "No real hittime."
        return
    end if

    const hittime0 : real := (-B + sqrt (dis)) / (2 * A)
    const hittime1 : real := (-B - sqrt (dis)) / (2 * A)

    if hittime0 >= 0 and hittime1 >= 0 then
        hittime := min (hittime0, hittime1)
    elsif hittime0 >= 0 then
        hittime := hittime0
    elsif hittime1 >= 0 then
        hittime := hittime1
    else
        put "No non-negative hittime."
        return
    end if

    b_dx := x0 + hittime * dx
    b_dy := y0 + hittime * dy

    put "hittime = ", hittime
    put "target = (", b_dx, ", ", b_dy, ")"

    const lenb := sqrt (b_dx ** 2 + b_dy ** 2)
    b_dx := b_dx / lenb
    b_dy := b_dy / lenb
    put "bullet = (", b_dx * sp * hittime, ", ", b_dy * sp * hittime, ")"

    exit when true
end loop

%%%%% done calculate

for t : 0 .. floor (hittime + 20)
    if t > hittime then
        bgcolor := 0;
    end if

    Draw.FillBox (0, 0, 500, 500, bgcolor)

    % center
    Draw.FillOval (250 + 0, 250 + 0, 5, 5, 30)

    % target
    Draw.FillOval (250 + floor (x0 + t * dx), 250 + floor (y0 + t * dy), 5, 5, 40)

    % bullet
    Draw.FillOval (250 + floor (t * sp * b_dx), 250 + floor (t * sp * b_dy), 5, 5, 50)

    View.Update
    delay (100)

    exit when t = floor (hittime + 20)

    % remove old target
    Draw.FillOval (250 + floor (x0 + t * dx), 250 + floor (y0 + t * dy), 5, 5, bgcolor)

    % remove old bullet
    Draw.FillOval (250 + floor (t * sp * b_dx), 250 + floor (t * sp * b_dy), 5, 5, bgcolor)
end for


Edit: ... and I left out some division-by-zero cases...

Author:  cavetroll [ Thu Apr 10, 2008 2:58 pm ]
Post subject:  RE:Determining direction of object

Thank you so much for your responses, you solved my problem.


: