
-----------------------------------
cavetroll
Wed Apr 09, 2008 7:07 pm

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 8-).

P.S. I don't need code just the equation.

-----------------------------------
Saad
Wed Apr 09, 2008 7:14 pm

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

-----------------------------------
cavetroll
Wed Apr 09, 2008 7:38 pm

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).

-----------------------------------
OneOffDriveByPoster
Wed Apr 09, 2008 7:40 pm

Re: 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).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.

-----------------------------------
Saad
Wed Apr 09, 2008 7:43 pm

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

-----------------------------------
OneOffDriveByPoster
Wed Apr 09, 2008 8:02 pm

Re: Determining direction of object
-----------------------------------
Hopefully correct for when the target and the bullet are points:
    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.

-----------------------------------
r691175002
Wed Apr 09, 2008 10:49 pm

Re: Determining direction of object
-----------------------------------
http://jobemakar.blogspot.com/
Newest post should have what you want.

-----------------------------------
A.J
Wed Apr 09, 2008 11:32 pm

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 :D

(hope this helps)

-----------------------------------
OneOffDriveByPoster
Wed Apr 09, 2008 11:51 pm

Re: Determining direction of object
-----------------------------------
Okay; I copied the equation wrong between steps :(.

Anyhow, I hope you understand how I derived the equations...

    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):
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...

-----------------------------------
cavetroll
Thu Apr 10, 2008 2:58 pm

RE:Determining direction of object
-----------------------------------
Thank you so much for your responses, you solved my problem.
