1. Help with "facing" routine

I would like some help on a function that should work like this:

I pass it two sequences, the first one containing the coordinates of the
active character, the second one containg the coordinates of the point that
the active character should look at. I have a total of 24 facings, the first
one being directly up, the second 15 degrees to the right, the second 30
degrees to the right, and so on. They are indexed 1-24. The function is
supposed to return the facing index that most closely matches the character
looking towards the point. If anyone out there which is more stable at
mathematics like this could help me with the routine (it should be as fast
as possible, since it will be called many times each frame of the game) then
I would be very grateful. I've started working on it, but now I'm both lazy
and tired, and I'm not too keen on this kind of mathematics. Following is an
outline of the function:

function determine_facing(sequence char_pos, sequence point)
    -- find the closest match of the 24 possibilites
    return facing -- 1 to 24
end function

Any help is greatly appreciated, the main thing I'm out for is the fastest
way to find the angle which the point is at, relative to the character,
either in degrees (or radians) or even better expressed with the indexes.

Einar (who hopes his english is not _totally_ hopeless)

new topic     » topic index » view message » categorize

2. Re: Help with "facing" routine

I need a little more.

Are you sending me the current x,y of the character and the x,y of the
point to which you want a 1-24 reference returned ?

At 12:44 AM 7/1/98 +0200, you wrote:
>I would like some help on a function that should work like this:
>
>I pass it two sequences, the first one containing the coordinates of the
>active character, the second one containg the coordinates of the point that
>the active character should look at. I have a total of 24 facings, the first
>one being directly up, the second 15 degrees to the right, the second 30
>degrees to the right, and so on. They are indexed 1-24. The function is
>supposed to return the facing index that most closely matches the character
>looking towards the point. If anyone out there which is more stable at
>mathematics like this could help me with the routine (it should be as fast
>as possible, since it will be called many times each frame of the game) then
>I would be very grateful. I've started working on it, but now I'm both lazy
>and tired, and I'm not too keen on this kind of mathematics. Following is an
>outline of the function:
>
>function determine_facing(sequence char_pos, sequence point)
>    -- find the closest match of the 24 possibilites
>    return facing -- 1 to 24
>end function
>
>Any help is greatly appreciated, the main thing I'm out for is the fastest
>way to find the angle which the point is at, relative to the character,
>either in degrees (or radians) or even better expressed with the indexes.
>
>Einar (who hopes his english is not _totally_ hopeless)
>

 Joe Phillips, Assistant Director
 Information Technology Services
 Texas Wesleyan University     817-531-4284

new topic     » goto parent     » topic index » view message » categorize

3. Re: Help with "facing" routine

>function determine_facing(sequence char_pos, sequence point)
>    -- find the closest match of the 24 possibilites
>    return facing -- 1 to 24
>end function

I don't know the math, but I (hope I) can clear up the English:

Einar wants a routine that takes the character and the position of the
object (or whatever) he wants to face. Of 24 directions (15 degree
incriments), he needs to know what is the closets. (Possibly for AI
facing the player, or the player clicking on something and his player
facing it.)

I'll also see if I can come up with something.



_____________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

new topic     » goto parent     » topic index » view message » categorize

4. Re: Help with "facing" routine

Einar Mogen wrote:
>I have a total of 24 facings, the first
>one being directly up, the second 15 degrees to the right,
>the second <third> 30 degrees to the right, and so on.

i see a few things that are problems so far...
since you mention 'the first one being up' i'll assume
you are working in 3d??? no? if you are then 24 facings
isn't enough...what about upAND30 (as opposed to your
current of up OR 15 OR 30 OR 45 ... OR down)
what if the Zaxis only differs by like 1, then
the facing will be up/down when you really want
a facing along X,Y axis per degree rotation.
secondly, 24 facings still isnt enough for 3d.
this is the list of angles as you specified:
15,30,45,60,
75,90,105,120,
135,150,165,180,
195,210,225,240,
255,270,285,300,
315,330,345,360
now if you note, '0' zero, is not included there.
if '0' is up, then so will be 360, since the trig
formulas will say those are equal.
also, suppose the angle comes back as 359. rounding would make
that 360, but that is -down- (supposedly) as opposed to
the desired 345.

now if it is 2d, the routines become easier, rounding will
work, and 0 versus 360 wont matter. :)
(i -say- easier...;) )

function determine_facing(sequence char_pos, sequence point)
   -- find the closest match of the 24 possibilites
   -- format: char_pos = {x,y} point = {x,y}
   --         facing = -pi/2 to pi/2 radians
   constant xi = 1 --X axis index
   constant yi = 2 --Y axis index
   atom facing
   --compute rise/run AKA opposite/adjacent
   facing = (char_pos[yi]-point[yi]) / (char_pos[xi]-point[xi])
   --find angle in radians
   facing = arctan( facing )
   return facing
end function

the above -wont- work for you. it's simply an outline
of what needs to be done. arctan only handles 0 to 180
(actually -pi/2 to pi/2 which is -90 to +90) so it
will only give you 12 of the 24 facings...

happy coding--Hawke'

new topic     » goto parent     » topic index » view message » categorize

5. Re: Help with "facing" routine

On Tue, 30 Jun 1998 17:26:40 -0700 Hawke <mdeland at NWINFO.NET> writes:
>Einar Mogen wrote:
>>I have a total of 24 facings, the first
>>one being directly up, the second 15 degrees to the right,
>>the second <third> 30 degrees to the right, and so on.
>
>i see a few things that are problems so far...
>since you mention 'the first one being up' i'll assume
>you are working in 3d??? no? if you are then 24 facings

Don't take this the wrong way:
Wrong!
:)

The game (I assume it's a game) is in 2d, with "up" being the direction
at the top of the monitor. (Facing north, top down game.)

Go download Hayes. :) Face the character to the top of the screen. How do
you know that's North? You don't, "up" is just the easiest term, (that I
can come up with, anyway), because the it actually is facing up, unless
your monitor is sideways or something. :)

>now if it is 2d, the routines become easier, rounding will
>work, and 0 versus 360 wont matter. :)
>(i -say- easier...;) )
>
>function determine_facing(sequence char_pos, sequence point)
>   -- find the closest match of the 24 possibilites
>   -- format: char_pos = {x,y} point = {x,y}
>   --         facing = -pi/2 to pi/2 radians
>   constant xi = 1 --X axis index
>   constant yi = 2 --Y axis index
>   atom facing
>   --compute rise/run AKA opposite/adjacent
>   facing = (char_pos[yi]-point[yi]) / (char_pos[xi]-point[xi])
>   --find angle in radians
>   facing = arctan( facing )
>   return facing
>end function
>
>the above -wont- work for you. it's simply an outline
>of what needs to be done. arctan only handles 0 to 180
>(actually -pi/2 to pi/2 which is -90 to +90) so it
>will only give you 12 of the 24 facings...

Actually, if it works for 2d, it will work for him. If it works, it'll
also work for me.... :) (Need similar code for my 2d game.. It's in space
so up is relative. ;)

_____________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

new topic     » goto parent     » topic index » view message » categorize

6. Re: Help with "facing" routine

Robert B Pilkington wrote:
> >i see a few things that are problems so far...
> >since you mention 'the first one being up' i'll assume
> >you are working in 3d??? no? if you are then 24 facings
>
> Don't take this the wrong way:
> Wrong!
> :)
>
> The game (I assume it's a game) is in 2d, with "up" being the direction
>top of monitor
thankee kind sir :) up was throwing me...i kept thinking 'forwards'
...heh

> >the above -wont- work for you. it's simply an outline
> >of what needs to be done. arctan only handles 0 to 180
> >(actually -pi/2 to pi/2 which is -90 to +90) so it
> >will only give you 12 of the 24 facings...
>
> Actually, if it works for 2d, it will work for him. If it works, it'll
> also work for me.... :)
don't take this the wrong way:
not!
:)
that function will not do as he asks...namely giving *24* directions.
the other half of the potential facings is *missing*, giving only 12.
you would have to flip the sign of the x or y axis to get the other
half.

new topic     » goto parent     » topic index » view message » categorize

7. Re: Help with "facing" routine

>> >the above -wont- work for you. it's simply an outline
>> >of what needs to be done. arctan only handles 0 to 180
>> >(actually -pi/2 to pi/2 which is -90 to +90) so it
>> >will only give you 12 of the 24 facings...
>>
>> Actually, if it works for 2d, it will work for him. If it works,
>> it'll also work for me.... :)

>don't take this the wrong way:
>not!
>:)
>that function will not do as he asks...namely giving *24* directions.
>the other half of the potential facings is *missing*, giving only 12.
>you would have to flip the sign of the x or y axis to get the other
>half.

I said "IF it works".. :) Besides, it had constant delcarations inside
the function. That's illegal. :)

Oh well, that's what I get for not reading everything completely... :/

_____________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

new topic     » goto parent     » topic index » view message » categorize

8. Re: Help with "facing" routine

Here's a bit of code that I wrote for Mark Honnor a while back, which
just happens to do exactly what you ask - even to the 360/24 degree
sections!  It should be fairly fast, because it uses no trig functions,
only a divide and tons of if's.

--code begins--
function determine_facing(sequence char_pos, sequence point)
    -- find the closest match of the 24 possibilites

atom invtan, dx, dy
dx = point[1] - char_pos[1]
dy = point[2] - char_pos[2]

if dx = 0 then
  if dy < 0 then
    -- 90
    return 1
  else
    -- 270
    return 13
  end if
else
  invtan = dy / dx
  if dx > 0 then
    if invtan > 7.595754113 then
      -- 90
      return 1
    elsif invtan > 2.414213562 then
      -- 75
      return 2
    elsif invtan > 1.303225373 then
      -- 60
      return 3
    elsif invtan > 0.767326988 then
      -- 45
      return 4
    elsif invtan > 0.4142135624 then
      -- 30
      return 5
    elsif invtan > 0.1316524976 then
      -- 15
      return 6
    elsif invtan > -0.1316524976 then
      -- 0
      return 7
    elsif invtan > -0.4142135624 then
      -- 345
      return 8
    elsif invtan > -0.767326988 then
      -- 330
      return 9
    elsif invtan > -1.303225373 then
      -- 315
      return 10
    elsif invtan > -2.414213562 then
      -- 300
      return 11
    elsif invtan > -7.595754113 then
      -- 285
      return 12
    else
      -- 270
      return 13
    end if
  else
    if invtan > 7.595754113 then
      -- 270
      return 13
    elsif invtan > 2.414213562 then
      -- 255
      return 14
    elsif invtan > 1.303225373 then
      -- 240
      return 15
    elsif invtan > 0.767326988 then
      -- 225
      return 16
    elsif invtan > 0.4142135624 then
      -- 210
      return 17
    elsif invtan > 0.1316524976 then
      -- 195
      return 18
    elsif invtan > -0.1316524976 then
      -- 180
      return 19
    elsif invtan > -0.4142135624 then
      -- 165
      return 20
    elsif invtan > -0.767326988 then
      -- 150
      return 21
    elsif invtan > -1.303225373 then
      -- 135
      return 22
    elsif invtan > -2.414213562 then
      -- 120
      return 23
    elsif invtan > -7.595754113 then
      -- 105
      return 24
    else
      -- 90
      return 1
    end if
  end if
end if
end function
-- code ends--

Later,
--
                  _____         _____        _____
   ________      /\    \       /\    \      /\    \
  /   \    \    /  \____\     /  \____\    /  \____\
 /  _  \____\  /   / ___/_   /   /____/   /   / ___/_
/  / \  |____|/   / /\____\ /    \    \  /   / /\____\
\  \_/ /    / \   \/ / ___/_\     \    \ \   \/ / ___/_
 \    /____/   \    / /\    \\/\   \    \ \    / /\    \
  \   \    \    \   \/  \____\  \   \    \ \   \/  \____\
   \   \    \    \      /    /   \   \____\ \      /    /
    \   \____\    \    /    /     \  /    /  \    /    /
     \  /    /     \  /    /       \/____/    \  /    /
      \/____/       \/____/xseal at harborside.com\/____/

new topic     » goto parent     » topic index » view message » categorize

9. Re: Help with "facing" routine

One or two more symmetries could be explored to further reduce the code
size, but I doubt it would result in any speed increase. Enjoy. Jiri


function determine_facing(sequence char_pos, sequence point)
    integer dx,dy,i
    atom raw_t,t
    dx=point[1]-char_pos[1]
    dy=point[2]-char_pos[2]
    if dy then                      -- if dy!=0
        raw_t=-dx/dy
        if raw_t>0 then t=raw_t else t=-raw_t end if
        -- 1st quadrant
        if t<0.1317 then i=1        -- tan( 7.5 deg)
        elsif t<0.4142 then i=2     -- tan(22.5 deg)
        elsif t<0.7673 then i=3     -- tan(37.5 deg)
        elsif t<1.3032 then i=4     -- tan(52.5 deg)
        elsif t<2.4142 then i=5     -- tan(67.5 deg)
        elsif t<7.5958 then i=6     -- tan(82.5 deg)
        else i=7
        end if
        if raw_t<0 then             -- 2nd or 4th quadrant
            if dy>0 then i=14-i     -- 2nd quadrant
            else                    -- 4th quadrant
                i=26-i
                if i=25 then i=1 end if
            end if
        elsif dy>0 then i=12+i      -- 3rd quadrant
        end if
    elsif dx>0 then i=7     -- horizontal, facing right
    else i=19               -- horizontal, facing left (or undetermined)
    end if
    return i
end function

-----Original Message-----
From: Einar Mogen <nord.staernes at ROLLAG.MAIL.TELIA.COM>
To: EUPHORIA at cwisserver1.mcs.muohio.edu
<EUPHORIA at cwisserver1.mcs.muohio.edu>
Date: Wednesday, 1 July 1998 10:45
Subject: Help with "facing" routine


>I would like some help on a function that should work like this:
>
>I pass it two sequences, the first one containing the coordinates of the
>active character, the second one containg the coordinates of the point that
>the active character should look at. I have a total of 24 facings, the
first
>one being directly up, the second 15 degrees to the right, the second 30
>degrees to the right, and so on. They are indexed 1-24. The function is
>supposed to return the facing index that most closely matches the character
>looking towards the point. If anyone out there which is more stable at
>mathematics like this could help me with the routine (it should be as fast
>as possible, since it will be called many times each frame of the game)
then
>I would be very grateful. I've started working on it, but now I'm both lazy
>and tired, and I'm not too keen on this kind of mathematics. Following is
an
>outline of the function:
>
>function determine_facing(sequence char_pos, sequence point)
>    -- find the closest match of the 24 possibilites
>    return facing -- 1 to 24
>end function
>
>Any help is greatly appreciated, the main thing I'm out for is the fastest
>way to find the angle which the point is at, relative to the character,
>either in degrees (or radians) or even better expressed with the indexes.
>
>Einar (who hopes his english is not _totally_ hopeless)
>

new topic     » goto parent     » topic index » view message » categorize

10. Re: Help with "facing" routine

I would like to thank for all help with this routine, now it works
perfectly. I have not decided which routine to use yet, I will have to speed
test them first. Right now I use the one given by Jiri because it has the
least lines of code.

There is one thing in the mail from Lithex I would like to point out:

> function Int(object x) return(x-remainder(x,1)) end function

Instead, you can just use the built-in floor(). Probably faster.

Einar

new topic     » goto parent     » topic index » view message » categorize

11. Re: Help with "facing" routine

At 05:16 PM 7/1/98 +0200, you wrote:
>I would like to thank for all help with this routine, now it works
>perfectly. I have not decided which routine to use yet, I will have to speed
>test them first. Right now I use the one given by Jiri because it has the
>least lines of code.
>
>There is one thing in the mail from Lithex I would like to point out:
>
>> function Int(object x) return(x-remainder(x,1)) end function
>
>Instead, you can just use the built-in floor(). Probably faster.
>
>Einar
>

They're a bit different.  Floor always rounds down, while int always rounds
towards 0, so:

floor({1.2,-1.2})  =>  {1,-2}
int({1.2,-1.2})    =>  {1,-1}

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu