Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 483
» Latest member: aplus
» Forum threads: 2,795
» Forum posts: 26,315

Full Statistics

Latest Threads
GNU C++ Compiler error
Forum: Help Me!
Last Post: eoredson
6 hours ago
» Replies: 2
» Views: 82
Fast QB64 base64 encoder ...
Forum: a740g
Last Post: a740g
9 hours ago
» Replies: 3
» Views: 439
Mean user base makes Stev...
Forum: General Discussion
Last Post: bobalooie
10 hours ago
» Replies: 7
» Views: 195
What do you guys like to ...
Forum: General Discussion
Last Post: bplus
11 hours ago
» Replies: 1
» Views: 36
_IIF limits two question...
Forum: General Discussion
Last Post: bplus
11 hours ago
» Replies: 6
» Views: 111
DeflatePro
Forum: a740g
Last Post: a740g
Today, 02:11 AM
» Replies: 2
» Views: 66
New QBJS Samples Site
Forum: QBJS, BAM, and Other BASICs
Last Post: dbox
Yesterday, 06:16 PM
» Replies: 25
» Views: 895
Raspberry OS
Forum: Help Me!
Last Post: Jack
Yesterday, 05:42 PM
» Replies: 7
» Views: 155
InForm-PE
Forum: a740g
Last Post: Kernelpanic
Yesterday, 05:22 PM
» Replies: 80
» Views: 6,158
Merry Christmas Globes!
Forum: Programs
Last Post: SierraKen
Yesterday, 03:46 AM
» Replies: 10
» Views: 141

 
  How about some vector noodles?
Posted by: TerryRitchie - 05-13-2024, 03:30 PM - Forum: Programs - Replies (22)

Just noodling around today with vectors. Came up with this little interesting toy.

Code: (Select All)
'Vector noodling

' Move mouse to attract particles
' Press left mouse button to repel particles

CONST PARTICLES = 250000 ' maximum number of particles
CONST SWIDTH = 960 '       screen width
CONST SHEIGHT = 540 '      screen height
CONST MASS = 25 '          mass of particles

TYPE PARTICLE '            PARTICLE PROPERTIES
    x AS SINGLE '          y location
    y AS SINGLE '          x location
    xv AS SINGLE '         y vector
    yv AS SINGLE '         x vector
END TYPE

DIM Particle(PARTICLES - 1) AS PARTICLE ' create particles
DIM p AS LONG '                           particle counter
DIM d AS SINGLE '                         distance between particle and mouse
DIM xv AS SINGLE '                        x vector from particle to mouse
DIM yv AS SINGLE '                        y vector from particle to mouse
DIM Circ AS LONG '                        picture of a solid circle

Circ = _NEWIMAGE(11, 11, 32) '            picture canvas
_DEST Circ '                              craw circle
CIRCLE (5, 5), 5
PAINT (5, 5)

RANDOMIZE TIMER
DO '                                      randomize particles
    Particle(p).x = RND * SWIDTH
    Particle(p).y = RND * SHEIGHT
    Particle(p).xv = RND - RND
    Particle(p).yv = RND - RND
    p = p + 1
LOOP UNTIL p = PARTICLES

SCREEN _NEWIMAGE(SWIDTH, SHEIGHT, 32) '   start the madness
_MOUSEHIDE
DO
    CLS
    _LIMIT 120
    p = 0
    DO
        PSET (Particle(p).x, Particle(p).y) '                          draw particle
        WHILE _MOUSEINPUT: WEND
        d = _HYPOT(_MOUSEX - Particle(p).x, _MOUSEY - Particle(p).y) ' distance to mouse
        xv = (_MOUSEX - Particle(p).x) / d '                           x vector to mouse
        yv = (_MOUSEY - Particle(p).y) / d '                           y vector to mouse
        IF _MOUSEBUTTON(1) THEN '                                      left mouse button?
            Particle(p).xv = (Particle(p).xv - xv) / d * MASS '        yes, repel
            Particle(p).yv = (Particle(p).yv - yv) / d * MASS
        ELSE '                                                         no
            Particle(p).xv = (Particle(p).xv + xv) / d * MASS '        attract
            Particle(p).yv = (Particle(p).yv + yv) / d * MASS
        END IF
        Particle(p).x = Particle(p).x + Particle(p).xv '               add vector velocity to x
        Particle(p).y = Particle(p).y + Particle(p).yv '               add vector velocity to y
        IF Particle(p).x < 0 THEN '                                    keep particles on screen
            Particle(p).x = 0
        ELSEIF Particle(p).x > SWIDTH - 1 THEN
            Particle(p).x = SWIDTH - 1
        END IF
        IF Particle(p).y < 0 THEN
            Particle(p).y = 0
        ELSEIF Particle(p).y > SHEIGHT - 1 THEN
            Particle(p).y = SHEIGHT - 1
        END IF
        p = p + 1
    LOOP UNTIL p = PARTICLES
    _PUTIMAGE (_MOUSEX - 5, _MOUSEY - 5), Circ
    _DISPLAY
LOOP UNTIL _KEYDOWN(27)
SYSTEM

Print this item

  Extended KotD #4, #5, and #6: _CRC32, _ADLER32, _MD5$
Posted by: SMcNeill - 05-13-2024, 06:37 AM - Forum: Keyword of the Day! - Replies (4)

So three new Keywords of the Day all at once!  Aren't you guys special, or what?!!

(It's "or what", in case anyone was wondering.  You guys aren't special at all.  It's just that all three of these are basically the same thing!  Big Grin )

If you guys haven't read my lesson on CHECKSUMS, kindly go do that now:  https://qb64phoenix.com/forum/showthread.php?tid=2674

The reason I wrote that little lesson for checksums, is simply because that's all each of these functions are -- varios methods to generate checksums for data.

_CRC32 is a *VERY* common method used to generate checksums -- if you guys have ever opened a ZIP, RAR, or 7Z archive and looked at the individual files, you'll see that everyone one of them has a _CRC32 value for them.  That value is basically their checksum that the file generated BEFORE compression, and it's the same value that it should generate AFTER decompression.  If the before and after values don't match, then that file is corrupted and isn't the same as what it was supposed to be originally!!

_ADLER32 is another common checksum that I've ran into and used dozen of times.  PNG-format image files are compressed, and PNG uses _ADLER32 to check the integretity of those files, much as ZIP uses _CRC32.

_MD5$ was once used as a secure checksum method, but then it was discovered that it actually doesn't generate unique values.  (Like in my post I linked to above, where I generally discuss checksum, "ABC" might have a value of 6, while "AAD" would also have that same value of 6.)  This lack of weakness in security has most security experts yelling and screaming, "GAH!! DON'T USE IT!!"...   and the rest of the world just kind of shrugs and goes, "Ehh...  It's good enough for my needs."   _MD5$ is *still* used as a checksum for all sorts of things, so it's still a very common method to see out in the wild world of programming.  I wouldn't use it for trying to store or transfer something like bank passwords, but as a log-in checksum for one of the games I write in QB64PE??   SURE!!  WTH not?  Tongue

All three methods are quite common and in constant usage for generating checksums for various things, and honestly, that's the BASIC reason why we included them into the language for folks to use.  WE -- as in you, and me, and anyone who uses QB64PE -- are already using each of the checksums at some point in our program.   Ever load a PNG file for use with _LOADIMAGE in QB4PE?  Use _Deflate or_Inflate?  Https communications?  Various routines in our user libraries *ALREADY* require the use of these routines, so it just makes sense to uncover these and make them available for our user-base as well.

As I mentioned before, and as the wiki mentions for each of these -- the way they work is really quite simple:

Send them a string of data, they send you back a checksum for that data.

Honestly, that's all there is to these things!!

And the purpose of this checksum?  Basically just a quick data-intregrity check.  That's all there is to it. Big Grin

If I pass you a 3 digit string, then ask you to pass me back the _CRC32 checksum that you got from that string, I'll instantly know if you got all the data properly, or if there was packet loss, or if what you got was corrupted or instantly infected via a virus from your machine....   If the checksum you generate doesn't match the number I generated before I sent it to you, then that file has been altered/corrupted in some manner!!

That's what checksums basically do for us, and that's what all three of these commands do -- you send them a string, they send you a checksum that you can later use to validate that the string hasn't changed from what it was when you grabbed that checksum of it.

Simple enough.  Right?  Wink

Print this item

  Is this a bug?
Posted by: TerryRitchie - 05-12-2024, 12:38 AM - Forum: General Discussion - Replies (6)

I just spent an hour tearing my hair out trying to track down a syntax error that the IDE failed to report. My need to comment everything bit me in the butt this time.

I accidentally placed a comment after a DATA statement. The line of code containing the READ statement kept failing with a syntax error after executing the code. The code worked fine, I made a few comments, ate supper, came back, and the code didn't work.

At first I thought my cat was playing a prank on me ... typing something in while I'm not looking! Hey, it's happened before! They love to walk on keyboards.

But I FINALLY figured out what was going on.

Is it a bug that the IDE does not catch a comment being placed after a DATA statement?

Print this item

  Add buttons to _MESSAGEBOX function?
Posted by: tothebin - 05-11-2024, 05:53 AM - Forum: Help Me! - Replies (4)

The _MESSAGEBOX function has been a major improvement for me. Is there any way to add or change the default buttons? Being able to have buttons such as [Help] or [Quit] would be extremely useful. With the right buttons some of my utility programs wouldn't need any other type of GUI.

Print this item

  Got a slow PC? Test these changes, kindly!
Posted by: SMcNeill - 05-11-2024, 03:32 AM - Forum: General Discussion - Replies (7)

@TerryRitchie You were asking about how the IDE slows down once you get to about 3000+ lines of code in it.   Here's a very simple fix, which seems to drastically cut down on that lag for my system.  Give it a try, if you will.  (And anyone else who wants to as well, as it'd be nice to make certain this doesn't break anything before trying to work it into the repo.)

To test this:

1) Have a version of the latest source from the repo (or at least from v3.13+)
2) Grab this file here:  
.bas   ide_methods.bas (Size: 842.52 KB / Downloads: 88)
3) Go to your QB64PE folder, navigate to source/ide and rename ide_methods.bas to something like ide_methods.bak.
4) Move the file you downloaded to that QB64PE/source/ide folder and let it take the place of that old file.
5) Start QB64PE, open source/qb64pe.bas and build yourself a new version of qb64pe.  I'd imagine this should be named QB64PE(2).EXE or similar.
  --- note:  *DON'T have the "PUT EXE IN SOURCE FOLDER" option clicked.
6) If you didn't see the note above, move the QB64PE(2).exe from the source folder to the main folder.  Tongue
7) Test it with anything and everything that you want to test it with.

See if the IDE is more responsive.  If it pastes code faster than it did before (CTRL-V) into the IDE.  If your 20000 line program gets sluggish and lags behind your typing, or if it now keeps up with it better.

Personally, I think this is giving me quite an improvement as even 100,000 lines programs now keep up with my typing and such, without lagging behind like they used to sometimes -- but I've got a fairly high end PC and for the last year or so, that lag has been minimal at best for me.

Let me know if any of you guys notice any changes at all -- for better, or worse, or even if I broke something terribly (which I'm certainly more than capable of doing -- and have done to our poor source more than once.  Big Grin ).  If things are an improvement, I'll see about pushing the changes into the repo to maybe help the IDE perform a little better for folks in the next release.

Print this item

  Ronning out of Undo
Posted by: PhilOfPerth - 05-11-2024, 12:09 AM - Forum: Site Suggestions - Replies (12)

While the Undo is extremely useful for recovering from a faux-pas (and that's quite frequent for me), there doesn't seem to be
 an indication when you've used up all your Undo's. When this involved back-tracking over a number of  changes, you may reach 
the limit, and no changes are made. This can be hard to see with a long programme, as  changes may not be obvious in the IDE.
Is there, or can there be, a "Limit of Undo" message?

Print this item

  A little bit of spark fun today
Posted by: TerryRitchie - 05-10-2024, 10:43 PM - Forum: Programs - Replies (2)

I thought I would take a day off from creating new tutorial material and update some old. In lesson 18 there is a spark particle physics generator that I wrote way back in 2012 when I was still relatively new to QB64. I plan to eventually go through all the old code I wrote in the tutorial and update it with new (and better) techniques I have learned over the years.

Here is the new spark particle physics generator. Have fun.

WHY when I post code using the Export As Forum Codebox does the spacing get messed up as seen below?? Am I doing something wrong or is their a bug somewhere?

Code: (Select All)
'+---------------------------------------------+
'|                Sparks! 2.0                  |
'|                    by                      |
'|              Terry Ritchie                |
'|                05/10/24                    |
'|                                            |
'| Updated for Lesson 18 of the QB64 tutorial  |
'|      https://www.qb64tutorial.com          |
'|                                            |
'| Sparks! 1.0 was written back in 2012 when I |
'| was still relatively new to QB64. This new  |
'| version incorporates coding techniques I    |
'| have learned since then.                    |
'|                                            |
'| This version of Sparks! uses an image of a  |
'| spark instead of drawing the sparks using  |
'| multiple PSET statements. Other speed      |
'| enhancements were also implemented.        |
'+---------------------------------------------+

OPTION _EXPLICIT '        declare all variables

TYPE SPARK '              SPARK PROPERTIES
    x AS SINGLE '        x location of spark
    y AS SINGLE '        y location of spark
    xVec AS SINGLE '      x vector of spark
    yVec AS SINGLE '      y vector of spark
    xVel AS SINGLE '      x velocity of spark
    yVel AS SINGLE '      y velocity of spark
    Fade AS SINGLE '      spark brightness
    Fader AS SINGLE '    spark brightness fader
    Alive AS INTEGER '    spark life countdown timer
    Image AS LONG '      spark image
END TYPE

REDIM Spark(0) AS SPARK ' create spark array
DIM x AS INTEGER '        x location of new spark(s)
DIM y AS INTEGER '        y location of new spark(s)
DIM xv AS SINGLE '        x vector to add to spark(s)
DIM yv AS SINGLE '        y vector to add to spark(s)
DIM Hyp AS SINGLE '      length between mouse x,y and spark(s) x,y

'+-------------------------+
'| Begin main demo program |
'+-------------------------+

SCREEN _NEWIMAGE(640, 480, 32) '                        enter graphics screen
_MOUSEHIDE '                                            hide the mouse pointer
DO '                                                    begin main program loop
    _LIMIT 60 '                                          60 frames per second
    CLS '                                                clear screen
    LOCATE 2, 28: PRINT "SPACEBAR TO SHOOT SPARKS" '    display instructions
    LOCATE 4, 27: PRINT "USE MOUSE TO MOVE REPULSER"
    LOCATE 6, 26: PRINT "LEFT MOUSE BUTTON TO REPULSE"
    LOCATE 8, 30: PRINT "ESC TO LEAVE PROGRAM"
    WHILE _MOUSEINPUT: WEND '                            get latest mouse update
    CIRCLE (_MOUSEX, _MOUSEY), 10 '                      draw repulser
    IF _KEYDOWN(32) THEN '                              is spacebar down?
        x = RND * 640 '                                  yes, x location of new spark(s)
        y = RND * 480 '                                  y location of new spark(s)
        IF _MOUSEBUTTON(1) THEN '                        left mouse button down?
            Hyp = _HYPOT(_MOUSEX - x, _MOUSEY - y) '    yes, get distance from mouse to spark(s)
            xv = (x - _MOUSEX) / Hyp '                  create normalized x vector to add
            yv = (y - _MOUSEY) / Hyp '                  create normalized y vector to add
        ELSE '                                          no, left mouse button is not down
            xv = 0 '                                    no x vector will be added
            yv = 0 '                                    no y vector will be added
        END IF
        MakeSpark 50, 60, xv, yv, x, y '                create the spark(s)
    END IF
    UpdateSpark '                                        update any live spark(s)
    _DISPLAY '                                          update the screen with changes
LOOP UNTIL _KEYDOWN(27) '                                leave when ESC key pressed
SYSTEM '                                                return to the operating system

'+-----------------------+
'| End main demo program |
'+-----------------------+

'------------------------------------------------------------------------------------------------------------
SUB UpdateSpark () ' spark maintainer

    '+-------------------------------------------------------------------------------------------------+
    '| Scans the spark array for active sparks and updates their properties. Will also reset the spark |
    '| array when no active sparks are found.                                                          |
    '+-------------------------------------------------------------------------------------------------+

    CONST WHITE~& = _RGBA32(255, 255, 255, 255) ' full opaque white
    SHARED Spark() AS SPARK '                    need access to spark array
    DIM Index AS LONG '                          array index counter
    DIM NoLife AS INTEGER '                      flag to reset array when dead

    IF UBOUND(Spark) = 0 THEN EXIT SUB '                                            leave if array empty
    NoLife = -1 '                                                                    assume array has no life
    DO '                                                                            begin spark update loop
        Index = Index + 1 '                                                          increment index counter
        IF Spark(Index).Alive THEN '                                                is this spark alive?
            NoLife = 0 '                                                            yes, array has life
            _PUTIMAGE (Spark(Index).x - 1, Spark(Index).y - 1), Spark(Index).Image ' draw spark image
            Spark(Index).Alive = Spark(Index).Alive - 1 '                            decrement spark life
            IF Spark(Index).Alive THEN '                                            is spark still alive?
                Spark(Index).Fade = Spark(Index).Fade - Spark(Index).Fader '        yes, update brightness
                Spark(Index).x = Spark(Index).x + Spark(Index).xVec * Spark(Index).xVel ' update x location
                Spark(Index).y = Spark(Index).y + Spark(Index).yVec * Spark(Index).yVel ' update y location
                Spark(Index).xVel = Spark(Index).xVel * .95 '                        update spark x velocity
                Spark(Index).yVel = Spark(Index).yVel * .95 '                        update spark y velocity
                _SETALPHA INT(Spark(Index).Fade), 0 TO WHITE, Spark(Index).Image '  set image brightness
            ELSE '                                                                  no, spark is now dead
                _FREEIMAGE Spark(Index).Image '                                      free image from RAM
            END IF
        END IF
    LOOP UNTIL Index = UBOUND(Spark) '                                              leave at top of array
    IF NoLife THEN REDIM Spark(0) AS SPARK '                                        reset array if no life

END SUB
'------------------------------------------------------------------------------------------------------------
SUB MakeSpark (num AS INTEGER, ttl AS INTEGER, xv AS SINGLE, yv AS SINGLE, x AS INTEGER, y AS INTEGER)

    '+--------------------------------------------------+
    '| Enters sparks into the spark array.              |
    '|                                                  |
    '| num - number of sparks to create                |
    '| ttl - spark time to live                        |
    '| xv  - x vector to be added to spark (0 for none) |
    '| xy  - y vector to be added to spark (0 for none) |
    '| x  - x location of spark(s)                    |
    '| y  - y location of spark(s)                    |
    '+--------------------------------------------------+

    SHARED Spark() AS SPARK ' need access to spark array
    STATIC Image AS LONG '    persistent spark image
    DIM Index AS LONG '      array index counter
    DIM Dest AS LONG '        current destination image

    '+------------------------------------------------------+
    '| Draw spark image the first time subroutine is called |
    '+------------------------------------------------------+

    IF Image > -2 THEN '                            has spark image been created?
        Image = _NEWIMAGE(3, 3, 32) '                no, create spark image canvas  +---+---+---+
        Dest = _DEST '                              get current destination image  | G | W | G |
        _DEST Image '                                draw on spark image canvas      +---+---+---+
        CLS , _RGB32(64, 64, 64) '                  gray corners                    | W |BW | W |
        LINE (1, 0)-(1, 2), _RGB32(128, 128, 128) '  white outer vertical centers    +---+---+---+
        LINE (0, 1)-(2, 1), _RGB32(128, 128, 128) '  white outer horizontal centers  | G | W | G |
        PSET (1, 1), _RGB32(255, 255, 255) '        bright white center            +---+---+---+
        _DEST Dest '                                restore destination image
    END IF

    '+-------------------------------+
    '| Add sparks to the spark array |
    '+-------------------------------+

    Index = UBOUND(Spark) '                          get last index of array
    REDIM _PRESERVE Spark(Index + num) AS SPARK '    add new sparks to top of array
    RANDOMIZE TIMER '                                seed random number generator
    DO '                                            begin spark addition loop
        Index = Index + 1 '                          increment index counter
        Spark(Index).Alive = ttl '                  spark time to live
        Spark(Index).x = x '                        x location of spark
        Spark(Index).y = y '                        y location of spark
        Spark(Index).Fade = 255 '                    initial brightness
        Spark(Index).Fader = 255 / ttl '            brightness fader value
        Spark(Index).xVel = 9 + RND * 6 '            random x velocity
        Spark(Index).yVel = 6 + RND * 6 '            random y velocity
        Spark(Index).xVec = RND - RND + xv '        random x vector plus passed in x vector
        Spark(Index).yVec = RND - RND + yv '        random y vector plus passed in y vector
        Spark(Index).Image = _COPYIMAGE(Image, 32) ' copy the spark image
    LOOP UNTIL Index = UBOUND(Spark) '              leave when top of array reached

END SUB

Print this item

  Steve's Lesson on Checksums
Posted by: SMcNeill - 05-10-2024, 06:33 PM - Forum: Learning Resources and Archives - No Replies

From time to time, anyone who works or plays on a computer is going to hear the term: checksums.

Do me a favor:  **Never try to look up the definition of a checksum.**

For some insane reason, you'll find folks trying to define checksums by saying they're, "a string of cryptographic representations of hashed data of unique representations of blah blah blah..." 

WTH?!!

A monkey on LSD couldn't decipher what the frick some of these guys are trying to say!!   Talk about overtalking a subject!!

All a checksum is.... dum dum de dumm....  is a SUM of values that can be used to CHECK the validity of something.

OMG!!   That was soooooooooooo hard to explain!!


Now, let me give you guys a few examples of the world's simplest checksums.

For starters, let's assign a few quick values to our uppercase alphabet.  I bet most of you can quickly figure these values out:
A = 1
B = 2
C = 3
...
X = 24
Y = 25
Z = 26

Now we're going to write a quick checksum to check for invalid input.  To do this, we're going to come up with some super-duper-Steve-approved-complex-math...   We're just going to add the values together.

So let's say you send me some data:
"ABC".....  I add the values together.  I get 1 + 2 + 3 = 6.   My checksum is now 6.

You send me some different data:
"XYZ"....  I add the values together.  I get 24 + 25 + 26 = 75.  My checksum is now 75.

Now, there are different ways that I can deal with this checksum.  One is you can send me the value that I'm expected to have, and I can simply compare it to the value I got.  You'll see this method a lot of times when downloading files.

Download this file...  checksums are blahblahblah...   You download the file, run the check on the sums, and see if they match.  If they do, then chances are your data/download is good and valid.  If they don't match, then someone hijacked the download and you may have infected files. Or a corrupted download.  Or whatever...  The thing is, you didn't get the correct data!


Another way you often see checksums in use is as an built-in data verifier.

Have you ever gotten a bill and had it look something like Account Number: 123-45-6789-2D?

Chances are, that account number has a built in checksum to it.  The first 9 digits may be your social security number, while those last 2 digits are the hex representation of those numbers added together.

1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45...  which is 2D, if my brain translated the figures right.

When you read your account number off to the billing representative so they'll pay your damn doctor's bill, the person behind the keyboard can almost instantly know if they typed the value correctly, or if they misheard you, or whatnot.  If the two digits on the right don't add up to the sum of the first nine numbers, then it's an invalid account.


Now, of course, these are the very simplest of examples of checksums.  They're not UNIQUE checksums at all.

For example, let's compare the alphabet versions above:
"ABC" = 1 + 2 + 3 = 6
"AAD" = 1 + 1 + 4 = 6

You could tell me your name was "ABC" with 6 for a checksum.  I could screw up (man, was I drunk that day) and type in "AAD" instead, and I'd still get back the same checksum.

Obviously, my math formula could probably use a little tweaking to give more unique answers.  Big Grin

....

So, Steve, being as AMAZING as he is, decides:  EACH digit is going to multiplied by 100^digit !!
"ABC" = 1 * (100 *^1) + 2 * (100 ^ 2)  + 3 * (100 ^ 3).... or 300200100
"AAD" = 1 * (100 ^ 1) + 1 * (100 ^ 2) + 4 * (100 ^ 3)... or 400100100

See -- unique numbers there!!

Which would work fine until someone sent the data "ABCDEFGHIJKLMNO"....  oh crap! OVERFLOW ERROR!!!

.....

So that's not a very good checksum formula either, to be honest.  Big Grin

But that's why we decide to let other folks -- those crazy folks who are obsessed with math and such -- we let them come up with the formulas which we end up making the use of in most cases.

https://qb64phoenix.com/qb64wiki/index.php/CRC32
https://qb64phoenix.com/qb64wiki/index.php/ADLER32
https://qb64phoenix.com/qb64wiki/index.php/MD5$

I'll basically cover those for tomorrow's Extended Keyword of the Day, but basically all they are, are math formulas to create a checksum of whatever data you give them.

And all a checksum is, is a quick way to eliminate invalid data as easily and efficiently as possible.

"ABC" may have a checksum of six, so I might send that data to someone else as "ABC6".   If they get it and it's "ABD6", just by doing the same math as I did, it's easy to see that there's no way the data they got is going to be valid.  That last digit doesn't match the checksum of the first few digits!

Checksums.... just a means to check the value of something else.

Nothing complicated to see here, no matter how complex some folks want to try to obfuscate the definition.  Big Grin

Print this item

  Another Phoenix Basic with bird logo out there.
Posted by: Dav - 05-10-2024, 01:57 PM - Forum: General Discussion - Replies (9)

Getting into Linux more, searching out linux BASIC compilers.  Came across one with Phoenix in it's name and also a fire bird logo.  I think this use to be called Envelop basic, but changed to 'Phoenix'  not too long ago.  I wonder which 'Phoenix edition' came first, theirs or ours? 

http://biz-wise.nl/phoenix_features.html

- Dav

Print this item

  Steve's basic SIN/COS Tutorial
Posted by: SMcNeill - 05-10-2024, 09:35 AM - Forum: Learning Resources and Archives - Replies (5)

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

Print this item