Finding the direction to another object

This is a discussion on Finding the direction to another object within the Game Programming forums, part of the General Programming Boards category; OK, I need to find the direction to the closest player for the AI code in a game that I ...

  1. #1
    Person Man
    Guest

    Finding the direction to another object

    OK, I need to find the direction to the closest player for the AI code in a game that I am making. I thought you were supposed to use the atan2() function for that, but it doesn't work. The worm (that's what the AI is for) just keeps pointing downward or to the sides.
    Maybe I'm using the function wrong:

    playerDir = atan2( closestToMe->pos.x - pos.x,
    closestToMe->pos.y - pos.y);

    I've tried switching the x and the y, that didn't work. I'm expecting the function to return the direction in radians, that's how it works right? I'm using allegro and Dev-C++, don't think that matters. Please Help!

  2. #2
    Has a Masters in B.S.
    Join Date
    Aug 2001
    Posts
    2,267
    find the angle between them like so...

    acos((A dot B) / (|A| * |B|))
    ADVISORY: This users posts are rated CP-MA, for Mature Audiences only.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,497
    > I'm expecting the function to return the direction in radians, that's how it works right?
    It is.

    double atan2(double _y, double _x);
    So it should be
    playerDir = atan2 ( closestToMe->pos.y - pos.y, closestToMe->pos.x - pos.x );

    Hard to say what's happening - I tried a simple known case, and it seems to produce the right answers
    double a = atan2( 4, 3 );
    printf( "%f %f\n", a, a/M_PI*180 );

    I would suggest a bit of basic debug and test to make sure you've got the right idea.

    Also watch out for bad happenings when x and y are 0.0
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    Or, you could just do vector-based direction. In (x,y) coordinates you just do vector subtraction. It's not really harder to make code that uses a vector as the direction instead of an angle, and the math is often simpler when dealing with vectors in (x,y) space. Really, what you are doing is converting the vector into polar form (r, theta) and ignoring the r term. An easy way to implement vector-motion is just to normalize the vector:

    [x, y] = [x, y]/(sqrt(x^2 + y^2))

    Then you can just move the object in the direction of the vector by simple vector addition to the current position.

  5. #5
    Sayeh
    Guest
    Take 'V's' advice-- convert your stuff to vector math-- It is so very much simpler and easier to work with because many of the intangibles just go away. You get the benefit of higher math, calculus, and heavy analytical geometry, without having to really know it.

    And it makes your product easy to convert to 3 dimensions if you want.

  6. #6
    Registered User WebSnozz's Avatar
    Join Date
    Oct 2001
    Posts
    102
    When yall talk about vectors in programming, are these similar to vectors in physics where the value is represented as a scalar quantity times an I hat, J hat, or K hat, or a scalar quantity and an angle?
    WebSnozz-
    Cats have no butt cheeks.
    If one farted, then it would make a flute noise.

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    Well, every point is also a vector (from the origin to the point).

    You can do simple subtraction to get the vector between two points.

    So, say object "Player" is, in a 2D space, at (15,35) and "Enemy" is at (44,12). Then, the vector from "Player" to "Enemy" is (44 - 15, 12 - 35) or (29,-23). What this tells you is that to move from "Player" to "Enemy", you must move 29 units in the positive x direction, and 23 units in the negative y direction.

    Now, the length of a vector (sqrt(x^2 + y^2)) tells you the distance between the objects. If v is a vector, |v| is the notation for the vector's magnitude.

    A unit vector is obtained by taking a vector and dividing both components by the length of the vector -- this gives you a vector that is "one unit" long. Why is this handy? Say you want "Player" to move in the direction of "Enemy". The player should move at a specific speed -- so you get the vector from "Player" to "Enemy", get the correcponding unit vector (which has the same direction but length of 1) and then multiply by the number of units the character can move per turn. Call this the "movement vector"

    Now, you want to do the movement? It's as easy as adding the movement vector (the change in position) to the current position.

    Here's a simple example (numbers chosen for convenience, normally it's messier, but then, the PC is doing the math, not you).

    Player is at (25, 36). Enemy is at (325, 436) and the player is to move 15 units towards the enemy.

    Vector from player to enemy:
    (325 - 25, 436 - 36) = (300,400)

    Distance from player to enemy = sqrt(300^2 + 400^2) = 500

    Unit vector = (300/500, 400/500) = (0.6, 0.8)

    Movement vector = (0.6 * 15, 0.8 * 15) = (9,12)

    Final player position = (25 + 9, 36 + 12) = (34,48)

  8. #8
    Registered User WebSnozz's Avatar
    Join Date
    Oct 2001
    Posts
    102
    Thanks, sometimes it's hard to take what I learn in school and apply it to something useful since they are so abstract in the way they present it.
    WebSnozz-
    Cats have no butt cheeks.
    If one farted, then it would make a flute noise.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    22
    And you do have to remember that unless you specify otherwise, the coordinatized plane of a computer monitor is different from your normal e1-e2 axis'

    -Vulcan

  10. #10
    Sayeh
    Guest
    Plus, using vector math (dot product), it is easy to determine what side of a wall (plane) you are on by checking the angle of the normal against the intersection of the point of view (POV).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Telling a shared_ptr not to delete object?
    By TriKri in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2008, 04:26 AM
  2. A question about constructors...
    By Wolve in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2005, 04:24 PM
  3. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 13
    Last Post: 10-31-2002, 01:56 PM
  4. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2002, 07:40 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21