'-------------------------------------------------------------------------------
Option Explicit

'-------------------------------------------------------------------------------
Public Sub NormalizeVector( _
    ByRef Rx As Single, _
    ByRef Ry As Single)

' For a 2D vector whose X and Y components are known, the vector is scaled
' to a unit vector.
'
' If the original vector has zero length, it is transformed to a unit vector
' in the X direction.

    Dim Length As Single

    ' Singularity -- transform to a unit vector in the X direction.
    If (Rx = 0.0) And (Ry = 0.0) Then
        Rx = 1.0
    End If

    Length = Sqr(Rx * Rx + Ry * Ry)

    Rx = Rx / Length
    Ry = Ry / Length

End Sub
'-------------------------------------------------------------------------------
Public Function UnitVectorAngle( _
    ByVal Rx As Single, _
    ByVal Ry As Single) As Single

' For a unit vector R in the XY plane, determine angle between the vector
' and the X axis. The returned angle is a positive number in range
' 0.0 .. 2.0*Pi radians.
'
' Results are unpredictable if the vector is not a unit vector.

    Const Pi As Single = 3.141592654
    Const HalfPi As Single = 1.570796327
    Const TwicePi As Single = 6.283185307
    Const ThreePiOverTwo As Single = 4.71238898

    Dim AbsX As Single, AbsY As Single, Steep As Boolean
    Dim Angle As Single

    ' Vector is exactly vertical.
    if (Rx = 0.0) then
        if (Ry > 0.0) then
            UnitVectorAngle = HalfPi
        else
            UnitVectorAngle = ThreePiOverTwo
        end if
        Exit Function
    end if

    ' Vector is exactly horizontal.
    if (Ry = 0.0) then
        if (Rx > 0.0) then
            UnitVectorAngle = 0.0
        else
            UnitVectorAngle = Pi
        end if
        Exit Function
    end if

    AbsX = Abs(Rx)
    AbsY = Abs(Ry)

    Steep = (AbsY > AbsX)

    If (Steep) Then
        Angle = ACos(AbsX)
    Else
        Angle = ASin(AbsY)
    End If

    if (Rx > 0.0) then
        if (Ry > 0.0) then
            ' Quadrant 1
            ' null
        else
            ' Quadrant 4
            Angle = TwicePi - Angle
        end if
    else
        if (Ry > 0.0) then
            ' Quadrant 2
            Angle = Pi - Angle
        else
            ' Quadrant 3
            Angle = Pi + Angle
        end if
    end if

    UnitVectorAngle = Angle

End Function
'-------------------------------------------------------------------------------
