Link to home
Start Free TrialLog in
Avatar of dbrckovi
dbrckoviFlag for Croatia

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!
Avatar of Arthur_Wood
Arthur_Wood
Flag of United States of America image

transform the Box location into a coordinate system centered on the Robot

    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
SOLUTION
Avatar of Eduski
Eduski

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ozo
angle to box:

atan2(By-Ry,Bx-Rx)
Avatar of dbrckovi

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)
BTW.
Origin point and the direction in which angle is increased (clockwise/counter-clockwise) 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!
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
'------------------------------------------------------------------------