3 Replies Latest reply on May 1, 2008 12:44 PM by McFazstp

# Trig problem - facing sprite towards other sprite...

Okay, I've tried to get my brain around this several different ways, but for
some reason, nothing works quite the way I'd expect it to. Here's the
situation: I need to basically draw a line (a bitmap sprite, not an actual
line shape - it's really more of a fancy laser-beam type thing) between one
sprite and another. So my basic strategy was to create sprite of just a
vertical beam, with the regPoint moved to one end of it. Then I position
the sprite on loc A, figure out the length needed to reach loc B using the
distance formula and adjust the sprite's height accordingly (this works
perfectly), and finally rotate the sprite to face loc B so that the other
end lands on the target. This is where things fall apart. (First, can I
just say how annoying it is that Director's trig functions all work in
radians but the rotation for a sprite must be given in degrees...)

Anyhow, here's my current code, which is clearly wrong, somehow, but I can't
quite figure out how - in about half the cases, the sprite appears rotated
180 degrees AWAY from the intended target. I can't figure out what
determines whether it will work correctly or not, but I know I'm doing
something wrong. To use this, I pass the beam-sprite's function two
sprites, sp1 and sp2. Thus the command would look something like:

sprite("Beam").pos(sprite("Shooter"),sprite("Target"))

The 57.295... junk is the radians-degrees converter, at least I THINK that's
how to do it. The rest is self-explanatory. I know I'm close, because the
angle is always either just about right or it's off by 180 degrees. It's
never off at some unrelated-looking angle, always either correct or the
exact reverse.

property my
on beginSprite me
my = sprite(me.spriteNum)
end
on pos me,sp1,sp2
my.height = dist(sp1.loc,sp2.loc)
my.loc = sp1.loc
if (sp1.locH > sp2.locH and sp1.locV > sp2.locV) or (sp1.locH < sp2.locH
and sp1.locV < sp2.locV) then
ang = atan((sp2.locV-sp1.locV)/float(sp2.locH-sp1.locH))
my.rotation = (ang * 57.2957795)+270
else
ang = atan((sp2.locV-sp1.locV)/float(sp2.locH-sp1.locH))
my.rotation = (ang * 57.2957795)+90
end if
end

Elsewhere I have the distance formula used here:

on dist locA, locB
return
sqrt(((locA.locH-locB.locH)*(locA.locH-locB.locH))+((locA.locV-locB.locV)*(locA.locV-locB .locV)))
end

• ###### 1. Re: Trig problem - facing sprite towards other sprite...
If it's correct or off by 180 degrees then it's probably the if-then you need to take out and work out if it's plus 270 or plus 90 which is correct.

• ###### 2. Re: Trig problem - facing sprite towards other sprite...
> If it's correct or off by 180 degrees then it's probably the if-then you
> need
> to take out and work out if it's plus 270 or plus 90 which is correct.

Thanks, seems to work perfectly. You know, I was trying to get it to be one
formula before, but it never worked. The 270/90 split was added to make it
work right in situations where it didn't before. It was all going perfectly
well, too, until I moved some of the sprites that were shooting the beams,
and then it failed again. And - hey, whoa... How are you using 2 values in
the atan() function? The documentation doesn't say anything about it taking
more than one parameter, I thought you had to give it a ratio of the two
sides in order to receive an angle. Is this some sort of weird undocumented
shortcut?

• ###### 3. Re: Trig problem - facing sprite towards other sprite...
quote:

Originally posted by: Darrel Hoffman

Is this some sort of weird undocumented shortcut?

Yep. It is very useful because it avoids divide by zero errors and you don't have to convert values to floats.

put atan( 10, 0 )
-- 1.5708

put atan( 1/ 2 )
-- 0.0000

put atan( 1, 2 )
-- 0.4636