; Vector:
;
;  Point 1
;
;     O 
;       `-_
;          '-_
;             `-_
;                '-_   ,
;                   `-_l
;                    _-'
;                        O
;
;                     Point 2
;
; This can be anything
; from calculation motion
; to drawing a simple line.
;
;          O  ---
;         /   /|\
;        /     |
;       /      | distance Y
;      /       |
;     /        |
;    /        \|/
;   O         ---
;
;   |<---->|
;
;  distance X
;
; It doesn't really matter
; where point 1 is
; compared to point 2.
;
; It can go in any direction.
;
;                :`
;                : `
;             1  ;  `
;                O  '  225 degrees
;               /   `
;              /   '
;   distance  / '''
;            /
;           /
;          /
;         O
;            2
;
; Going from point 1 to point 2
; means going in the direction of 225 degrees
; when 0 degrees means UP
; and clockwise means positive.
;
; Some people use anti-clockwise
; and 0 degrees means RIGHT.
;
; It's all up to the programmer :)
;
; So you can actually look at vectors
; in multiple ways.
;
;   Distance X  and  Distance Y
;
; or
;
;   Distance    and  Direction (angle)
;
; I've created 4 functions you can use
; to convert to/from each of these
; without breaking your head over maths.
;
;,,,,,,,,
        ;   Easy to use functions
    ;----
    ;
    ; For those of you (including me)
    ; who don't like doing all the maths
    ; every time and time again :P
    ;
    ;= Get horizontal size of vector using distance and angle

        Function VectorX# ( Distance# , Angle# )
            Return Sin ( Angle ) * Distance
        End Function

    ;= Get vertical size of vector using distance and angle

        Function VectorY# ( Distance# , Angle# )
            Return Sin ( Angle - 90 ) * Distance
        End Function

    ;= Get true length of a vector

        Function VectorDistance# ( X# , Y# )
            Return Sqr ( X * X + Y * Y )
        End Function

    ;= Get true angle of a vector

        Function VectorAngle# ( X# , Y# )
            Return -Atan2 ( X , Y ) + 180
        End Function
    ;
;----
;
; And here's how they work:
;
;   DistanceX = VectorX ( Distance , Angle )
;   DistanceY = VectorY ( Distance , Angle )
;
;   Distance = VectorDistance ( DistanceX , DistanceY )
;   Angle    = VectorAngle    ( DistanceX , DistanceY )
;
; Note that the orientation used
; in the functions is:
;
;   - clockwise
;   - 0 degrees means UP
;
; I've included 5 example programs
; to demonstrate the usage of the functions.
; E.g. to display that you can create
; entire games without complicated maths :)
;
; I've created functions out of the sections
; so you can just run each section
; without having to copy/paste
; everything to a new program.
;
; Here are the first 5 functions
; (name, description):
;
;   prog1   How vectors work
;   prog2   Motion using vectors (example 1)
;   prog3   Motion using vectors (example 2)
;   prog4   Space physics (example 1)
;   prog5   Space physics (example 2)
;
; If you want to dive deeper into
; how exactly Sin and Cos work,
; here's a number of more
; math intensive programs
; to demonstrate how they work.
;
;   sine1   What Sin and Cos look like
;   sine2   What values Sin has
;   sine3   Sin(a) = Cos(a - 90)
;   sine4   Simple vector example
;   sine5   Elaborate vector example
;   sine6   Circle
;   sine7   Rays
;
; If you only want to use the functions,
; here's the function call to try out
; a particular section.

prog1

; Below I'll explain more about
; how Sin and Cos work.
;
; First, some more vector
; orientation explanation
; found on BlitzCoder:
;
; There are different ways to use vectors.
; The most common vector is simply having an X and Y.
; These would be used to, for example, calculate a ship's displacement.
; Imagine a matrix or grid with (0,0) as the center.
; When visualizing, a vector would always be drawn from this point.
; Another way is to use Angle and Length.
; Angle would be the angle of the line from (0,0) to (X,Y).
; And Length being the actual distance between these points.
;
; The graph below displays:
;
;               T
;             *
;            /I
;           / I
;          /  I
;     v   /   I
;        /    I  y
;       /     I
;      /      I
;     /       I
;    /a       I
;   *---------*
; V             B
;        x
;
; Line VB represents the horizontal distance x
; Line BT represents the vertical distance y
; Line VT (v) represents the length of the vector
;   E.g. the combined of distance x and y
; Angle 'a' represents the angle of the vector
;
;                          X
; Native vector notation: ---
;                          Y
;
; Default pythagoras formula applies to this triangle: x^2 + y^2 = v^2
; There are also various Sin, Cos and Tan formulas to apply.
; Basically anything with trigonometry.
;
; The first section (prog1) is a representation of the above.
;
; Now, even though Sin and Cos are functions
; which calculate something for you,
; they should always return the same value
; when giving the same parameter.
;
; So you can basically look at them like
; arrays containing values.
;
; You can take a look at sine1
; (the program or function)
; to see what the values look like
; when you draw them.
;
; Program sine2 will display a table
; of exactly which values you get
; with which angles.
;
; Why not displaying a table
; with the values of Cos?
;
; Actually Sin and Cos have
; the exact same pattern, a sinewave.
;
; The only difference is where they begin.
; When you look at sine1 again,
; you'll see the phase difference.
;
; Sine3 will show you that
; you can use any phase or offset
; using only Sin.
;
; When you multiply the value
; from Sin/Cos you can get
; a distance of your choice.
;
; Normally the returned value
; is in range of [-1..1]
; e.g. max distance = 1.
;
; When looking at sine4
; you'll find that:
;
;   PosX = Sin ( Angle ) * Radius
;
; And when running sine5
; you might find that it's
; actually a lot like prog1.
;
; Finally there's sine6 which
; plots pixels on the path
; making a circle.
;
; And sine7 where lines
; are drawn towards the path
; creating rays from the center.
;
; Below you'll find all the code inside separated functions.

; Example of displaying a true vector
; ---------------------------------------------------------------------------- ;
; Move your mouse to alternate the vector

Function prog1 ()
    Graphics 640 , 480
    SetBuffer BackBuffer()  ; Double buffering, e.g. draw to invisible buffer and swap to visible when done

    X1 = GraphicsWidth() / 2   ; Center of screen is center of vector
    Y1 = GraphicsHeight() / 2  ;

    MoveMouse X1 + 100 , Y1 - 100  ; Put mouse in a spot to resemble the graph in the vector help

    Repeat  ; Main loop
      Cls  ; Clear screen each frame

      X2 = MouseX()  ; Use mouse for vector coordinates
      Y2 = MouseY()  ;

      Length = VectorDistance( X2-X1 , Y2-Y1 )  ; Calculate true length of the vector
      Angle = VectorAngle( X2-X1 , Y2-Y1 )  ; And true angle

      Color 0 , 127 , 255  ; Display relevant info
      Text 0 , 0 * FontHeight() , "X Length: " + (X2-X1)
      Text 0 , 1 * FontHeight() , "Y Length: " + (Y2-Y1)
      Text 0 , 2 * FontHeight() , "Vector Length: " + Length
      Text 0 , 3 * FontHeight() , "Vector Angle: " + Angle

      X2 = X1 + VectorX( Length , Angle )  ; REcalculate vector coordinates, to demonstrate using GetVector
      Y2 = Y1 + VectorY( Length , Angle )  ; The vector is drawn from center of screen

      Color 0 , 255 , 0
      Line X1 , Y1 , X2 , Y2  ; Draw vector line (v)

      Color 255 , 255 , 0
      Line X1 , Y1 , X2 , Y1  ; Draw the horizontal line (x)
      Line X2 , Y2 , X2 , Y1  ; Draw the vertical line (y)

      Flip  ; Using double buffering so, display all
    Until GetKey()  ; Until any ASCII keypress

    EndGraphics
    End
End Function

; Specific example for GetLength and GetAngle
; ---------------------------------------------------------------------------- ;
; Demonstrates 'ashies' (grey dots) floating around.

    Type Dot  ; Ashy
      Field PosX#  ; All ashies have unique positions
      Field PosY#  ;
      Field LastAngle%  ; And an angle to remember where they're going
      Field Color%  ; Also a color
    End Type

Function prog2 ()
    Graphics 640 , 480
    SetBuffer BackBuffer()
    SeedRnd MilliSecs()  ; Randomize

          TotalDots = 100  ; Total number of dots to create

    Local Dot.Dot  ; Creating a collection of dots

    For Counter = 1 To TotalDots  ; Creating the dolly dots
      Dot = New Dot
      Dot\PosX = Rnd( 0 , GraphicsWidth() )   ; Random position on screen
      Dot\PosY = Rnd( 0 , GraphicsHeight() )  ;
      Dot\LastAngle = Rnd( 0 , 359 )  ; Random direction to begin with
      Dot\Color = Rnd( 64 , 255 )  ; And a random color (grey shade)
    Next

    Repeat
      Cls
      For Dot = Each Dot  ; Iterate through all dots

        Repeat
          IncX# = Rnd( -5 , 5 )  ; Get random horizontal increment
          IncY# = Rnd( -5 , 5 )  ; Get random vertical increment
          Length = VectorDistance( IncX , IncY )  ; Calculate the real length of the line (size of the vector)
          Angle = VectorAngle( IncX , IncY )  ; Calculate the real angle
        Until Length >= 2 And Length <= 5 And Abs ( Dot\LastAngle - Angle ) <= 10
        ; Repeat calculating until we get a line with length between 2 and 5
        ; and an angle that differs no more than 10 degrees from the current angle
        ; This technique is very slow but demonstrates the purpose

        Dot\LastAngle = Angle  ; Remember the current angle

        Dot\PosX = Dot\PosX + IncX  ; Update the dot's horizontal position by the new increment
        If Dot\PosX < 0 Then Dot\PosX = Dot\PosX + GraphicsWidth()  ; But if it goes off-screen, make it warp
        If Dot\PosX > GraphicsWidth() Then Dot\PosX = Dot\PosX - GraphicsWidth()

        Dot\PosY = Dot\PosY + IncY  ; Same for vertical position
        If Dot\PosY < 0 Then Dot\PosY = Dot\PosY + GraphicsHeight()
        If Dot\PosY > GraphicsHeight() Then Dot\PosY = Dot\PosY - GraphicsHeight()

        Color Dot\Color , Dot\Color , Dot\Color  ; Pick da color
        Plot Dot\PosX , Dot\PosY  ; Plot the dot, you can use writepixel too

      Next
      Flip
    Until GetKey()

    Delete Each Dot  ; Wipe them out
    EndGraphics
    End
End Function

; Specific example for GetVectorX and GetVectorY
; -------------------------------------------------------------------------------------------------------------------- ;
; Demonstrates 'fishies' (nibbles/lines) wondering about with various speeds, sizes and colors.

    Type Nibble  ; Fishy
      Field TailX#  ; Fishy has head and tail
      Field TailY#  ; Program uses tail for positioning
      Field Speed%  ; Fishy has speed
      Field Heading%  ; Fishy has angle or heading
      Field Size%   ; Fishy has size, e.g. difference between head and tail
      Field Color%  ; And color (simple grey scale)
    End Type

Function prog3 ()
    Graphics 640 , 480
    SetBuffer BackBuffer()
    SeedRnd MilliSecs()

          TotalNibbles = 20  ; Total number of nibbles to create

    Local Nibble.Nibble  ; Our collection of nibbles

    For Counter = 1 To TotalNibbles  ; Create nibbles
      Nibble = New Nibble
      Nibble\TailX = Rnd( 0 , GraphicsWidth() )   ; Random position within screen boundaries
      Nibble\TailY = Rnd( 0 , GraphicsHeight() )  ;
      Nibble\Speed = Rnd( 2 , 5 )  ; Random speed
      Nibble\Heading = Rnd( 0 , 359 )  ; Random heading to start with
      Nibble\Size = Rnd( 5 , 10 )  ; Random size too
      Nibble\Color = Rnd( 64 , 255 )  ; And random shade
    Next

    Repeat
      Cls
      For Nibble = Each Nibble  ; Iterate through all nibbles

        Nibble\Heading = Nibble\Heading + Rnd( -10 , 10 )  ; Randomly alternate heading with max 10 degrees
        If Nibble\Heading < 0 Then Nibble\Heading = Nibble\Heading + 360  ; Keep angle in range of 0 and 359
        If Nibble\Heading > 359 Then Nibble\Heading = Nibble\Heading - 360

        Nibble\TailX = Nibble\TailX + VectorX( Nibble\Speed , Nibble\Heading )  ; Update position
        If Nibble\TailX < 0 Then Nibble\TailX = Nibble\TailX + GraphicsWidth()  ; Warp if off-screen
        If Nibble\TailX >= GraphicsWidth() Then Nibble\TailX = Nibble\TailX - GraphicsWidth()

        Nibble\TailY = Nibble\TailY + VectorY( Nibble\Speed , Nibble\Heading )  ; Same for vertical
        If Nibble\TailY < 0 Then Nibble\TailY = Nibble\TailY + GraphicsHeight()
        If Nibble\TailY >= GraphicsHeight() Then Nibble\TailY = Nibble\TailY - GraphicsHeight()

        HeadX# = Nibble\TailX + VectorX( Nibble\Size , Nibble\Heading )  ; Calculate head based on tail
        HeadY# = Nibble\TailY + VectorY( Nibble\Size , Nibble\Heading )  ;  (can go off-screen)
        Color Nibble\Color , Nibble\Color , Nibble\Color  ; Nibble color
        Line Nibble\TailX , Nibble\TailY , HeadX , HeadY  ; Line from tail to head

      Next
      Flip
    Until GetKey()

    Delete Each Nibble
    EndGraphics
    End
End Function

; Example of space physics using vector translation (Method A)
; ---------------------------------------------------------------------------- ;
; Demonstrates the use of angle, thrust, heading and velocity

Function prog4 ()
    Graphics 640 , 480
    SetBuffer BackBuffer()

    ; Keyboard scancodes
          KeyCursorUp%    = 200
          KeyCursorDown%  = 208
          KeyCursorLeft%  = 203
          KeyCursorRight% = 205
          KeyEscape%      =   1
          KeySpace%       =  57

    ; Craft specifications
          ThrustMax# = 0.1  ; Maximum thrust speed
          SpeedMax# = 5     ; Maximum allowed velocity
          RotateMax# = 4    ; Maximum rotation speed (degrees)

    ; Craft related
    PosX# = GraphicsWidth() / 2   ; Start at center of screen
    PosY# = GraphicsHeight() / 2  ;
    Thrust#  = 0  ; Current thrust speed - in the direction of where the ship is pointing at
    Angle%   = 0  ; Current angle (rotation) - where the ship is pointing at
    Speed#   = 0  ; Current actual speed of the ship
    Heading% = 0  ; Current heading - where the ship is moving towards (degrees)

    ; Logic related
    Local Thrusting% = False  ; Thrusts forwards/backwards when True, automatically decelerates thrust when False
    Local VelocityX# = 0  ; Temporary variables for calculating the new velocity vector
    Local VelocityY# = 0  ;

    Repeat
      Cls

      If KeyDown( KeyCursorLeft ) Then Angle = Angle - RotateMax  ; Rotate anti-clockwise
      If KeyDown( KeyCursorRight ) Then Angle = Angle + RotateMax  ; Rotate clockwise
      If Angle < 0 Then Angle = Angle + 360  ; Make sure angle is in range of 0-359 (shift)
      If Angle > 359 Then Angle = Angle - 360

      Thrusting = False  ; Automatically decelerate thrust - reset thrusting flag
      If KeyDown( KeyCursorUp ) Then  ; Cursor up held down
        Thrust = ThrustMax  ; Start thrusting forwards at max speed
        Thrusting = True  ; Do not decelerate thrust
      EndIf
      If KeyDown( KeyCursorDown ) Then  ; Cursor down held down
        Thrust = -ThrustMax  ; Start thrusting backwards at max speed
        Thrusting = True  ; Do not decelerate thrust
      EndIf
      If Not Thrusting Then Thrust = 0  ; Automatically decelerate thrusting when not thrusting (on request)

      ; Note:
      ;   Speed & Heading = Current velocity vector [ VelocityX VelocityY ]
      ;   Thrust & Angle = Current thrust vector [ ThrustX ThrustY ]
      VelocityX = VectorX( Speed , Heading ) + VectorX( Thrust , Angle )  ; The new velocity vector is the sum of
      VelocityY = VectorY( Speed , Heading ) + VectorY( Thrust , Angle )  ; the current velocity and thrust vector
      Speed = VectorDistance( VelocityX , VelocityY )   ; Translate back to speed and heading
      Heading = VectorAngle( VelocityX , VelocityY )  ;
      If Speed > SpeedMax Then Speed = SpeedMax  ; Limit speed to maximum

      If KeyDown( KeySpace ) Then Speed = 0  ; Handbrake

      PosX = PosX + VectorX( Speed , Heading )  ; Update horizontal position with current horizontal velocity inc.
      If PosX < 0 Then PosX = PosX + GraphicsWidth()  ; Warp if off-screen
      If PosX >= GraphicsWidth() Then PosX = PosX - GraphicsWidth()
      PosY = PosY + VectorY( Speed , Heading )  ; Same for vertical
      If PosY < 0 Then PosY = PosY + GraphicsHeight()
      If PosY >= GraphicsHeight() Then PosY = PosY - GraphicsHeight()

      Color 0 , 127 , 255  ; Additional information
      Oval PosX - 10 , PosY - 10 , 21 , 21 , True
      Text 0 , 0 * FontHeight() , "X: " + Int(PosX) + " Y: " + Int(PosY)
      Color 127 , 255 , 127
      Line PosX , PosY , PosX + VectorX( 10 , Heading ) , PosY + VectorY( 10 , Heading )
      Text 0 , 1 * FontHeight() , "Speed: " + Int(Speed) + " Heading: " + Heading
      Color 255 , 255 , 255
      Line PosX , PosY , PosX + VectorX( 20 , Angle ) , PosY + VectorY( 20 , Angle )
      Text 0 , 2 * FontHeight() , "Thrust: " + Thrusting + " Angle: " + Angle

      Flip
    Until KeyDown( KeyEscape )

    EndGraphics
    End
End Function

; Example of space physics using vector translation (Method B)
; ---------------------------------------------------------------------------- ;
; Demonstrates the use of native thrust and velocity vectors

Function prog5 ()
    Graphics 640 , 480
    SetBuffer BackBuffer()

    ; Keyboard scancodes
          KeyCursorUp%    = 200
          KeyCursorDown%  = 208
          KeyCursorLeft%  = 203
          KeyCursorRight% = 205
          KeyEscape%      =   1
          KeySpace%       =  57

    ; Craft specifications
          ThrustMax# = 0.1  ; Maximum thrust speed
          SpeedMax# = 5     ; Maximum allowed velocity
          RotateMax# = 4    ; Maximum rotation speed (degrees)

    ; Craft related
    PosX# = GraphicsWidth() / 2   ; Start at center of screen
    PosY# = GraphicsHeight() / 2  ;
    ThrustX#   = 0  ; Native vector for thrust
    ThrustY#   = 0  ;
    VelocityX# = 0  ; Native vector for velocity
    VelocityY# = 0  ;
    Angle%     = 0  ; Current angle (degrees)

    ; Logic related
    Local Thrusting% = False  ; Thrusts forwards/backwards when True, automatically decelerates thrust when False
    Local Speed#    ; Temporary variables for calculation
    Local Heading%  ;

    Repeat
      Cls

      If KeyDown( KeyCursorLeft ) Then Angle = Angle - RotateMax  ; Rotate anti-clockwise
      If KeyDown( KeyCursorRight ) Then Angle = Angle + RotateMax  ; Rotate clockwise
      If Angle < 0 Then Angle = Angle + 360  ; Make sure angle is in range of 0-359 (shift)
      If Angle > 359 Then Angle = Angle - 360

      Thrusting = False  ; Automatically decelerate thrust - reset thrusting flag

      If KeyDown( KeyCursorUp ) Then  ; Cursor up held down
        ThrustX = VectorX( ThrustMax , Angle )  ; Start thrusting forwards at max speed
        ThrustY = VectorY( ThrustMax , Angle )  ;
        Thrusting = True  ; Do not decelerate thrust
      EndIf

      If KeyDown( KeyCursorDown ) Then  ; Cursor down held down
        ThrustX = VectorX( -ThrustMax , Angle )  ; Start thrusting backwards at max speed
        ThrustY = VectorY( -ThrustMax , Angle )  ;
        Thrusting = True  ; Do not decelerate thrust
      EndIf

      If Not Thrusting Then
        ThrustX = 0  ; Automatically decelerate thrusting when not thrusting (on request)
        ThrustY = 0  ;
      EndIf

      VelocityX = VelocityX + ThrustX  ; The new velocity vector is the sum of the current velocity and thrust vector
      VelocityY = VelocityY + ThrustY  ;

      Speed = VectorDistance( VelocityX , VelocityY )   ; Calculate actual speed
      Heading = VectorAngle( VelocityX , VelocityY )  ; Calculate actual heading

      If Speed > SpeedMax Then Speed = SpeedMax    ; Limit speed to maximum

      If KeyDown( KeySpace ) Then Speed = 0        ; Handbrake

      VelocityX = VectorX( Speed , Heading )    ; Translate back to native velocity vector
      VelocityY = VectorY( Speed , Heading )    ;

      PosX = PosX + VelocityX  ; Update horizontal position with current horizontal velocity increment
      If PosX < 0 Then PosX = PosX + GraphicsWidth()  ; Warp if off-screen
      If PosX >= GraphicsWidth() Then PosX = PosX - GraphicsWidth()

      PosY = PosY + VelocityY  ; Same for vertical
      If PosY < 0 Then PosY = PosY + GraphicsHeight()
      If PosY >= GraphicsHeight() Then PosY = PosY - GraphicsHeight()

      Color 0 , 127 , 255  ; Additional information
      Oval PosX - 10 , PosY - 10 , 21 , 21 , True
      Text 0 , 0 * FontHeight() , "X: " + Int(PosX) + " Y: " + Int(PosY)

      Color 127 , 255 , 127
      Line PosX , PosY , PosX + VectorX( 10 , Heading ) , PosY + VectorY( 10 , Heading )
      Text 0 , 1 * FontHeight() , "Speed: " + Int(Speed) + " Heading: " + Heading

      Color 255 , 255 , 255
      Line PosX , PosY , PosX + VectorX( 20 , Angle ) , PosY + VectorY( 20 , Angle )
      Text 0 , 2 * FontHeight() , "Thrust: " + Thrusting + " Angle: " + Angle

      Flip
    Until KeyDown( KeyEscape )

    EndGraphics
    End
End Function

;-------------------------------------------------------------------------------

Function sine1 ()

    Height = 50
    Offset = Height

    Graphics 360 + 10 , Height*2 + Offset*2 + 10 , 2

    ClsColor 255 , 255 , 255
    Color 0 , 0 , 0
    Cls

    Text 0 , 0 , "SIN"
    Text 0 , Offset + Height , "COS"
    For PosX = 0 To 360 Step 10
        For PosY = 0 To Height*2 + Offset*2 Step 4
            Plot PosX , PosY
        Next
    Next
    Line 0 , 0 , 360 , 0
    Line 0 , Offset + Height , 360 , Offset + Height
    Text   0 , Height*2 + Offset*2 ,   "0" , True , True
    Text  90 , Height*2 + Offset*2 ,  "90" , True , True
    Text 180 , Height*2 + Offset*2 , "180" , True , True
    Text 270 , Height*2 + Offset*2 , "270" , True , True
    Text 360 , Height*2 + Offset*2 , "360" , True , True
	For Position = 0 To 359
        Color 0 , 0 , 255
		Plot Position , Sin ( Position ) * Height + Offset
        Color 255 , 0 , 0
		Plot Position , Cos ( Position ) * Height + Offset*2 + Height
	Next
	WaitKey

End Function

;-------------------------------------------------------------------------------

Function sine2 ()

    Graphics 300 , 600 , 2

    Text 0 , 0 , "Angle"
    Text 100 , 0 , "Sine"
    Text 200 , 0 , "(rounded)"
    pos = 10

    For angle = 0 To 360 Step 10

        value# = Sin ( angle )

        pos = pos + 10
        Text   0 , pos , angle
        Text 100 , pos , value
        Text 200 , pos , Int value

    Next
    WaitKey

End Function

;-------------------------------------------------------------------------------

Function sine3 ()

    offset = 180

    finish = offset + 360

    Repeat
        pos = pos + 1

        value# = Sin ( pos + offset )

        Plot pos , value * 50 + 50

    Until pos + offset >= finish

    WaitKey

End Function

;-------------------------------------------------------------------------------

Function sine4 ()

    Graphics 640 , 480

    middleX = 320
    middleY = 240

    radius = 100

    ; range
    Oval middleX - radius , middleY - radius , radius*2 , radius*2 , False

    ; center point
    Oval middleX - 5 , middleY - 5 , 10 , 10 , True

    ; start in center
    startX = middleX
    startY = middleY

    ; direction
    angle = 123

    ; calculate end point
    endX = Sin ( angle      ) * radius + startX
    endY = Sin ( angle - 90 ) * radius + startY

    ; draw vector from center
    Line startX , startY , endX , endY

    WaitKey

End Function

;-------------------------------------------------------------------------------

Function sine5 ()

  Graphics 400 , 300 , 2

  SetBuffer BackBuffer ()

  middlex = GraphicsWidth () / 2
  middley = GraphicsHeight () / 2

  radius = 100

  Repeat

    angle = angle + 1
    If angle = 360 Then angle = 0

    x = Sin ( angle ) * radius
    y = Sin ( angle - 90 ) * radius

    SpecialRect middlex , middley , x , y , False
    Line middlex , middley , middlex + x , middley + y

    Text 0 , 0 , "Angle: " + angle

    Flip
    Cls

  Until KeyHit ( 1 )

End Function

  Function SpecialRect ( x1 , y1 , sizex , sizey , filled = True )
    x = x1
    y = y1
    xs = sizex
    ys = sizey
    If xs < 0
      xs = -xs
      x = x - xs
    End If
    If ys < 0
      ys = -ys
      y = y - ys
    End If
    Rect x , y , xs , ys , filled
  End Function

;-------------------------------------------------------------------------------

Function sine6 ()

    Graphics 640 , 480

    SetBuffer BackBuffer ()

    middleX = GraphicsWidth () / 2
    middleY = GraphicsHeight () / 2

    radius = 100

    For angle = 0 To 359 Step 5

        ; calculate end point
        X = Sin ( angle      ) * radius + middleX
        Y = Sin ( angle - 90 ) * radius + middleY

        Plot X , Y

    Next
    WaitKey

End Function

;-------------------------------------------------------------------------------

Function sine7 ()

    Graphics 640 , 480

    SetBuffer BackBuffer ()

    middleX = GraphicsWidth () / 2
    middleY = GraphicsHeight () / 2

    radius = 100

    For angle = 0 To 359 Step 5

        ; calculate end point
        endX = Sin ( angle      ) * radius + middleX
        endY = Sin ( angle - 90 ) * radius + middleY

        ; draw vector from center
        Line middleX , middleY , endX , endY

    Next
    WaitKey

End Function

;-->

End