Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Steve's basic SIN/COS Tutorial
#1
I swear, I'd thought I'd shared this here somewhere before, but it must've been on the old forums as I couldn't find it.  

/shrug

So anywho, some of you might remember this from the past, but I thought I'd share it once again here for whoever missed this the first time around -- Steve's basic SIN/COS Tutorial for Programming:

Code: (Select All)
ts = _NEWIMAGE(800, 6000, 32)
ws = _NewImage(800, 600, 32)
Screen ws

_Dest ts
Color _RGB32(255, 255, 0)
CenterText 10, "Steve's Basic SIN/COS Demo/Tutorial for Programming"
Color -1
Locate 3, 1
Print "First, let's go over what SIN and COS actually are.  A lot of people are completely mystified by"
Print "these two basic math commands."
Print
Print "SIN and COS are nothing more than than a RATIO of the sides of a right triangle"
Print
Print "For example, take a look at the triangle below"
Line (200, 150)-(0, 250), _RGB32(255, 0, 0) 'Red
Line (0, 250)-(200, 250), _RGB32(0, 255, 0) 'Green
Line (200, 250)-(200, 150), _RGB32(0, 0, 255) 'Blue

Color _RGB32(255, 0, 0)
Locate 11, 40: Print "The RED Line is the Hypotenuse"
Color _RGB32(0, 255, 0)
Locate 13, 40: Print "The GREEN Line is Adjacent to our angle"
Color _RGB32(0, 0, 255)
Locate 15, 40: Print "The BLUE Line is Opposite from our angle"
Color -1

Locate 18, 1
Print "If we look at the triangle above, we want to use the angle from the far left corner to get our SIN"
Print "and COS ratios."
Print
Print "SINE (SIN) is basically nothing more than the ratio of the length of the side that is opposite that"
Print "angle to the length of the longest side of the triangle (the Hypotenuse)."
Print
Print "Now, that might sound like a complex mouthful, but it's not as complicated as it seems."
Print "Basically, in the image above, if we were to measure the length of the BLUE line and then DIVIDE it"
Print "By the length of the RED line, we'd have the SINE value of our angle."
Print
Print "Opposite/ Hypotenuse = SINE  (or in this case, length of BLUE / length of RED = SINE)"
Print
Print
Print "Now, image taking this triangle and making it bigger or larger.  DON'T change the angle, but expand"
Print "the length and height of it in your imagination."
Print
Print "No matter how large you scale it, the RATIO of that opposite side and hypotenuse is ALWAYS going to"
Print "be the same."
Print
Print
Color _RGB32(255, 255, 0)
Print "That RATIO of opposite side divided by hypotenuse IS what SINE (SIN) is."
Color -1
Print
Print "And COSINE (COS) is nothing more than the ratio of the ADJACENT side divided by the hypotenuse."
Print "Which, in the above triangle would be nothing more than the length of the GREEN line, divied by"
Print "the length of the RED line."
Print
Color _RGB32(255, 255, 0)
Print "That RATIO of adjacent side divided by hypotenuse IS what COSINE (COS) is."
Color -1
Print
Print
Print "No matter how much you scale that triangle, that RATIO between those sides is going to stay the same"
Print "for that angle"
Print
Print "Now, let's say that my triangle has sides which are 3, 4, and 5 (units) long.  (If you're American,"
Print "they can be inches.  Elsewhere, centimeters...)."
Print
Print "Now, obviously looking at my (not to scale) triangle above, the Opposite side would have to be the"
Print "shortest at a length of 3.  The Adjacent side would have to be a little longer at a length of 4."
Print "And the Hypotenuse would be the longest side with the height of 5)"
Print
Print "(Red Line = 5, Green Line = 3, Blue Line = 4 on the diagram above)"
Print
Print
Color _RGB32(255, 255, 0)
Print "So what would our SIN and COS be for the above triangle (with the imaginary figures provided)?"
Color -1
Print
Print "SIN = Opposite / Hypotenuse, so that's 3/5 in this case (.6)"
Print "COS = Adjacent / Hypotenuse, so that's 4/5 in this case (.8)"
Print
Print
Print "And if we take a protractor (remember those from school?), we can measure the angle (for that"
Print "imaginary triangle), and see that it is roughly 36.87 degrees."
Print
Print "So, if we use the computer to check our math, this is what it tells us:"
Print "SIN = "; Sin(_D2R(36.87))
Print "COS = "; Cos(_D2R(36.87))
Print
Print "As you can see, our numbers aren't an EXACT match, but that's because I didn't use an EXACT figure"
Print "for that angle.  The angle formed by a 3-4-5 triangle is actually closer to 36.86989764582773"
Print "degrees, but who's counting that close?  (Except for the computer?) Tongue"
Print
Print
Print
Color _RGB32(255, 0, 255)
CenterText 1250, "Press the <<RIGHT ARROW>> to go on to PART II: Using SIN/COS In Triangles"
Color -1
Print
Print
Print
Print
Color _RGB32(255, 255, 0)
CenterText 1320, "PART II: Usine SIN/COS in triangles"
Color -1
Print
Print
Print "To briefly recap:"
Print "SIN(angle) = Opposite / Hypotenuse"
Print "COS(angle) = Adjacent / Hypotenuse"
Print
Print
Print "Which all sounds good and such.  We now know HOW we get sine and cosine from an angle, but how"
Print "the heck do we make use of it?"
Print
Print
Print "First, let's look at a basic right triangle again.  (A right triangle is defined as having one"
Print "side which is 90 degrees, as illustrated again below.)"
Line (400, 1650)-Step(-20, -20), _RGB32(185, 185, 0), B
Line (400, 1550)-(300, 1650)
Line (300, 1650)-(400, 1650)
Line (400, 1550)-(400, 1650)
Color _RGB32(255, 255, 0)
_PrintString (396, 1530), "A"
_PrintString (286, 1642), "B"
_PrintString (404, 1642), "C"
Color -1
Locate 106, 1
Print "As you can see, the angle at Point C is 90 degrees, so this is indeed a right triangle."
Print "(I'd hate to work with wrong ones.  Last I heard, they got several years jail time!)"
Print
Print
Print "So given two pieces of information for this triangle, can you figure out the rest?"
Print
Print "For example, let's pretend that this is a triangle with the longest side (hyptoenuse) being"
Print "200 units long, and our angle at point B is 45 degrees."
Print
Print "What would the length of the other 2 sides be?"
Print
Print
Print "Now, even though we all hate word problems, let's take a look at this one before we give up."
Print
Print "First, what's the side opposite of our given angle?"
Print "(Looking at the illustration above, it'd be the line from A to C, correct?)"
Print
Print "Open up your calculator, and get ready to do some math!  (Or else you'll never learn...)"
Print
Print "Remember what we said about what SINE and COSINE was?"
Print "SIN(angle) = Opposite / Hypotenuse"
Print "COS(angle) = Adjacent / Hypotenuse"
Print
Print "So to find that side opposite our given angle, we'd need to multiple both sides by the"
Print "Hypotenuse, so that we'd end up with basically the following:"
Print "SIN(angle) * Hypotenuse = Opposite"
Print "COS(angle) * Hypotenuse = Adjacent"
Print
Print
Color _RGB32(125, 125, 125)
Print "Remember why this works?  Think of our formula with actual numbers:"
Print "6 = x / 2  <-- let's pretend this is our formula."
Print "Now, if we multiply each side by 2, we'd end up getting:"
Print " 6 * 2 = x / 2 * 2"
Print "When you divide by a number and multiply by the same number, you get 1..."
Print "Which simplifies down to:    6 * 2 = x (or our answer of 12 in this case)"
Color -1
Print
Print
Print "In this case, we can just plug in the 2 numbers we know and get the last one."
Print "Our angle is 45 degrees."
Print "Our Hypotenuse is 100 units in length."
Print
Print "What would the length of the opposite side be? See if you can figure it out with what we've went"
Print "over above."
Print
Print
Print
Print
Color _RGB32(125, 125, 125)
Print "SIN(angle) * Hypotenuse = Opposite"
Print "SIN(45) * 100 = Opposite"
Print Sin(_D2R(45)) * 100; " = Opposite"
Print
Print "COS(angle) * Hypotenuse = Adjacent"
Print "COS(45) * 100 = Adjacent"
Print Cos(_D2R(45)) * 100; " = Adjacent"
Color -1
Print
Print
Print
Print
Print "Does the numbers you have look similar to the ones above?"
Print
Print "Seems simple enough, but think of what we've just did..."
Print "We took nothing more than a given angle and a side, and calculated the other sides of our triangle!"
Print
Print
Print "CONGRATULATIONS!!  You're well on the way to understanding SIN and COS."
Print "It's really not as complicated as some folks like to make it seem.  It's basically just"
Print "a relationship between 3 things, and using 2 of those things to figure out the third..."
Print
Print
Print
Color _RGB32(255, 0, 255)
CenterText 2770, "Press the <<RIGHT ARROW>> to go on to PART III: Using SIN/COS For Circles and Arcs"
Color _RGB32(255, 255, 0)
Print
CenterText 2820, "PART III: Using SIN/COS for Circles and Arcs"
Color -1
Print
Print
Print "Now that we've discussed the basics about how we can use SIN and COS in triangles, just how the heck"
Print "do we make them useful for circles?"
Print
Print
Circle (400, 3000), 100, _RGB32(255, 255, 0)
PSet (400, 3000), _RGB32(255, 255, 0)
Print
Print
Print
Print
Print
Print "This is a standard QB64 circle."
Print "The command to make this is:"
Print "CIRCLE (x,y), radius, color"
Print
Print
Print
Print
Print
Print "Using the information above, we know a heck of a lot of information about this circle."
Print "If you look at the source code for this program, you'll see our circle command is:"
Print "CIRCLE (400,3000), 100, _RGB32(255,255,0)"
Print
Print "Which breaks down to the center being at the point 400,3000, the radius being 100 pixels, and the"
Print "color being yellow."
Print
Print
Print "But could we draw this circle manually, using SIN and COS?"
Print
Print "Of course!"
Print
Print
Print "But how??"
Print
Print
Print "Think back on our previous lesson..."
Print "We take an angle and a side, and we calculate the length of the other 2 sides."
Print "To make a circle, we basically make a 360 degree arc, correct?"
Print
Print "So this would give us a nice loop so we can plot a pixel at each degree:"
Print "FOR angle = 1 to 360"
Print
Print
Print "And we know what our radius would be, correct?  (It was 100, if you remember...)"
Print
Print
Print "And using what we learned previously, what would the length of the opposite and adjacent sides"
Print "of a triangle be with 45 degrees and a 100 unit hypotenuse??"
Color _RGB32(125, 125, 125)
Print "SIN(angle) * Hypotenuse = Opposite"
Print "COS(angle) * Hypotenuse = Adjacent"
Color -1
Print
Print "And how does this pertain to our CIRCLE, you ask...."
Print
Print "As you can see, we have a 45"
Print "degree angle in this circle,"
Print "as illustrated here."
Print
Print
Circle (400, 3750), 100, _RGB32(255, 255, 255)
Line (250, 3750)-Step(300, 0), _RGB32(125, 125, 0)
Line (400, 3600)-Step(0, 300), _RGB32(125, 125, 0)
x = Sin(_D2R(45)) * 100
y = -Cos(_D2R(45)) * 100
Color _RGB32(255, 0, 0)
Line (400, 3750)-Step(x, y)
Line Step(0, 0)-Step(0, -y)
Line Step(0, 0)-Step(-x, 0)
_PrintString (390, 3740), "A"
_PrintString (420, 3700), "R"
Color -1
_PrintString (435, 3752), "x"
_PrintString (480, 3708), "y"
Print
Print "Now, for Angle A, with Radius R"
Print "What is the length of the other"
Print "two sides?"
Print
Color _RGB32(125, 125, 125)
Print "SIN(angle) * Hypotenuse = Opposite"
Print "COS(angle) * Hypotenuse = Adjacent"
Color -1
Print
Print
Print "So, let's plug in what we know to these 2 sets of equations:"
Print "x is ADJACENT to our angle A."
Print "y is OPPOSITE to our angle A."
Print "Our Hypotenuse is 100 pixels in size.  (R)"
Print "The angle A that we're using here is 45 degrees"
Print
Print "SIN(45) * 100 = Opposite (or y in this case)"
Print "COS(45) * 100 = Adjacent (or x in this case)"
Print
Print "X = "; Int(Sin(_D2R(45)) * 100)
Print "Y = "; Int(Cos(_D2R(45)) * 100)
Print
Print
Print "And what does this tell us about this single point on our circle??"
Print
Print "That when we have a radius of 100 pixels, the point at 45 degrees is going to be 70 pixels above"
Print "and 70 pixels right of the center!"
Print
Print
Print "But this just gives us a single point on the circle, for where 45 degrees would be..."
Print
Print "But never fear!  We can apply the exact same logic and math to get ANY point on our circle!!"
Print
Print "Try it out yourself, in your head.  Change that angle to 30 degrees.  The radius is going to stay"
Print "the same, as it's consistent with a circle (or else you don't have a circle), but using the"
Print "above method, we can find ANY point on our circle..."
Print
Print
Print "So to do a complete circle, we might code the following:"
Print
Print "FOR angle = 1 to 360 '1 point on the circle for each degree"
Print "    x = SIN(_D2R(angle)) * Radius 'we have to convert degree to radian for computer math, thus _D2R"
Print "    y = COS(_D2R(angle)) * Radius"
Print "    PSET (x,y)"
Print "NEXT"
Print
Print
Color _RGB32(255, 0, 0)
Print "And we don't make a circle!!"
Color -1
Print
Print "ARGH!!  Why the heck is he teaching us how to NOT make a circle?"
Print "WHY didn't that make a circle??"

clip$ = "SCREEN 12" + Chr$(10) + "COLOR 4" + Chr$(10) + "Radius = 50" + Chr$(10)
clip$ = clip$ + "FOR angle = 1 TO 360 '1 point on the circle for each degree" + Chr$(10)
clip$ = clip$ + "x = SIN(_D2R(angle)) * Radius 'we have to convert degree to radian for computer math, thus _D2R" + Chr$(10)
clip$ = clip$ + "y = COS(_D2R(angle)) * Radius" + Chr$(10)
clip$ = clip$ + "PSET (x, y)" + Chr$(10)
clip$ = clip$ + "NEXT"
_Clipboard$ = clip$
Print
Print
Print "If you're using a Windows machine to run this, open a second version of QB64 and test it out"
Print "for yourself."
Print "I've made the process as simple as possible:  Just open a new QB64 window, hit Ctrl-V to paste"
Print "and then compile and run.  I've already loaded your clipboard with a sample program all set to run!"
Print
Print
Print "For you Linux folks (whom clipboard support doesn't work fully for yet with GL), or for those"
Print "who don't want to test the results themselves..."
Print
Print "The reason this fails is simple:"
Print "We just calculated our circle, but forgot to plot it RELATIVE TO THE CENTER!"
Print
Print
Print "x and y were how far right and up we had to go from the CENTER to draw our circle (or arc for a"
Print "partial segment) -- and we didn't calculate for that."
Print
Print "What we'd want to do is change the PSET line to include that center coordinate."
Print "Something like this should work:  PSET (Xcenter + x, Ycenter + y)"
Print
Print "Then we just set that Xcenter and YCenter to wherever we want the center point of our circle to be"
Print "and we can draw it onto our screen!"
Print
Print
Print
Print "Now, that wasn't TOO terrible was it?"
Print
Print "I feel like I've rushed part of this, and have skipped over several things that would potentially be"
Print "very useful to people in the long run (like Opposite ^ 2 + Adjacent ^ 2 = Hypotenuse ^ 2), but I"
Print "wanted to toss together the very basics of SIN/COS, what they are, and how we use them for a circle"
Print "in our programming."
Print
Print
Print "I'm still going to be busy for the next few weeks, but I hope this helps people get a start on"
Print "learning what these commands are, and how they relate to our circles for us."
Print
Print
Print "Keep an eye open, and once my time frees up once more, I'll expand this even more and try and add"
Print "some interactive demostrations for everyone to play around with."
Print
Print "Like most projects, I don't know if it'll ever get finished."
Print
Print
Print "Look for the next update...."
Print
Print "SOON(tm) !!"


y = 0: Part = 1

_Dest ws
Do
    _Limit 60
    _PutImage (0, 0)-(800, 600), ts, ws, (0, y)-Step(800, 600)
    k = _KeyHit
    Button = MouseClick: MK = 0
    Select Case Button
        Case 1: k = 19712: MK = -1
        Case 2: k = 19200: MK = -1
        Case 4: k = 18432: MK = -1
        Case 5: k = 20480: MK = -1
    End Select
    If k = 27 Then System
    If MK Then Scroll = 25 Else Scroll = 10
    Select Case Part
        Case 1
            Select Case k
                Case 18432: y = y - Scroll: If y < 0 Then y = 0
                Case 20480: y = y + Scroll: If y > 700 Then y = 700
                Case 19712: Part = 2: y = 1300
            End Select
        Case 2
            Select Case k
                Case 18432: y = y - Scroll: If y < 1300 Then y = 1300
                Case 20480: y = y + Scroll: If y > 2200 Then y = 2200
                Case 19712: Part = 3: y = 2800
                Case 19200: Part = 1: y = 0
            End Select
        Case 3
            Select Case k
                Case 18432: y = y - Scroll: If y < 2800 Then y = 2800
                Case 20480: y = y + Scroll: If y > 5000 Then y = 5000
                Case 19200: Part = 2: y = 1300
            End Select

    End Select

    _Display
    Cls
Loop



Sub CenterText (y, text$)
    l = _PrintWidth(text$)
    w = _Width
    x = (w - l) \ 2
    _PrintString (x, y), text$
End Sub

Function MouseClick%
    Do While _MouseInput 'check mouse status
        scroll% = scroll% + _MouseWheel ' if scrollwheel changes, watch the change here
        If _MouseButton(1) Then 'left mouse pushed down
            speedup = 1
        ElseIf _MouseButton(2) Then 'right mouse pushed down
            speedup = 2
        ElseIf _MouseButton(3) Then 'middle mouse pushed down
            speedup = 3
        End If
        If speedup Then 'buton was pushed down
            mouseclickxxx1% = _MouseX: mouseclickyyy1% = _MouseY 'see where button was pushed down at
            Do While _MouseButton(speedup) 'while button is down
                i% = _MouseInput
            Loop 'finishes when button is let up
            If mouseclickxxx1% >= _MouseX - 2 And mouseclickxxx1% <= _MouseX + 2 And mouseclickyyy1% >= _MouseY - 2 And mouseclickyyy1% <= _MouseY + 2 Then 'if mouse hasn't moved (ie  clicked down, dragged somewhere, then released)
                MouseClick% = speedup
            Else
                MouseClick% = 0
            End If
        End If
    Loop
    If scroll% < 0 Then MouseClick% = 4
    If scroll% > 0 Then MouseClick% = 5
End Function


Arrow keys or mouse to navigate.  It short and to the point, so I don't think anyone will have issues following or understanding this.  Wink
Reply
#2
This is cool! I need to read up on how you made a scrolling console window like that.

This is nifty @SMcNeill

I haven't read the tutorial because I just got off of work and my brain is fried and I'm tired.

I will read it some day when I need to understand more about COS and SIN.
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#3
(05-16-2024, 10:08 PM)grymmjack Wrote: This is cool! I need to read up on how you made a scrolling console window like that.

This is nifty @SMcNeill

I haven't read the tutorial because I just got off of work and my brain is fried and I'm tired.

I will read it some day when I need to understand more about COS and SIN.

The scrolling window isn't anything impressive, once you learn the secret behind it.  I tend to lazily make use of stufff like this in a lot of different programs.   Here's the trick:

ts = _NewImage(800, 6000, 32)
ws = _NewImage(800, 600, 32)
Screen ws

_Dest ts

Two screens -- ts (temp screen) and ws (work screen). If you notice, ws is the actual screen that we display and show to the user, while ts is the screen that we work with, and which all our PRINT/COLOR/LINE/ect statements take place on.

(also notice that the temp screen (ts) is the same width, but 10 times longer than the display screen (ws).)

...

And, in our main program loop, we have this little tidbit which rounds out the process:

_PutImage (0, 0)-(800, 600), ts, ws, (0, y)-Step(800, 600)

We basically take a segment of the tempscreen (ts) and place it on the workscreen (ws), starting at whatever Y position we want for that tempscreen.

So if y is 0, the work screen is showing (0,0)-(800,600).... The top of the temp screen.

Press the down arrow, increment Y by 100, and not the work screen is showing (0,100)-(800,700)... The temp screen scrolled down that 100 pixels.



That's honestly all there is to that simple little voodoo trick! Quick. Easy to set up and implement. And useful as heck in organizing and displaying longer screens of text than what you can normally display on a single screen.

Nothing tricky at all to learn here. It's just a very simple little putimage of a portion of a longer image onto a shorter one, without any scaling/stretching or whatnot affecting things. Smile
Reply
#4
(05-16-2024, 10:41 PM)SMcNeill Wrote:
(05-16-2024, 10:08 PM)grymmjack Wrote: This is cool! I need to read up on how you made a scrolling console window like that.

This is nifty @SMcNeill

I haven't read the tutorial because I just got off of work and my brain is fried and I'm tired.

I will read it some day when I need to understand more about COS and SIN.

The scrolling window isn't anytime impressive, once you learn the secret behind it.  I tend to lazily make use of stufff like this in a lot of different programs.   Here's the trick:

ts = _NewImage(800, 6000, 32)
ws = _NewImage(800, 600, 32)
Screen ws

_Dest ts

Two screens -- ts (temp screen) and ws (work screen).  If you notice, ws is the actual screen that we display and show to the user, while ts is the screen that we work with, and which all our PRINT/COLOR/LINE/ect statements take place on.

(also notice that the temp screen (ts) is the same width, but 10 times longer than the display screen (ws).)

...

And, in our main program loop, we have this little tidbit which rounds out the process:

    _PutImage (0, 0)-(800, 600), ts, ws, (0, y)-Step(800, 600)

We basically take a segment of the tempscreen (ts) and place it on the workscreen (ws), starting at whatever Y position we want for that tempscreen.

So if y is 0, the work screen is showing (0,0)-(800,600).... The top of the temp screen.

Press the down arrow, increment Y by 100, and not the work screen is showing (0,100)-(800,700)...  The temp screen scrolled down that 100 pixels.



That's honestly all there is to that simple little voodoo trick!  Quick.  Easy to set up and implement.  And useful as heck in organizing and displaying longer screens of text than what you can normally display on a single screen.

Nothing tricky at all to learn here.  It's just a very simple little putimage of a portion of a longer image onto a shorter one, without any scaling/stretching or whatnot affecting things.  Smile

Wow, even I can understand that!
This bears further investigation (for me).
Thanks Steve. Cool
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Please visit my Website at: http://oldendayskids.blogspot.com/
Reply
#5
>"Now, image taking this triangle..."

Imagine that! Big Grin 

Pete

- I never make typos. I have people who do that for me!
Reply
#6
not bad Steve, you could throw in a couple more formulas, namely

the rotation matrix -- rotate any point (x,y) along the origin:
Code: (Select All)
newx = x*cos(angle) - y*sin(angle)
newy = x*sin(angle) + y*cos(angle)
bonus points if you derive it from scratch

and also, using trig to model any kind of oscillatory behavior, a radians crash course
Code: (Select All)
y = A * sin ( 2*pi * f * t )
where A is amplitude, or "height" of the sine wave, f for frequency or oscillation cycles/time with t being time or some other free parameter

and that's a fair overview of most of the trig you might require as a programmer
Reply




Users browsing this thread: 1 Guest(s)