# I Using trigonometry to create a radar for a game.

1. Jun 4, 2017

### Mr. Fizzix

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));

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. Jun 4, 2017

### SlowThinker

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].

3. Jun 4, 2017

### Mr. Fizzix

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));
}
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.

4. Jun 4, 2017

### Mr. Fizzix

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.

5. Jun 4, 2017

### SlowThinker

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.

6. Jun 4, 2017

### Staff: Mentor

They look like this:
[code=c]
[/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));
}
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;

7. Jun 4, 2017

9. Jun 4, 2017

### 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
10. Jun 5, 2017

### Mr. Fizzix

You're absolutely right. Thank you for that. And yes, I meant C#.

Last edited by a moderator: Jun 5, 2017