Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Orbit Demo SIN and COS
#1
Orbit sub calculates points about a point cx, cy at a given angle in degrees and radius using trig functions COS and SIN ratios according to degrees.

Code: (Select All)
Option _Explicit
_Title "orbit demo" 'b+ 2024-05-10

'============================== Main
Const Xmax = 1000, Ymax = 700
Const Thick = 2
Const Arc_Radius = 100
Const Sin_color = _RGB32(0, 0, 255)
Const Cos_color = _RGB32(0, 128, 0)
Const Radius_color = _RGB32(255, 0, 0)
Const Ang_color = _RGB32(255, 255, 0)
Const White = _RGB32(255, 255, 255)
Const Origin_color = _RGB32(255, 128, 0)
Dim cx, cy, mx, my, stepX, stepY, Radius, dAng, xOut, yOut, x, y
cx = Xmax / 2: cy = Ymax / 2
Screen _NewImage(Xmax, Ymax, 32)
_ScreenMove 60, 0
_PrintMode _KeepBackground
_MouseMove cx + 100, cy + 100 ' get ball rolling
While 1
    Cls
    Color White
    Locate 2, 18
    Print "Move your mouse clockwise starting at 0 due East to see Basics Angle in Degrees increase."
    Locate 5, 68
    Print "Orbit ";
    Color Origin_color
    Print "X_Origin, Y_Origin,";
    Color Ang_color
    Print " Degrees,";
    Color Radius_color
    Print " Radius,";
    Color White
    Print " xOut, yOut"
    'draw horizontal through center of screen
    Line (70, cy)-(Xmax - 70, cy), Cos_color
    ' draw vertical line through center of screen
    Line (cx, 70)-(cx, Ymax - 70), Sin_color
    'poll mouse
    While _MouseInput: Wend ' updates all mouse stuff except wheel
    mx = _MouseX: my = _MouseY 'get mouse location

    'draw our Color Coded Trig Triangle
    ThickLine cx, cy, mx, cy, 1, Cos_color
    ThickLine mx, cy, mx, my, 1, Sin_color
    ThickLine cx, cy, mx, my, Thick, Radius_color

    stepX = mx - cx: stepY = my - cy
    Radius = (stepX ^ 2 + stepY ^ 2) ^ .5

    'to draw angle need to do some math
    'dAng = mouse angle to 0 Degrees due East
    dAng = _R2D(_Atan2(my - cy, mx - cx))
    If dAng < 0 Then dAng = dAng + 360

    Color Ang_color
    ThickArc cx, cy, Radius, 0, dAng, Thick

    'report all numbers color coded
    Color Ang_color
    Locate 5, 3: Print "Yellow Angle (in Degrees) ~ "; dAng \ 1
    Color Radius_color
    Locate 7, 7: Print "    Length red Radius ~ "; Radius \ 1
    Color Sin_color
    Locate 9, 7: Print " Length blue Opp side ~ "; Abs(stepY) \ 1
    Color Cos_color
    Locate 8, 7: Print "Length green Adj side ~ "; Abs(stepX) \ 1
    Color White
    Locate 11, 1: Print " Ratios: (if no division by 0)"
    If Radius <> 0 Then
        Color Cos_color
        Locate 12, 8: Print "COS = Adj ";
        Color Radius_color
        Print "/ Radius ";
        Color White
        Print "~ "; Left$(Str$(stepX / Radius), 6) '; Cos(_D2R(dAng))  ' double check

        Color Sin_color
        Locate 13, 8: Print "SIN = Opp ";
        Color Radius_color
        Print "/ Radius ";
        Color White
        Print "~ "; Left$(Str$(stepY / Radius), 6) '; Sin(_D2R(dAng)) ' double check
    End If
    Color White
    orbit cx, cy, dAng, Radius, xOut, yOut ' mouse here
    orbit cx, cy, dAng, Radius + 50, x, y ' set label here
    label x, y, "(xOut, yOut) = (" + _Trim$(Str$(xOut \ 1)) + "," + Str$(yOut \ 1) + ")"
    Color Origin_color
    label cx, cy - 10, "(X_Origin, Y_Origin) = (" + _Trim$(Str$(cx)) + "," + Str$(cy) + ")"
    _Display
    _Limit 60
Wend


'      !!!!!!   featuring the use of this SUB routine   !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single  should be ok
    xOut = X_Origin + Radius * Cos(_D2R(Degrees))
    yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub

Sub label (xc, yc, text$)
    Dim th2, pw2
    th2 = _FontHeight / 2
    pw2 = _PrintWidth(text$) / 2
    _PrintString (xc - pw2 + 1.25, yc - th2 + .5), text$
End Sub

Sub ThickArc (xCenter, yCenter, arcRadius, dAngleStart, dAngleEnd, rThick)
    Dim rAngle, rAngleStart, rAngleEnd, x1, y1, Stepper
    'draws an Arc with center at xCenter, yCenter, Radius from center is arcRadius

    'for SmallBASIC angle 0 Degrees is due East and angle increases clockwise towards South

    'THIS SUB IS SETUP TO DRAW AN ARC IN CLOCKWISE DIRECTION

    'dAngleStart is where to start Angle in Degrees
    ' so make the dAngleStart the first ray clockwise from 0 Degrees that starts angle drawing clockwise

    'dAngleEnd is where the arc ends going clockwise with positive Degrees
    ' so if the arc end goes past 0 Degrees clockwise from dAngleStart
    '  express the end angle as 360 + angle

    'rThick is the Radius of the many,many tiny circles this will draw to make the arc thick
    ' so if rThick = 2 the circles will have a Radius of 2 pixels and arc will be 4 pixels thick
    If arcRadius < 1 Then PSet (xCenter, yCenter): Exit Sub
    rAngleStart = _D2R(dAngleStart): rAngleEnd = _D2R(dAngleEnd)
    If Int(rThick) = 0 Then Stepper = 1 / (arcRadius * _Pi) Else Stepper = rThick / (arcRadius * _Pi / 2)
    For rAngle = rAngleStart To rAngleEnd Step Stepper
        x1 = arcRadius * Cos(rAngle): y1 = arcRadius * Sin(rAngle)
        If Int(rThick) < 1 Then
            PSet (xCenter + x1, yCenter + y1)
        Else
            fcirc xCenter + x1, yCenter + y1, rThick, Ang_color
        End If
    Next
End Sub

Sub ThickLine (x1, y1, x2, y2, rThick, K As _Unsigned Long)
    Dim length, stepx, stepy, dx, dy, i

    'x1,y1 is one endpoint of line
    'x2,y2 is the other endpoint of the line
    'rThick is the Radius of the tiny circles that will be drawn
    '   from one end point to the other to create the thick line
    'Yes, the line will then extend beyond the endpoints with circular ends.

    stepx = x2 - x1
    stepy = y2 - y1
    length = (stepx ^ 2 + stepy ^ 2) ^ .5
    If length Then
        dx = stepx / length: dy = stepy / length
        For i = 0 To length
            fcirc x1 + dx * i, y1 + dy * i, rThick, K
        Next
    End If
End Sub

Sub fcirc (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
    Dim Radius As Long, RadiusError As Long
    Dim X As Long, Y As Long
    Radius = Abs(R): RadiusError = -Radius: X = Radius: Y = 0
    If Radius = 0 Then PSet (CX, CY), C: Exit Sub
    Line (CX - X, CY)-(CX + X, CY), C, BF
    While X > Y
        RadiusError = RadiusError + Y * 2 + 1
        If RadiusError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            End If
            X = X - 1
            RadiusError = RadiusError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    Wend
End Sub
edit: to show when sin and cos go negative. abs() should only be applied to lengths.

Notice 0 Degrees is due East and as the angle in degrees increases the the arc goes CLOCK-WISE about cx, cy from EAST to SOUTH to WEST to NORTH and returns to due EAST at 360 degrees, one complete turn.

   
b = b + ...
Reply
#2
to use orbit imagine standing at point X_Origin, Y_Origin face towards Degrees direction and move forward Radius length

xOut, yOut are the coordinates of where you are after the move.

here is a simple pentagram made from 5 turns and moves
Code: (Select All)
_Title "orbit demo make pentagram " 'b+ 2024-05-10
Const Xmax = 700, Ymax = 700
Screen _NewImage(Xmax, Ymax, 32)
x = _Width / 2: y = _Height / 2 ' start in center of screen
pentAngle = 72 ' the angles inside a pentagram are 360 / 5 = 72 degrees
forward = 100
For turn = 1 To 5 ' turn
    orbit x, y, Angle, forward, nextx, nexty
    Line (x, y)-(nextx, nexty)
    Angle = Angle + pentAngle ' the absolute angle from 0 degrees accumulates at every turn
    x = nextx: y = nexty
    _Limit 2
Next
'      !!!!!!   featuring the use of this SUB routine   !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single  should be ok
    xOut = X_Origin + Radius * Cos(_D2R(Degrees))
    yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub

a little mod and we have a pentagram spiral
Code: (Select All)
_Title "orbit demo make pentagram spiral " 'b+ 2024-05-10
Const Xmax = 700, Ymax = 700
Screen _NewImage(Xmax, Ymax, 32)
x = _Width / 2: y = _Height / 2 ' start in center of screen
pentAngle = 72 ' the angles inside a pentagram are 360 / 5 = 72 degrees
forward = 10
angle = -36
While y > 0 And y < _Height
    orbit x, y, angle, forward, nextx, nexty
    Line (x, y)-(nextx, nexty)
    forward = forward + 10
    angle = angle + pentAngle ' the absolute angle from 0 degrees accumulates at every turn
    x = nextx: y = nexty '      restart where we left off
    _Limit 2
Wend
'      !!!!!!   featuring the use of this SUB routine   !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single  should be ok
    xOut = X_Origin + Radius * Cos(_D2R(Degrees))
    yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub
b = b + ...
Reply
#3
Orbit Poly 24


Code: (Select All)
Option _Explicit
_Title "orbit poly 24" 'b+ 2024-06-05
' a geometric meditation on the 24 points of circle / polygon

Const Xmax = 700, Ymax = 700
Screen _NewImage(Xmax, Ymax, 32)
_ScreenMove 300, 20

Dim px(1 To 24), py(1 To 24) '          24 points on the circle
Dim As Long i, j, pIndex, cx, cy '      indexs and center point
Dim a, angle24, radius, x, y '          orbit point calculations
Dim As Long r, g, b '                   color rgb trackers

cx = _Width / 2: cy = _Height / 2 '     start in center of screen

angle24 = 360 / 24 '                    the angles inside a regular polygon of 24 sides
radius = 340 '                          fill screen with big 340 radius circle
For a = 0 To 359 Step angle24 '         24 angles
    orbit cx, cy, a, radius, x, y '     orbit calc of x, y from center at angle and radius
    pIndex = pIndex + 1 '               update point index
    px(pIndex) = x: py(pIndex) = y '    save point calcs into an array
    '
    If a > 0 Then Line (px(pIndex - 1), py(pIndex - 1))-(x, y) ' draw the line around edge
Next
Line (px(24), py(24))-(px(1), py(1)) '  finsih edge lines

' now from all the points to all the other points, draw the lines
For i = 1 To 24
    For j = 1 To 24
        If i <> j Then Line (px(i), py(i))-(px(j), py(j)), _RGB32(255 - i * 10, 255 * i * j / 576, j * 10 + 15)
    Next
Next

' now animate with moving color
r = 0: g = 80: b = 180
While _KeyDown(27) = 0
    For i = 1 To 24
        For j = 1 To 24
            If i <> j Then
                r = (r + 3) Mod 24: g = (g + 2) Mod 24: b = (b + 1) Mod 24
                Line (px(i), py(i))-(px(j), py(j)), _RGB32(10 * r + 25, 10 * g + 25, 10 * b + 25)
            End If
            _Limit 552
        Next
    Next
Wend

'      !!!!!!   featuring the use of this SUB routine   !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single  should be ok
    xOut = X_Origin + Radius * Cos(_D2R(Degrees))
    yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub


Attached Files Image(s)
   
b = b + ...
Reply
#4
Very cool, b+! Brings me back to my Spirograph days...
Reply




Users browsing this thread: 1 Guest(s)