Using trigonometry to create a radar for a game.

In summary, the conversation discusses troubleshooting for a radar in a video game created using Game Maker Studio 2.0. The first part of the radar works perfectly, but the second part has some issues with the radius not staying constant. Suggestions are made to check for typos and implement arctan2(y,x) instead of arctan(y/x). The issue is resolved by fixing a second if statement that was causing the dot to move.
  • #1
Mr. Fizzix
13
0
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.
 
Mathematics news on Phys.org
  • #2
Mr. Fizzix said:
Code:
 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));
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].
 
  • Like
Likes Mr. Fizzix
  • #3
SlowThinker said:
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].

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.
 
  • #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.
 
  • #5
Mr. Fizzix said:
if (x <= 825)
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.
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.
 
  • Like
Likes Mr. Fizzix
  • #6
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:
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:
C:
if (obj_Radar.image_alpha != 0) image_alpha = 1;
else image_alpha = 0;
 
  • Like
Likes Mr. Fizzix
  • #7
SlowThinker said:
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.
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.
 
  • #8
Mark44 said:
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:
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:
C:
if (obj_Radar.image_alpha != 0) image_alpha = 1;
else image_alpha = 0;

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).
 
  • #9
Mr. Fizzix said:
I didn't know that about the = vs ==, but will look into that
By all means, do so. Putting = instead of == in an if statement is a very common mistake, and one that can produce surprising results.

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.

Mr. Fizzix said:
It is GML (game maker language, largely C$ based
Do you mean C#? There is C, C++, C#, but not C$.
 
Last edited:
  • Like
Likes RJLiberator and Mr. Fizzix
  • #10
Mark44 said:
By all means, do so. Putting = instead of == in an if statement is a very common mistake, and one that can produce surprising results.

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$.
You're absolutely right. Thank you for that. And yes, I meant C#.
 
Last edited by a moderator:

1. How does trigonometry play a role in creating a radar for a game?

Trigonometry is used to calculate the distance and angle between the player's location and the objects or enemies on the radar. This allows the radar to accurately display the location of the objects in relation to the player.

2. What trigonometric functions are used in creating a radar for a game?

The main trigonometric functions used are sine, cosine, and tangent. These functions are used to calculate the angles and distances between the player and the objects on the radar.

3. How is the radar display created using trigonometry?

The radar display is created by using the calculated angles and distances to plot the objects on a circular or rectangular grid. The player's location is usually displayed at the center of the grid.

4. Can trigonometry be used to create a 3D radar for a game?

Yes, trigonometry can be used to create a 3D radar by incorporating the third dimension (height) in the calculations. This allows for a more realistic and accurate radar display in games.

5. Is a strong understanding of trigonometry necessary for creating a radar in a game?

While a strong understanding of trigonometry is not necessary, it is beneficial for creating a more accurate and efficient radar. There are also many resources and tools available that can assist with the trigonometric calculations needed for a radar in a game.

Similar threads

  • Introductory Physics Homework Help
Replies
2
Views
2K
Replies
1
Views
3K
  • Calculus and Beyond Homework Help
Replies
7
Views
1K
Replies
1
Views
4K
  • Introductory Physics Homework Help
Replies
4
Views
5K
  • Linear and Abstract Algebra
Replies
4
Views
1K
  • Calculus and Beyond Homework Help
Replies
1
Views
1K
Replies
1
Views
967
  • Calculus and Beyond Homework Help
Replies
2
Views
3K
  • Introductory Physics Homework Help
Replies
3
Views
6K
Back
Top