dbrckovi
asked on
Coordinate system (distance, angles and similar)
Hi!
I am trying to create a small 2D game where I have a field of dimensions 1000x1000 units.
On this field I have a robot and a box.
Robot is defined by its coordinates (in field units) and the direction where it is looking (in degrees).
- for example: RobotPositionX = 323, RobotPositionY = 476, RobotDirection = 43 (RX, RY, RD - to make it simple)
Box is defined only by its coordinates: BoxPositionX, BoxPositionY (BX, BY)
The robot has the field of view of 90 degrees. Which means, it can see 45 degrees to the left and 45 degrees to the right.
I would like to know the following:
- can the robot see the box: YES or NO.
- where on its view is the box: from -45 to +45 degrees, where 0 means that the box is right in front of it, -34 means it is on robot's left side.
- how far is the box
Now some more information which might or might not be usefull:
- origin point of coordinate system is at top-left point of playfield
- when robot's direction is set to 0 degrees, it is looking towards north (up)
- degrees are increasing clockwise which means when RD = 90, robot is looking towards East
Example:
RX = 800
RY = 900
RD = 315 degrees
BX = 400
BY = 800
would look something like this:
(0,0)
-------------------------- ---------- ---------- ------
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 0 |
| box ^ |
| ----------- * |
| robot ^ |
-------------------------- ---------- ---------- ------
(1000,1000)
Results would be:
Box visible : YES
Where is the box: 35 degrees to the left OR -35 ( I made 35 up, but I belive it is somewhere around )
Distance from box: 650 ( I also made this up )
Can someone show me how can I calculate the results from the given coordinates?
Some may think this is a homework assignmend, if so then please give me at least some theory on how I can get what I need.
Maybe, before few years I could get this myself, but I forgot all trigonomertical functions (distance between two points, etc.), so can you give me
the functions which I would need for solving this?
Thanks!
I am trying to create a small 2D game where I have a field of dimensions 1000x1000 units.
On this field I have a robot and a box.
Robot is defined by its coordinates (in field units) and the direction where it is looking (in degrees).
- for example: RobotPositionX = 323, RobotPositionY = 476, RobotDirection = 43 (RX, RY, RD - to make it simple)
Box is defined only by its coordinates: BoxPositionX, BoxPositionY (BX, BY)
The robot has the field of view of 90 degrees. Which means, it can see 45 degrees to the left and 45 degrees to the right.
I would like to know the following:
- can the robot see the box: YES or NO.
- where on its view is the box: from -45 to +45 degrees, where 0 means that the box is right in front of it, -34 means it is on robot's left side.
- how far is the box
Now some more information which might or might not be usefull:
- origin point of coordinate system is at top-left point of playfield
- when robot's direction is set to 0 degrees, it is looking towards north (up)
- degrees are increasing clockwise which means when RD = 90, robot is looking towards East
Example:
RX = 800
RY = 900
RD = 315 degrees
BX = 400
BY = 800
would look something like this:
(0,0)
--------------------------
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 0 |
| box ^ |
| ----------- * |
| robot ^ |
--------------------------
(1000,1000)
Results would be:
Box visible : YES
Where is the box: 35 degrees to the left OR -35 ( I made 35 up, but I belive it is somewhere around )
Distance from box: 650 ( I also made this up )
Can someone show me how can I calculate the results from the given coordinates?
Some may think this is a homework assignmend, if so then please give me at least some theory on how I can get what I need.
Maybe, before few years I could get this myself, but I forgot all trigonomertical functions (distance between two points, etc.), so can you give me
the functions which I would need for solving this?
Thanks!
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
angle to box:
atan2(By-Ry,Bx-Rx)
atan2(By-Ry,Bx-Rx)
ASKER
Thank you guys for responding, but I can't figure out what angle to box result represents.
I can't figure its logic. I mean. When I move my robot around, angle is not what I expect it to be.
I'll explain later:
This is the code written in Visual Basic which I am using at the moment. ( You just need a large picture box and a command button)
'------------------------- ---------- ---------- ---------- ---------- ---------- ---
Private Const PI = 3.1416 'Define PI
Private Sub Command1_Click()
Dim RX As Double 'Define required variables
Dim RY As Double
Dim RD As Double
Dim BX As Double
Dim BY As Double
Dim ax As Double
Dim ay As Double
Dim Distance As Double
Dim IntAngle As Double
Dim Visible As Boolean
RX = 100 'set values
RY = 100
RD = 0
BX = 200
BY = 200
Call DrawItems(RX, RY, RD, BX, BY) 'jump to DrawItems subroutine
ax = BX - RX 'I couldn't use bX becouse VB is not case sensitive
ay = BY - RY
Distance = Sqr(ax ^ 2 + ay ^ 2) 'works fine
IntAngle = Atn(ay / (ax ^ 2 + ay ^ 2)) 'I can't figure out what the results represent
'IntAngle = Atn((BY - RY) / (BX - RX)) - 45
Print "Distance: " & Format(Distance)
Print "Angle: " & Format(IntAngle)
If IntAngle >= -45 And IntAngle <= 45 Then
Visible = True
Print "Visible"
Else
Visible = False
Print "Not visible"
End If
End Sub
Sub DrawItems(RX As Double, RY As Double, RD As Double, BX As Double, BY As Double)
Dim X1Temp As Double 'some temporary variables used to hold coordinates of robots field-of-view arc
Dim Y1Temp As Double
Dim X2Temp As Double
Dim Y2Temp As Double
X1Temp = 25 * Cos((RD - 45) / 180 * PI) 'calculate coordinates of field-of-view arc
Y1Temp = 25 * Sin((RD - 45) / 180 * PI)
X2Temp = 25 * Cos((RD + 45) / 180 * PI)
Y2Temp = 25 * Sin((RD + 45) / 180 * PI)
Picture1.Refresh
'robot
Picture1.Circle (RX, RY), 10, vbRed 'draw robot
Picture1.Line (RX, RY)-(X1Temp + RX, Y1Temp + RY), vbRed 'draw robots arc (FOV)
Picture1.Line (RX, RY)-(X2Temp + RX, Y2Temp + RY), vbRed
'box
Picture1.Circle (BX, BY), 10, vbBlue 'draw box
End Sub
'------------------------- ---------- ---------- ---------- ---------- ---------- ---------- --
Since coordinate system origin is at upper-left corner of the picture box (play field), this means that positive X axis is pointing right,
and positive Y axis is pointing down.
When robots viewing angle is 0, it is looking to the right.
OK. Now when I set the following values:
RX = 100
RY = 100
RD = 0
BX = 200
BY = 200
I get something like this:
_ -
_--
R_
--_
-
B
Now I would expect angle to box to be 45 (right?), but Arthur_Wood's algorythm returns 4,99995833395832E-03, Eduski's algorythm returns -44,21
When I now move the robot around the box (without changing the view direction(RD)), I get strange results:
I won't draw each of them, I'll just provide values. Note that box is allways at 200,200.
-------------------------- --------
RX = 100
RY = 200
Arthur's algorythm: 0
Eduski's algorythm: -45
I would expect: 0
-------------------------- --------
RX = 100
RY = 300
Arthur's algorythm: 4,99995833395832E-03
Eduski's algorythm: -45.78
I would expect: -45 OR 315
-------------------------- --------
RX = 200
RY = 300
Arthur's algorythm: -9,99996696542E-03
Eduski's algorythm: Division by zero error
I would expect: -90 OR 270
-------------------------- --------
RX = 300
RY = 300
Arthur's algorythm: -4,99995833395832E-03
Eduski's algorythm: -44.21
I would expect: -135 OR 225
-------------------------- --------
RX = 300
RY = 200
Arthur's algorythm: 0
Eduski's algorythm: 45
I would expect: -180 OR 180
-------------------------- --------
Can you figure out what is wrong, or can you tell me what result of your function represents (radians, degrees, why isn't it changing correctly)?
ozo
I think your example is the function from some other programming language (C if I'm not mistaking) so it doesn't work in VB. (Although, I don't see how arctangent can recieve 2 values)
I can't figure its logic. I mean. When I move my robot around, angle is not what I expect it to be.
I'll explain later:
This is the code written in Visual Basic which I am using at the moment. ( You just need a large picture box and a command button)
'-------------------------
Private Const PI = 3.1416 'Define PI
Private Sub Command1_Click()
Dim RX As Double 'Define required variables
Dim RY As Double
Dim RD As Double
Dim BX As Double
Dim BY As Double
Dim ax As Double
Dim ay As Double
Dim Distance As Double
Dim IntAngle As Double
Dim Visible As Boolean
RX = 100 'set values
RY = 100
RD = 0
BX = 200
BY = 200
Call DrawItems(RX, RY, RD, BX, BY) 'jump to DrawItems subroutine
ax = BX - RX 'I couldn't use bX becouse VB is not case sensitive
ay = BY - RY
Distance = Sqr(ax ^ 2 + ay ^ 2) 'works fine
IntAngle = Atn(ay / (ax ^ 2 + ay ^ 2)) 'I can't figure out what the results represent
'IntAngle = Atn((BY - RY) / (BX - RX)) - 45
Print "Distance: " & Format(Distance)
Print "Angle: " & Format(IntAngle)
If IntAngle >= -45 And IntAngle <= 45 Then
Visible = True
Print "Visible"
Else
Visible = False
Print "Not visible"
End If
End Sub
Sub DrawItems(RX As Double, RY As Double, RD As Double, BX As Double, BY As Double)
Dim X1Temp As Double 'some temporary variables used to hold coordinates of robots field-of-view arc
Dim Y1Temp As Double
Dim X2Temp As Double
Dim Y2Temp As Double
X1Temp = 25 * Cos((RD - 45) / 180 * PI) 'calculate coordinates of field-of-view arc
Y1Temp = 25 * Sin((RD - 45) / 180 * PI)
X2Temp = 25 * Cos((RD + 45) / 180 * PI)
Y2Temp = 25 * Sin((RD + 45) / 180 * PI)
Picture1.Refresh
'robot
Picture1.Circle (RX, RY), 10, vbRed 'draw robot
Picture1.Line (RX, RY)-(X1Temp + RX, Y1Temp + RY), vbRed 'draw robots arc (FOV)
Picture1.Line (RX, RY)-(X2Temp + RX, Y2Temp + RY), vbRed
'box
Picture1.Circle (BX, BY), 10, vbBlue 'draw box
End Sub
'-------------------------
Since coordinate system origin is at upper-left corner of the picture box (play field), this means that positive X axis is pointing right,
and positive Y axis is pointing down.
When robots viewing angle is 0, it is looking to the right.
OK. Now when I set the following values:
RX = 100
RY = 100
RD = 0
BX = 200
BY = 200
I get something like this:
_ -
_--
R_
--_
-
B
Now I would expect angle to box to be 45 (right?), but Arthur_Wood's algorythm returns 4,99995833395832E-03, Eduski's algorythm returns -44,21
When I now move the robot around the box (without changing the view direction(RD)), I get strange results:
I won't draw each of them, I'll just provide values. Note that box is allways at 200,200.
--------------------------
RX = 100
RY = 200
Arthur's algorythm: 0
Eduski's algorythm: -45
I would expect: 0
--------------------------
RX = 100
RY = 300
Arthur's algorythm: 4,99995833395832E-03
Eduski's algorythm: -45.78
I would expect: -45 OR 315
--------------------------
RX = 200
RY = 300
Arthur's algorythm: -9,99996696542E-03
Eduski's algorythm: Division by zero error
I would expect: -90 OR 270
--------------------------
RX = 300
RY = 300
Arthur's algorythm: -4,99995833395832E-03
Eduski's algorythm: -44.21
I would expect: -135 OR 225
--------------------------
RX = 300
RY = 200
Arthur's algorythm: 0
Eduski's algorythm: 45
I would expect: -180 OR 180
--------------------------
Can you figure out what is wrong, or can you tell me what result of your function represents (radians, degrees, why isn't it changing correctly)?
ozo
I think your example is the function from some other programming language (C if I'm not mistaking) so it doesn't work in VB. (Although, I don't see how arctangent can recieve 2 values)
ASKER
BTW.
Origin point and the direction in which angle is increased (clockwise/counter-clockwi se) is not so important.
I would just like the robot's internal viewing andle to make a full 0-360 "circle" when I move it around the box and it is viewing in the same direction (0).
Thanks in advance.
Another BTW.
I remember one method which I think should work, but I am unable to implement it, becouse I forgot few important trigonometrical functions, and can't find them anywhere.
The method is as follows: (sorry for bad english)
- draw a line from the robot's coordinates towards its viewing direction, and in oposite direction (line1)
- draw a line2 which goes through Box'es coordinates, and "cuts" line1 at 90 degrees
- draw a line 3 which goes through both (robot's and box'es) coordinates
- now we have a triangle, where one angle is 90 degrees
If I could manage to calculate the coordinates of that third point, I could do the rest my self, but I'm having difficulties:
If I remember correctly, the explicit function for a line in coordinate system is: Y = A * X + B where A is the "koeficient of direction" (at least in my language), and B is the horizontal offset.
To get the line which cuts first line at 90 degrees, we have to do 1/A, and use this as a "direction koeficient" in another line.
To get B2 (offset of second line), we have to do B2 = Y2 - 1/A1 * X2.
Is everything above correct?
So I guess all I need is:
- how to translate the robots view angle (in degrees) to line's direction koeficient?
- how do I get the function of a line (A (koeficient) and B (offset)) which draws the line through two points? (between robot and a box)
(maybe all of this is not required at this moment, but it will be usefull to me later in my program)
Thanks again!
Origin point and the direction in which angle is increased (clockwise/counter-clockwi
I would just like the robot's internal viewing andle to make a full 0-360 "circle" when I move it around the box and it is viewing in the same direction (0).
Thanks in advance.
Another BTW.
I remember one method which I think should work, but I am unable to implement it, becouse I forgot few important trigonometrical functions, and can't find them anywhere.
The method is as follows: (sorry for bad english)
- draw a line from the robot's coordinates towards its viewing direction, and in oposite direction (line1)
- draw a line2 which goes through Box'es coordinates, and "cuts" line1 at 90 degrees
- draw a line 3 which goes through both (robot's and box'es) coordinates
- now we have a triangle, where one angle is 90 degrees
If I could manage to calculate the coordinates of that third point, I could do the rest my self, but I'm having difficulties:
If I remember correctly, the explicit function for a line in coordinate system is: Y = A * X + B where A is the "koeficient of direction" (at least in my language), and B is the horizontal offset.
To get the line which cuts first line at 90 degrees, we have to do 1/A, and use this as a "direction koeficient" in another line.
To get B2 (offset of second line), we have to do B2 = Y2 - 1/A1 * X2.
Is everything above correct?
So I guess all I need is:
- how to translate the robots view angle (in degrees) to line's direction koeficient?
- how do I get the function of a line (A (koeficient) and B (offset)) which draws the line through two points? (between robot and a box)
(maybe all of this is not required at this moment, but it will be usefull to me later in my program)
Thanks again!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much.
This was very helpful. I didn't think of that approach. I had the 90deg triangle all the time (X and Y axis), I just didn't see it.
If anyone is interested, this is what I managed to do from all of it (Visual Basic):
'------------------------- ---------- ---------- ---------- ---------- ---------
Private Const PI = 3.1416
Private Sub Command1_Click()
Dim RX As Double
Dim RY As Double
Dim RD As Double
Dim BX As Double
Dim BY As Double
Dim ax As Double
Dim ay As Double
Dim Distance As Double
Dim IntAngle As Double
Dim Visible As Boolean
RX = Val(txtRX.Text)
RY = Val(txtRY.Text)
RD = Val(txtRD.Text) - 90 'adjust angle so 0 points up
If RD < 0 Then RD = 360 + RD
BX = Val(txtBX.Text)
BY = Val(txtBY.Text)
Call DrawItems(RX, RY, RD, BX, BY)
ax = BX - RX
ay = BY - RY
Distance = Sqr(ax ^ 2 + ay ^ 2)
If BX = RX Then
If BY < RY Then IntAngle = 270
If BY > RY Then IntAngle = 90
Else
IntAngle = Round(Atn(ay / ax) * 180 / PI)
End If
If BY >= RY And BX > RX Then IntAngle = IntAngle 'right-front
If BY < RY And BX > RX Then IntAngle = 360 + IntAngle 'right-behind
If BY <= RY And BX < RX Then IntAngle = 180 + IntAngle 'left-behind
If BY > RY And BY < RX Then IntAngle = 180 + IntAngle 'left-front
IntAngle = IntAngle - RD
If IntAngle < 0 Then IntAngle = 360 + IntAngle
txtDistance.Text = Format(Distance)
txtIntAngle.Text = Format(IntAngle)
If IntAngle >= 315 Or IntAngle <= 45 Then
Visible = True
txtVisible.Text = "YES"
Else
Visible = False
txtVisible.Text = "NO"
End If
End Sub
Sub DrawItems(RX As Double, RY As Double, RD As Double, BX As Double, BY As Double)
Dim X1Temp As Double
Dim Y1Temp As Double
Dim X2Temp As Double
Dim Y2Temp As Double
X1Temp = 25 * Cos((RD - 45) / 180 * PI)
Y1Temp = 25 * Sin((RD - 45) / 180 * PI)
X2Temp = 25 * Cos((RD + 45) / 180 * PI)
Y2Temp = 25 * Sin((RD + 45) / 180 * PI)
'robot
Picture1.Refresh
Picture1.Circle (RX, RY), 10, vbRed
Picture1.Line (RX, RY)-(X1Temp + RX, Y1Temp + RY), vbRed
Picture1.Line (RX, RY)-(X2Temp + RX, Y2Temp + RY), vbRed
'box
Picture1.Circle (BX, BY), 10, vbBlue
End Sub
'------------------------- ---------- ---------- ---------- ---------- -------
This was very helpful. I didn't think of that approach. I had the 90deg triangle all the time (X and Y axis), I just didn't see it.
If anyone is interested, this is what I managed to do from all of it (Visual Basic):
'-------------------------
Private Const PI = 3.1416
Private Sub Command1_Click()
Dim RX As Double
Dim RY As Double
Dim RD As Double
Dim BX As Double
Dim BY As Double
Dim ax As Double
Dim ay As Double
Dim Distance As Double
Dim IntAngle As Double
Dim Visible As Boolean
RX = Val(txtRX.Text)
RY = Val(txtRY.Text)
RD = Val(txtRD.Text) - 90 'adjust angle so 0 points up
If RD < 0 Then RD = 360 + RD
BX = Val(txtBX.Text)
BY = Val(txtBY.Text)
Call DrawItems(RX, RY, RD, BX, BY)
ax = BX - RX
ay = BY - RY
Distance = Sqr(ax ^ 2 + ay ^ 2)
If BX = RX Then
If BY < RY Then IntAngle = 270
If BY > RY Then IntAngle = 90
Else
IntAngle = Round(Atn(ay / ax) * 180 / PI)
End If
If BY >= RY And BX > RX Then IntAngle = IntAngle 'right-front
If BY < RY And BX > RX Then IntAngle = 360 + IntAngle 'right-behind
If BY <= RY And BX < RX Then IntAngle = 180 + IntAngle 'left-behind
If BY > RY And BY < RX Then IntAngle = 180 + IntAngle 'left-front
IntAngle = IntAngle - RD
If IntAngle < 0 Then IntAngle = 360 + IntAngle
txtDistance.Text = Format(Distance)
txtIntAngle.Text = Format(IntAngle)
If IntAngle >= 315 Or IntAngle <= 45 Then
Visible = True
txtVisible.Text = "YES"
Else
Visible = False
txtVisible.Text = "NO"
End If
End Sub
Sub DrawItems(RX As Double, RY As Double, RD As Double, BX As Double, BY As Double)
Dim X1Temp As Double
Dim Y1Temp As Double
Dim X2Temp As Double
Dim Y2Temp As Double
X1Temp = 25 * Cos((RD - 45) / 180 * PI)
Y1Temp = 25 * Sin((RD - 45) / 180 * PI)
X2Temp = 25 * Cos((RD + 45) / 180 * PI)
Y2Temp = 25 * Sin((RD + 45) / 180 * PI)
'robot
Picture1.Refresh
Picture1.Circle (RX, RY), 10, vbRed
Picture1.Line (RX, RY)-(X1Temp + RX, Y1Temp + RY), vbRed
Picture1.Line (RX, RY)-(X2Temp + RX, Y2Temp + RY), vbRed
'box
Picture1.Circle (BX, BY), 10, vbBlue
End Sub
'-------------------------
bX = BX - RX
bY = BY - RY
Distance to Box = sqrt(bX^2 + bY^2)
Angle to Box = ArcTan(bY/(bX^2 + bY^2)) in the coordinate system of the Robot
you should be able to take it from here.
AW