Jump to content

Help Calculating Rotation


hounder
 Share

Recommended Posts

I am working on a program that takes two coords from a 3D game (X and Y, Z not relevent), and calculates how far point A (current position) is from point B (target position). However, i am having problems calculating which direction the object on point A needs to be facing (in degrees) to get to point B. I know there is some formula for this, however, I'm clueless.

So lets say my current position in the game is X-996 and Y-1071 currently facing a value of 100 (from what i see rotation is measured on a -180 to 180 scale, north being -90, east being 180, south being 90 and west being 0) and my target location is X-985 Y-1133, how would i go about calculating the rotation at which i need to be facing in order to reach my target position?

Below is the function i am currently using, that doesnt seem to work. what it does is grabs the coords from the objects current position then reads "waypoints" or pre-defined target positions from the text file. after that it tries to calculate the rotation (which is wrong) and then moves in that position towards the target position.

Func _Turn()
    Local $Cur_Coords = _GetCoords()
    Local $Next_Coords = StringSplit(FileReadLine(@ScriptDir & "\waypoints.txt",$Cur_Waypoint), ",") ;split x, y, z, map
 
    ;-------------------------------------------
    Local $PosX = $Cur_Coords[0]-$Next_Coords[1];x
    Local $PosY = $Cur_Coords[1]-$Next_Coords[2];y
 
                $Next_Rot = _ATan2($Next_Coords[2] - $Cur_Coords[1], $Next_Coords[1] - $Cur_Coords[0]) * 180 / $Pi
 
 
    GUICtrlSetData($Input6, $Next_Coords[1])
    GUICtrlSetData($Input7, $Next_Coords[2])
    GUICtrlSetData($Input10, Floor($Next_Rot))
 
        $Cur_Rot = _GetRotation()
 
        If $Next_Rot = $Cur_Rot Then Return $Next_Rot
 
        While $Cur_Rot <> $Next_Rot And $Run
                $Cur_Rot = _GetRotation()
                _MouseMovePlus()
                GUICtrlSetData($Input5, Floor($Cur_Rot))
        WEnd
 
    Return $Next_Rot
EndFunc

any help much appreciated :D

Edited by hounder
Link to comment
Share on other sites

Hiya,

Try this, see how it works for you.

Func DistAndDir( $Ax, $Ay, $CurHeading, $Bx, $By, $OutDistance, $OutHdgChange)
        ;assume X is positive-right, Y is positive-down
        ;heading is weird, see further down.

    ;distance is simple Pythagoras...
    ;Distance-squared = X-difference-squared + Y-difference-squared
    Local $XDiff = $Ax - $Bx
    Local $YDiff = $Ay - $By
    Local $DistanceSquared = ($XDiff * $XDiff) + ($YDiff * $YDiff)
    $OutDistance = Sqrt($DistanceSquared)
    
    ;now let's work out the bearing, which is based on ATan of the X- and Y-differences
    ;and then resolved into the appropriate quadrant
    Const $TO_DEGREES = 180 / (4 * ATan(1))
    Local $QuadrantBearing = ATan($XDiff / $YDiff) * $TO_DEGREES
    Local $RealBearing
    If $Bx > $Ax Then   ;we need to head east-ish
        If $By > $Ay Then   ;we need to head southeast
            $RealBearing = 180 - $QuadrantBearing
        ElseIf $By = $Ay    ;we need to head pure east
            $RealBearing = 090
        Else                ;we need to head northeast
            $RealBearing = $QuadrantBearing
        EndIf
    ElseIf $Bx = $Ax    ;we need to head pure north/south
        If $By > $Ay Then   ;we need to head south
            $RealBearing = 180
        Else                ;it's north
            $RealBearing = 000
        EndIf
    Else                ;we need to head west-ish
        If $By > $Ay Then   ;we need to head southwest
            $RealBearing = 180 + $QuadrantBearing
        ElseIf $By = $Ay    ;we need to head pure west
            $RealBearing = 270
        Else                ;we need to head northwest
            $RealBearing = 360 - $QuadrantBearing
        EndIf
    EndIf
    
    ;and finally work out the change in heading, in game-heading terms
    $OutHdgChange = $CurHeading - _dad_RealHeadingToGameHeading($RealBearing)
    ;ensure it's in +/-180
    While $OutHdgChange >= 180 Do $OutHdgChange = $OutHdgChange - 360
    While $OutHdgChange < -180 Do $OutHdgChange = $OutHdgChange + 360

EndFunc

;Real heading   Game-heading
;   000             -90
;   090             +/-180
;   180             +90
;   270             000

Func _dad_GameHeadingToRealHeading( Const $GameHeading)
    Local $liResult
    $liResult = 270 - $GameHeading
    While $liResult >= 360 Do $liResult = $liResult - 360
    While $liResult < 0 Do $liResult = $liResult + 360
    Return $liResult
EndFunc
    
Func _dad_RealHeadingToGameHeading( Const $RealHeading)
    Local $liResult
    $liResult = -90 - $RealHeading
    While $liResult >= 180 Do $liResult = $liResult - 360
    While $liResult < -180 Do $liResult = $liResult + 360
    Return $liResult
EndFunc

Hope this helps,

RAC

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...