Math's Trig Versus Basic's Trig Functions
#1
As if Trig is not confusing enough, the confusion is made far worse because in the Basic screen Y increases going down screen whereas in math graphing, you learned Y increases going up.

To make matters still more confusing, there are 2 unit measures for angles, Degrees and Radians.

Degrees go full circle from 0 to 360 in nice easy to understand way with integers giving a pretty accurate picture of the angle.
Radians go full circle from 0 to 2 * _Pi and with not so easy to picture angle measures unless you express them in fractions of 2*_Pi eg _Pi is 180 Degrees half a circle = 2*Pi / 2 which is just _Pi, _Pi / 2 = 90 one quarter of a circle 2*_PI / 4 same as _PI / 2.
120 Degrees is 1/3 of circle same as 2*_Pi / 3
60 Degrees is 1/6 of circle same as 2*_PI /6 = _Pi / 3
30 Degrees is 1/12 of circle same as 2 *_Pi / 12 = _PI / 6

Anyway here is maybe a Rosetta Stone for Math's Trig Comparing to Basic's Trig with pictures to show WTH? is what!
Code: (Select All)
Option _Explicit
_Title "A Look at Math's Trig and Comparing to Basic's Trig Functions" 'b+ trans from:
' Another look at Trig functions.bas  SmallBASIC 0.12.2 [B+=MGA] 2016-05-01
' inspired by PeterMaria's simple code for Atan2 on Aurels' forum BasicPro
' 2017-09-23 Modified to run again on Android

' Here is another effort in a continuing series to demystify Trig functions:

' Move your mouse around the center point of the screen and see the right triangles
' created with the mouse and a horizontal line from the center.

' See all the parts of the triangle expressed in numbers:
' Angles to the horizontal line, lengths of the sides and hypotenuse of the right
' and the COS, SIN and TAN ratios

'============================== Main
Const Xmax = 800, Ymax = 700
Const Thick = 2
Const Arc_radius = 100
Const Sin_color = _RGB32(0, 0, 255)
Const Cos_color = _RGB32(255, 0, 0)
Const Hyp_color = _RGB32(0, 192, 0)
Const Ang_color = _RGB32(255, 255, 0)
Const White = _RGB32(255, 255, 255)
Dim cx, cy, mx, my, stepX, stepY, hyp, dAng, startA, endA, reportA
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

    'draw horizontal through center of screen
    Line (0, cy)-(Xmax, cy), Cos_color
    ' draw vertical line through center of screen
    Line (cx, 0)-(cx, Ymax), 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, Thick, Cos_color
    ThickLine mx, cy, mx, my, Thick, Sin_color
    ThickLine cx, cy, mx, my, Thick, Hyp_color

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

    'to draw angle need to do some math
    'dAng = mouse angle to 0 degrees due East
    ' other Angles:  StartA, EndA and reportA are for the Trig Ratios of triangle
    dAng = Int(_R2D(_Atan2(my - cy, mx - cx)) + .5)
    If dAng < 0 Then dAng = dAng + 360

    If dAng <= 90 Then
        startA = 0: endA = dAng: reportA = dAng
    ElseIf dAng <= 180 Then
        startA = dAng: endA = 180: reportA = 90 - (dAng - 90)
    ElseIf dAng <= 270 Then
        startA = 180: endA = dAng: reportA = dAng - 180
    ElseIf dAng <= 360 Then
        startA = dAng: endA = 360: reportA = 90 - (dAng - 270)
    End If
    Color Ang_color
    ThickArc cx, cy, Arc_radius, startA, endA, Thick

    'report all numbers color coded
    Color Ang_color
    Locate 1, 1: Print " Yellow Angle (in degrees) ~ "; reportA
    Color White
    Locate 3, 1: Print "    Lengths:"
    Color Hyp_color
    Locate 4, 1: Print " green Hyp ~ "; hyp
    Color Sin_color
    Locate 5, 1: Print "  blue Opp ~ "; stepY \ 1
    Color Cos_color
    Locate 6, 1: Print "   red Adj ~ "; stepX \ 1
    Color White
    Locate 8, 1: Print " Ratios: (if no division by 0)"
    If hyp <> 0 Then
        Color Cos_color
        Locate 9, 2: Print "COS = Adj ";
        Color Hyp_color
        Print "/ Hyp ";
        Color White
        Print "~ "; Left$(Str$(stepX / hyp), 6)

        Color Sin_color
        Locate 10, 2: Print "SIN = Opp ";
        Color Hyp_color
        Print "/ Hyp ";
        Color White
        Print "~ "; Left$(Str$(stepY / hyp), 6)
    End If
    If stepX <> 0 Then
        Locate 11, 2: Print "TAN = ";
        Color Sin_color
        Print "Opp ";
        Color Cos_color
        Print "/ Adj ";
        Color White
        Print "~ "; Left$(Str$(stepY / stepX), 6)
    End If

    Color &H55FFFFFF
    Locate 33, 2: Print "QB64 Coding Notes for Basic Graphics without Window( ):"
    Print "   The Screen center Center X, Center Y is "; _Trim$(Str$(cx)); ", "; _Trim$(Str$(cy))
    Print "   Mouse X ="; mx; "   MouseX - Center X = "; _Trim$(Str$(mx - cx))
    Print "   Mouse Y ="; my; "   MouseY = Center Y = "; _Trim$(Str$(my - cx))
    Print "   So Mouse Angle in Radians = _Atan2(my - cy, mx - cx) ="; _Atan2(my - cy, mx - cx)
    Print "   Mouse Angle converted to Degrees rounding to nearest 1 = Int(_R2D(Radian Angle) +.5) = ";
    Print _Trim$(Str$(Int(_R2D(_Atan2(my - cy, mx - cx)) + .5)))
    Print "   BUT! if Degrees < 0 add 360 to see angle in postive numbers from Basic's 0 (due East) = ";
    If Int(_R2D(_Atan2(my - cy, mx - cx)) + .5) < 0 Then
        Print _Trim$(Str$(Int(_R2D(_Atan2(my - cy, mx - cx)) + .5) + 360))
    Else
        Print _Trim$(Str$(Int(_R2D(_Atan2(my - cy, mx - cx)) + .5)))
    End If
    Print
    Print "  Move your mouse clockwise starting at 0 due East to see Basics Angle in Degrees increase."
    _Display
    _Limit 60
Wend

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

I sure hope this helps and does not add to the confusion.
b = b + ...
Reply
#2
That is one really well put together demo! Oh, and thanks for the explanation. I was right with you all the way up to "AS if..."

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#3
This is a good thing for me to study, I think. I try to work in vectors mostly, but it would be helpful to have a deeper understanding of the coding differences for trig.

I prefer to work in math mode and so I generally resort to WINDOW commands to redefine my screen with (0, 0) at the desired central point and the axes appropriately flipped. Even then I find there are other things that need tweaking. For instance when I was doing the space vectoring thing I was using a 0/360 at the top and ascending clockwise, so in that instance I had to swap out SIN & COS as well as a few other tweaks to get it to work. In that program I was not having to define the whole screen, but rather just the sensor screen image and _PUTIMAGE-ing it to the main screen

For the unit circle visualizer it worked pretty well out of the gate except for an issue of going from 0-180 twice, rather than 0-360. First in quadrant I & II and then again from 0-180 in quadrant III & IV.

I ended up using a correctional branch, which seems to work fine:

    IF ci.y < 0 THEN ' aka the point is in quad. III & IV
        rad = TwoPI - ABS(_ATAN2(ci.y, ci.x))
    ELSE
        rad = _ATAN2(ci.y, ci.x)
    END IF


One thing my latest code did was get me more acquainted with PMAP since my redefined screen demands its use.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#4
Yes, @OldMoses your Unit Circle WIP is fine example of using Window( ) to reset coordinates of the screen. (It's not finished?)
It did inspire me to pull out my old thing about Trig Math and add more details about working with Basic's Screens as they are.

No matter which system you use, you have to jump through hoops.
b = b + ...
Reply
#5
I never finish anything, really, except my dinner. Wink

I just uploaded some small changes. It now includes a tangent line plot, and other fiddly display bits. It's also pointing out some issues with my Fix_Float$ function, which I've used elsewhere, so not only is it helping me conceptualize trig identities, but it's finding potential bugs in other programs. A nice twofer there...

I think a lot of folks resist trig because of the amount of memorization that's required. I know it's the case with me. I only discovered the SOH CAH TOA mnemonic a few years back. It certainly wasn't taught to me in school. Prior to that, anytime I needed to use trig it was off to find a math book or my machinist notes. It was only a few days ago that I found that with the reciprocal identities, only one of each pair starts with "CO..." So now I no longer need confuse which is secant and cosecant.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#6
This is GREAT B+! I see you stuck with the 90 degree limit. Just so everyone knows, degrees on BASIC can be any number. If it goes higher than 360 it will just go back around again but the number can go higher if you want it to. It also can be a negative number, but at the opposite direction.
Reply
#7
"90 Degrees", that is Trig in a nutshell, it's all and only about triangles with a 90 Degree corner AKA Right Triangles.
b = b + ...
Reply
#8
Remember Obamacare? That's why Democrats can't do simple math... because there are no left triangles!

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#9
(07-30-2022, 05:30 AM)Pete Wrote: Remember Obamacare? That's why Democrats can't do simple math... because there are no left triangles!

That explains why they're always looking for a bigger slice of _PI, but we're going off on a TAN here...
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#10
(07-30-2022, 11:37 AM)OldMoses Wrote:
(07-30-2022, 05:30 AM)Pete Wrote: Remember Obamacare? That's why Democrats can't do simple math... because there are no left triangles!

That explains why they're always looking for a bigger slice of _PI, but we're going off on a TAN here...

I secant that. Wouldn't want to get anyone trig-gered.

Pete

There's always an angle, and I'll find it!
Reply




Users browsing this thread: 15 Guest(s)