Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

I Using trigonometry to create a radar for a game.

  1. Jun 4, 2017 #1
    I am making a video game using Game Maker Studio 2.0 and am making a radar. To give you some background, one object is obj_Player, and the other is obj_Sub. The radar gives the sub's position and distance from the player (center of radar).

    The first part of my radar works perfect. I normalized the screen size to fit the radar size, and it shows the dots on the radar perfectly as long as the target is on screen. FYI, my radar is in bearing mode rather than angle mode, so it starts at 12 o'clock and sweeps clockwise, rather than a unit circle which starts at 3 and sweeps CCW.

    The second part of it, I have run into some trouble. I don't believe the program uses polar coordinates, so I am restricted to cartesian.The second part of it, if the target is offscreen, I want the dot to be on the edge of the radar and get bigger and bigger until the target comes on screen (at which point I have a working model for).

    The code I have is below, and executed every frame:
    x = obj_Radar.x + (sin(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));
    y = obj_Radar.y + (-cos(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));

    Where obj_Radar.x is the radar x center coordinate
    obj_Radar.y is the radar y center coordinate
    obj_Player.x is the player x coordinate
    obj_Player.y is the player y coordinate
    obj_Sub.x is the sub x coordinate
    obj_Sub.y is the y coordinate

    Basically, the first part of the equation (obj_Radar.x and obj_Radar.y), I am have it start at the center of the radar, then adding the necessary values.

    Now, you might be asking yourself "Why is he using sin for the x coordinate and not the y". That is because I am using a bearing and the course and direction is perpendicular to the radar's x and y system. But this may not be relevant for the trouble shooting I am doing.

    Anyway, I am looking for the radius to stay constant (at the edge of the radar), but to show the angle between the offscreen target and the player. For some reason that is beyond me, the radius doesn't stay constant.

    Inside the arctan function, you have the difference between the target and player's y divided by the difference between the target and player's x (opposite over adjacent), which should give me the angle of this triangle. I then take the sin / cos of it to give me y / x component of it and then multiple by the radius (0.65 * 139).

    So, can anyone tell me where I went wrong and why my radius is not constant here? Thank you very much.
     
  2. jcsd
  3. Jun 4, 2017 #2
    Is this copy&paste of the actual code? It sounds as if you have a typo in the code somewhere. Or maybe something is overwriting the result after you compute it.
    If you have sin(anything) and cos(the same anything), the point is always at distance 1 from the origin (or 0.65*139 from the center of the radar in your case).

    Also you may want to try and find something like arctan2(y,x) instead of arctan(y/x). Otherwise you should implement it yourself. The way it is written you risk division by zero, and cannot distinguish delta [1,1] from [-1,-1].
     
  4. Jun 4, 2017 #3
    First of all, thank you very much for the speedy, helpful reply. Here is the entire block of code, the //'s being comments. This is just the code for the dot on the radar, executed each step of the game (that is, every frame, at 30 frames per second).

    if (x > 825)
    {
    x = obj_Radar.x + (sin(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));
    y = obj_Radar.y + (-cos(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));
    }
    if (x <= 825)
    {
    x = obj_Radar.x + ((0.65 * 139/((((825)^2)+((440)^2))^0.5)) * (obj_Sub.y - obj_Player.y));
    y = obj_Radar.y + (-( 0.65 * 139/((((825)^2)+((440)^2))^0.5)) * (obj_Sub.x - obj_Player.x));
    }
    // coefficient is radar radius / room diagonal
    if (!obj_Radar.image_alpha = 0) image_alpha = 1;
    else image_alpha = 0;
    // x^2 + y ^2 = r^2
    // x = (r^2 - y^2)^0.5

    So, in this code, x will never be 0 in the arctan function, as it switches code once x crosses 825. The code for "if x <= 825" works perfectly. Those numbers on those lines of code basically rescale the room size to the radar size. Below that, I am just adjusting the transparency of the image, and below that have some comments that do not affect the code.

    I am with you, the radius should stay constant, but I cannot think of why it is not. Those two if statements should not both be executed, it should be one or the other. I will try your arctan2(x,y). Does that give me the square of arctan as well, or does the 2 mean that it just has two arguments? Thank you.
     
  5. Jun 4, 2017 #4
    You were right. Somehow my second if statement was moving the dot even though only the first one should have been on. I should be able to figure out the rest from here. The radius expands slightly as it goes from 12 to 6, not sure why, but it is workable now, and I should be able to fix it. Thank you very much. Not sure how to mark this thread as solved, but you helped me see it. Thank you.
     
  6. Jun 4, 2017 #5
    You may want to add an "else" before this test.
    Also what you're doing doesn't seem right but I guess you'll be able to figure it out.
    The 2 in arctan2 means it takes 2 arguments. I'm not sure what language you're using but it should be there somewhere.
     
  7. Jun 4, 2017 #6

    Mark44

    Staff: Mentor

    Please use code tags around your code.
    They look like this:
    [code=c]
    // your code goes here
    [/code]

    I have added code tags to your code below, and also indented it to make it more easilly understandable.
    Code (Text):
    if (x > 825)
    {
       x = obj_Radar.x + (sin(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));
       y = obj_Radar.y + (-cos(arctan((obj_Player.y - obj_Sub.y)/(obj_Sub.x - obj_Player.x))) * (0.65 * 139));
    }
    if (x <= 825)
    {
       x = obj_Radar.x + ((0.65 * 139/((((825)^2)+((440)^2))^0.5)) * (obj_Sub.y - obj_Player.y));
       y = obj_Radar.y + (-( 0.65 * 139/((((825)^2)+((440)^2))^0.5)) * (obj_Sub.x - obj_Player.x));
    }
    // coefficient is radar radius / room diagonal
    if (!obj_Radar.image_alpha = 0) image_alpha = 1;    // <-- Possible error here
    else image_alpha = 0;
    // x^2 + y ^2 = r^2
    // x = (r^2 - y^2)^0.5
    In the last if statement (I marked it with a comment), you might have a semantic error. I guess that your intent is to see whether obj_Radar.image_alpha is not equal to zero. That's not what the code is doing though. I'm not sure what language you're using, but it appears C-like. In C and all languages descended from it, = is only for assignment, == is for equality.
    If my suspicion is correct, the if statement would be clearer like this:
    Code (C):
    if (obj_Radar.image_alpha != 0) image_alpha = 1;
    else image_alpha = 0;
     
  8. Jun 4, 2017 #7
    I figured out what I did wrong. The if statement conditions should have had obj_Sub.x instead of just x. That is why I was getting if statements to run that I did not want to run. Once I changed that, it started working again. Thank you for clarifying. FYI, I am using GML (Game Maker Language) from Game Maker Studio 2, and it is largely C$ based.
     
  9. Jun 4, 2017 #8
    Thank you for that. I appreciate it. I am self-taught at writing code, picked it up at first 3 months ago (Excel VBA), so I don't know all the conventions but usually get by. I indeed did have those if statements indented just like that, but the copy paste didn't carry them over. I didn't know that about the = vs ==, but will look into that (so far, no problem with the image alpha working fine), and have seen =='s in this language. It is GML (game maker language, largely C$ based).
     
  10. Jun 4, 2017 #9

    Mark44

    Staff: Mentor

    By all means, do so. Putting = instead of == in an if statement is a very common mistake, and one that can produce surprising results.

    Code (C):

    int x = 3;
    if (x = 1) printf("What happened?");
    else printf("Not a surprise.");
     
    Output from this code: What happened?

    If the expression in parentheses is replaced by x == 1, the code produces more reasonable results.

    Do you mean C#? There is C, C++, C#, but not C$.
     
    Last edited: Jun 5, 2017
  11. Jun 5, 2017 #10
    You're absolutely right. Thank you for that. And yes, I meant C#.
     
    Last edited by a moderator: Jun 5, 2017
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted