Summer Banner? YES! (Submit entries until the 20th!)
#21
Hi boys and girls of QB64pe

Here an more explicative opera


[Image: qb64pe-summer.png]
Reply
#22
Below is the image for my entry in the summer banner challenge.

The attached ZIP file contains the code and images to create the banner.

The sunflower field is randomly generated. Each sunflower is created from random petal placements around a randomly created seed pod. Every time you run the code a new sunflower field is generated containing new entirely random sunflowers. The image is then saved as "SummerBanner.PNG" thanks to Steve's Image Library.

Code: (Select All)
'+---------------------------------------------------------------------------+
'| Terry's Sunflower Field Generator                                        |
'| June 14th, 2023                                                          |
'|                                                                          |
'| Creates a random sunflower field banner for the summer banner competition |
'+---------------------------------------------------------------------------+

'Steve's SaveImage Library
'$INCLUDE:'saveimage.bi'

'OPTION _EXPLICIT ' Had to disable because of library

TYPE Type_POINT '              a single coordinate
    x AS SINGLE
    y AS SINGLE
END TYPE

TYPE Type_FLOWER '            sunflower part
    Image AS LONG '            image of petal / stem
    w AS INTEGER '            width of image
    h AS INTEGER '            height of image
END TYPE

DIM Petal(14) AS Type_FLOWER ' 14 petal images
DIM Stem(14) AS Type_FLOWER '  14 stem images
DIM Seed AS LONG '            image of sunflower seed
DIM p AS INTEGER '            generic counter
DIM Degree AS SINGLE '        angle in degrees
DIM VecX(359) AS SINGLE '      precalculated sine values for degrees
DIM VecY(359) AS SINGLE '      precalculated cosine values for degrees
DIM Background AS LONG '      background image
DIM Logo AS LONG '            QB64PE logo image
DIM stepper AS INTEGER '      spacing of sunflowers in each row in field
DIM Yloc AS INTEGER '          y location of row of sonflowers in field
DIM Size AS SINGLE '          size of sunflowers in each row in field
DIM r AS INTEGER '            introduce random height variances with each sunflower in sunflower rows
DIM SaveImg AS INTEGER '      result of Steve's SaveImage library

'+---------------------------------------+
'| Precalculate rotational vector values |
'+---------------------------------------+

Degree = 0 '                                  reset degree counter
DO '                                          cycle through 360 degrees (0 to 359)
    VecX(Degree) = SIN(_D2R(Degree)) '        degree to vector calculations for matrix rotation and direction
    VecY(Degree) = -COS(_D2R(Degree)) '      degrees converted to negative radians for clockwise rotation
    Degree = Degree + 1 '                    increment degree value
LOOP UNTIL Degree = 360 '                    leave when 360 degrees calculated

'+------------------------------------------------------------------+
'| Load petal and stem images and create a mirror image of each one |
'+------------------------------------------------------------------+

FOR p = 1 TO 7 '                                                                              load 7 petal images
    Petal(p).Image = _LOADIMAGE("petal" + _TRIM$(STR$(p)) + ".png", 32) '                    load petal image
    Petal(p).w = _WIDTH(Petal(p).Image) '                                                    width of image
    Petal(p).h = _HEIGHT(Petal(p).Image) '                                                    height of image
    Petal(p + 7).Image = _NEWIMAGE(Petal(p).w, Petal(p).h, 32) '                              create image holder
    Petal(p + 7).w = Petal(p).w '                                                            width of new image
    Petal(p + 7).h = Petal(p).h '                                                            height of new image
    _PUTIMAGE , Petal(p).Image, Petal(p + 7).Image, (Petal(p).w - 1, 0)-(0, Petal(p).h - 1) ' flip image horizontally in new image holder
    Stem(p).Image = _LOADIMAGE("stem" + _TRIM$(STR$(p)) + ".png", 32) '                      load stem image
    Stem(p).w = _WIDTH(Stem(p).Image) '                                                      width of image
    Stem(p).h = _HEIGHT(Stem(p).Image) '                                                      height of image
    Stem(p + 7).Image = _NEWIMAGE(Stem(p).w, Stem(p).h, 32) '                                create image holder
    Stem(p + 7).w = Stem(p).w '                                                              width of new image
    Stem(p + 7).h = Stem(p).h '                                                              height of new image
    _PUTIMAGE , Stem(p).Image, Stem(p + 7).Image, (Stem(p).w - 1, 0)-(0, Stem(p).h - 1) '    flip image horizontally in new image holder
NEXT p

'+-----------------------+
'| Load remaining images |
'+-----------------------+

Background = _LOADIMAGE("background.png", 32) '                            load background imgage
Logo = _LOADIMAGE("pelogo.png", 32) '                                      load QB64PE logo image
Seed = _LOADIMAGE("seed.png", 32) '                                        load seed image

'+---------------+
'| Begin Program |
'+---------------+

SCREEN Background '                                                        1400x256 screen
RANDOMIZE TIMER '                                                          randomize

'+------------------------+
'| Create sunflower field |
'+------------------------+

stepper = 8 '                                                              set sunflower spacing
Yloc = 128 '                                                                set sunflower row location
Size = .05 '                                                                set sunflower size
r = 5 '                                                                    set random sunflower height variance
DO '                                                                        start making sunflower rows
    FOR p = 0 TO 1400 STEP stepper '                                        create a row with pre-determined sunflower spaceing
        MakeFlower p, Yloc + INT((RND - RND) * r), Size '                  draw a sunflower on the background
    NEXT p
    Yloc = Yloc + 10 '                                                      move next sunflower row down
    stepper = stepper + 5 '                                                increase sunflower spacing
    Size = Size + .025 '                                                    increase size of sunflowers
    r = r + 2 '                                                            increase height variance
LOOP UNTIL Yloc > 280 '                                                    leave when all rows created
_PUTIMAGE (25, 30), Logo '                                                  draw QB64PE logo images
_PUTIMAGE (1240, 30), Logo
SaveImg = SaveImage("SummerBanner.png", 0, 0, 0, _WIDTH - 1, _HEIGHT - 1) ' save finished banner to drive
SLEEP '                                                                    wait for a key press

'+----------+
'| Clean up |
'+----------+

SCREEN 0, 0, 0, 0 '            go to screen 0
CLS '                          clear the screen
FOR p = 1 TO 14 '              cycle through images
    _FREEIMAGE Petal(p).Image ' remove petal images
    _FREEIMAGE Stem(p).Image '  remove stem images
NEXT p
_FREEIMAGE Background '        remove remaining images
_FREEIMAGE Logo
_FREEIMAGE Seed
SYSTEM '                                                                    return to operating system

' ______________________________________________________________________________________________________________________________________________
'/                                                                                                                                              \
SUB MakeFlower (x AS INTEGER, y AS INTEGER, Zoom AS SINGLE) '                                                                        MakeFlower |
    ' __________________________________________________________________________________________________________________________________________|____
    '/                                                                                                                                              \
    '| Creates a sunflower the hard way                                                                                                              |
    '\_______________________________________________________________________________________________________________________________________________/

    SHARED Petal() AS Type_FLOWER ' petal images
    SHARED Stem() AS Type_FLOWER '  stem images
    SHARED Origin AS Type_POINT '  rotation origin
    SHARED pPoint AS Type_POINT '  a single coordinate
    SHARED Seed AS LONG '          seed image
    DIM Degree AS SINGLE '          angle in degrees
    DIM p AS INTEGER '              generic counter
    DIM pp AS INTEGER '            generic counter
    DIM InImg AS LONG '            image returned from rotozoom
    DIM Flower AS LONG '            flower image
    DIM Stem AS LONG '              stem image (flower image gets placed on top)
    DIM r AS INTEGER '              random stem image

    '+--------------------------------------+
    '| Create flower and stem image holders |
    '+--------------------------------------+

    Flower = _NEWIMAGE(221, 221, 32) '                          create flower image holder
    r = INT(RND * 14) + 1 '                                      get random stem number
    Stem = _NEWIMAGE(Stem(r).w, Stem(r).h + 140, 32) '          create stem image holder
    _PUTIMAGE (0, 140), Stem(r).Image, Stem '                    place stem image onto lower portion of stem image holder
    _DEST Flower '                                              draw on flower image

    '+---------------+
    '| Create petals |
    '+---------------+

    Origin.x = 110 '                                            rotation origin point
    Origin.y = 110
    pPoint.x = 110 '                                            location of point that rotates
    pPoint.y = Origin.y - 70
    Degree = 0 '                                                reset degree angle
    FOR pp = 1 TO 2 '                                            2 layers of petals
        FOR p = 1 TO 24 '                                        24 petals on each later
            Rotate pPoint, 15, Origin '                          rotate point 15 degrees
            Degree = Degree + 15 '                              increase degree angle by 15 degrees
            InImg = _COPYIMAGE(Petal(INT(RND * 14) + 1).Image) ' create a copy of a random petal image
            __ROTOZOOM_IMAGE InImg, Degree, 1 '                  rotate the petal image
            _PUTIMAGE (pPoint.x - _WIDTH(InImg) / 2, pPoint.y - _HEIGHT(InImg) / 2), InImg ' draw rotated petal image onto flower image holder
            _FREEIMAGE InImg '                                  free the image copy
        NEXT p
        Rotate pPoint, 7.5, Origin '                            rotate the point half of 15 degrees for next layer
        Degree = 7 '                                            set degree angle equal to 7
        pPoint.y = Origin.y - 50 '                              move this row of petals in closer to the center
    NEXT pp

    '+-----------------+
    '| Create seed pod |
    '+-----------------+

    pPoint.x = 110 '                                            new rotation origin point
    pPoint.y = Origin.y - 3
    Degree = 0 '                                                reset degree angle
    FOR pp = 1 TO 16 '                                          16 rows of seeds
        FOR p = 1 TO 120 '                                      120 seeds in each row
            Rotate pPoint, 3, Origin '                          rotate point 3 degrees
            Degree = Degree + 3 '                                increase degree angle by 3 degrees
            InImg = _COPYIMAGE(Seed) '                          copy the seed image
            __ROTOZOOM_IMAGE InImg, Degree, 1 '                  rotate the seed image
            _PUTIMAGE (pPoint.x - _WIDTH(InImg) / 2, pPoint.y - _HEIGHT(InImg) / 2), InImg ' draw rotated seed image onto flower image holder
            _FREEIMAGE InImg '                                  free the image copy
        NEXT p
        Rotate pPoint, 6, Origin '                              rotate the point 6 degrees for the next row
        Degree = Degree + 6 '                                    increase degree angle by 6 degrees
        pPoint.y = pPoint.y + 3 '                                next row of seeds out a little farther
    NEXT pp
    _PUTIMAGE (Stem(r).w / 2 - 110, 0), Flower, Stem '          place the flower image on top of the stem image
    _DEST 0 '                                                    draw on background image

    '+------------------------------------------------+
    '| Zoom the flower image and draw onto background |
    '+------------------------------------------------+

    _PUTIMAGE (x - (Stem(r).w / 2) * Zoom, y - ((Stem(r).h + 140) / 2) * Zoom)-(x + (Stem(r).w / 2) * Zoom, y + ((Stem(r).h + 140) / 2) * Zoom), Stem
    _FREEIMAGE Flower '                                          free image holders created
    _FREEIMAGE Stem

END SUB
' ______________________________________________________________________________________________________________________________________________
'/                                                                                                                                              \
SUB Rotate (pPoint AS Type_POINT, AngleDeg AS SINGLE, Origin AS Type_POINT) '                                                            Rotate |
    ' __________________________________________________________________________________________________________________________________________|____
    '/                                                                                                                                              \
    '| Rotate a point around an origin using linear transformation.                                                                                  |
    '|                                                                                                                                              |
    '| Vec      : the point to rotate (NOTE these values get modified and passed back)                                                              |
    '| AngleDeg : the angle in degrees to rotate (additive)                                                                                          |
    '| Origin  : the rotation point of origin                                                                                                      |
    '\_______________________________________________________________________________________________________________________________________________/

    DIM x AS SINGLE '      location of point's x with origin at 0
    DIM y AS SINGLE '      location of point's y with origin at 0
    DIM Cosine AS SINGLE ' cosine of angle
    DIM Sine AS SINGLE '  sine of angle
    DIM xPrime AS SINGLE ' new point x location with original origin
    DIM yPrime AS SINGLE ' new point y location with original origin

    x = pPoint.x - Origin.x '            move rotation origin to 0
    y = pPoint.y - Origin.y
    Cosine = COS(_D2R(AngleDeg)) '      calculate sine and cosine of angle
    Sine = SIN(_D2R(AngleDeg))
    xPrime = (x * Cosine) - (y * Sine) ' calculate rotated location of vector
    yPrime = (x * Sine) + (y * Cosine)
    xPrime = xPrime + Origin.x '        move back to original origin
    yPrime = yPrime + Origin.y
    pPoint.x = xPrime '                  pass back rotated vector
    pPoint.y = yPrime

END SUB
' ______________________________________________________________________________________________________________________________________________
'/                                                                                                                                              \
SUB __ROTOZOOM_IMAGE (InImg AS LONG, Deg AS INTEGER, Zoom AS SINGLE) '                                                        __ROTOZOOM_IMAGE |
    ' __________________________________________________________________________________________________________________________________________|____
    '/                                                                                                                                              \
    '| Rotates and zooms an input image by the amounts specified.                                                                                    |
    '|                                                                                                                                              |
    '| __ROTOZOOM_IMAGE MyImage, 180                                                                                                                |
    '|                                                                                                                                              |
    '| InImg  - image to rotate and zoom. ImImg is modified to contain the updated rotated and zoomed image.                                        |
    '| Deg    - amount of image rotation (0 to 359)                                                                                                  |
    '| Zoom  - amount to zoom image (.5 = 50%, 1 = 100%, 1.5 = 150%, etc..)                                                                        |
    '|                                                                                                                                              |
    '| This subroutine based on code provided by Rob (Galleon) on the QB64.NET website in 2009.                                                      |
    '| Special thanks to Luke for explaining the matrix rotation formula used in this routine.                                                      |
    '\_______________________________________________________________________________________________________________________________________________/

    SHARED VecX() AS SINGLE ' need access to precalculated x vector values
    SHARED VecY() AS SINGLE ' need access to precalculated y vector values
    DIM px(3) AS INTEGER '      x vector values of four corners of image
    DIM py(3) AS INTEGER '      y vector values of four corners of image
    DIM Left AS INTEGER '        left-most value seen when calculating rotated image size
    DIM Right AS INTEGER '      right-most value seen when calculating rotated image size
    DIM Top AS INTEGER '        top-most value seen when calculating rotated image size
    DIM Bottom AS INTEGER '      bottom-most value seen when calculating rotated image size
    DIM WOutImg AS INTEGER '    width of rotated image
    DIM HOutImg AS INTEGER '    height of rotated image
    DIM WInImg AS INTEGER '      width of original image
    DIM HInImg AS INTEGER '      height of original image
    DIM CenterX AS INTEGER '    offsets used to move (0,0) back to upper left corner of image
    DIM CenterY AS INTEGER
    DIM x AS SINGLE '            new x vector of rotated point
    DIM y AS SINGLE '            new y vector of rotated point
    DIM v AS INTEGER '          vector counter
    DIM Degree AS INTEGER '      corrected input degree
    DIM OrigImg AS LONG '        temporary copy of input image

    '+-----------------------+
    '| Rotate and zoom image |
    '+-----------------------+

    OrigImg = _COPYIMAGE(InImg) '                                copy input image
    Degree = __FIX_DEGREE(Deg) '                                  keep degree within 0 to 359
    WInImg = _WIDTH(InImg) '                                      width of input image
    HInImg = _HEIGHT(InImg) '                                    height of input image
    _FREEIMAGE InImg '                                            free input image from RAM

    '+----------------------------------+
    '| Make 0,0 the center of the image |
    '+----------------------------------+

    px(0) = -WInImg / 2 * Zoom ' -x,-y ----------------- x,-y
    py(0) = -HInImg / 2 * Zoom ' py(0),|              | px(3)    Create points around (0,0)
    px(1) = px(0) '              px(0) |              | py(3)    that match the size of the
    py(1) = HInImg / 2 * Zoom '        |      .      |          original image. This
    px(2) = WInImg / 2 * Zoom '        |    (0,0)    |          creates fouor vector
    py(2) = py(1) '              px(1),|              | px(2),  quantities to work with.
    px(3) = px(2) '              py(1) |              | py(2)
    py(3) = py(0) '              -x,y ----------------- x,y

    '+--------------------------------------------------------+
    '| Perform matrix rotation on all four corner coordinates |
    '+--------------------------------------------------------+

    DO '                                                          cycle through vectors
        x = px(v) * -VecY(Degree) + -VecX(Degree) * py(v) ' perform 2D rotation matrix on vector
        y = py(v) * -VecY(Degree) - px(v) * -VecX(Degree) ' https://en.wikipedia.org/wiki/Rotation_matrix
        px(v) = x '                                              save new x vector
        py(v) = y '                                              save new y vector

        '+--------------------------------------------------------------------------------+
        '| Image size changes when rotated so remember lowest and highest x,y values seen |
        '+--------------------------------------------------------------------------------+

        IF px(v) < Left THEN Left = px(v) '                      lowest x coordinate seen
        IF px(v) > Right THEN Right = px(v) '                    highest x coordinate seen
        IF py(v) < Top THEN Top = py(v) '                        lowest y coordinate seen
        IF py(v) > Bottom THEN Bottom = py(v) '                  highest y coordinate seen
        v = v + 1 '                                              increment vector counter
    LOOP UNTIL v = 4 '                                            leave when all vectors processed (0 through 3)

    '+------------------------------------+
    '| Make 0,0 the top left of the image |
    '+------------------------------------+

    WOutImg = Right - Left + 1 '                                  calculate width of rotated image
    HOutImg = Bottom - Top + 1 '                                  calculate height of rotated image
    CenterX = WOutImg \ 2 '                                      place (0,0) in upper left corner of rotated image
    CenterY = HOutImg \ 2
    v = 0 '                                                      reset vector counter
    DO '                                                          cycle through rotated image coordinates
        px(v) = px(v) + CenterX '                                move image coordinates so (0,0) at upper left corner
        py(v) = py(v) + CenterY '                                and (width-1,height-1) at lower right
        v = v + 1 '                                              increment corner counter
    LOOP UNTIL v = 4 '                                            leave when all four vectors of image moved
    InImg = _NEWIMAGE(WOutImg, HOutImg, 32) '                    create new rotated image canvas

    '+-------------------------------------+
    '| Map triangles onto new image canvas |
    '+-------------------------------------+

    _MAPTRIANGLE (0, 0)-(0, HInImg - 1)-(WInImg - 1, HInImg - 1), OrigImg TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2)), InImg
    _MAPTRIANGLE (0, 0)-(WInImg - 1, 0)-(WInImg - 1, HInImg - 1), OrigImg TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2)), InImg
    _FREEIMAGE OrigImg '                                          free original image from RAM

END SUB
' ______________________________________________________________________________________________________________________________________________
'/                                                                                                                                              \
FUNCTION __FIX_DEGREE (Degree AS INTEGER) '                                                                                        __FIX_DEGREE |
    ' __________________________________________________________________________________________________________________________________________|____
    '/                                                                                                                                              \
    '| Normalizes degree to between 0 and 359.                                                                                                      |
    '|                                                                                                                                              |
    '| Degree = __FIX_DEGREE(-270)                                                                                                                  |
    '\_______________________________________________________________________________________________________________________________________________/

    DIM Deg AS INTEGER ' degree value passed in

    Deg = Degree '                        get passed in degree value
    IF Deg < 0 OR Degree > 359 THEN '    degree out of range?
        Deg = Deg MOD 360 '              yes, get remainder of modulus 360
        IF Deg < 0 THEN Deg = Deg + 360 ' add 360 if less than 0
    END IF
    __FIX_DEGREE = Deg '                  return degree

END FUNCTION

' Steve's SaveImage Library
'$INCLUDE:'saveimage.bm'


Attached Files Image(s)
   

.zip   Summer.zip (Size: 1.47 MB / Downloads: 28)
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#23
Thumbs Up 
Excellent! @TerryRitchie I recommend showing off some of that extra work you did with the stems yLoc to 230 instead of 280

Compare:
   
b = b + ...
Reply
#24
Hi Terry, I downloaded 'Summer.zip'. Loaded it and got 5 Warnings in SaveImage.BM - Unused variables. Loaded on QB64-PE 3.8.0 and 3.7.0 with the same warnings in Linux OS. What about Windows? I loaded Summer on Windows 10 in 3.8.0 the same results. What I am missing? I am new to the forum. I was looking forward to seeing your banner on my computer. Things like that happens.
Reply
#25
(06-14-2023, 11:11 PM)GareBear Wrote: Hi Terry, I downloaded 'Summer.zip'. Loaded it and got 5 Warnings in SaveImage.BM - Unused variables. Loaded on QB64-PE 3.8.0 and 3.7.0 with the same warnings in Linux OS. What about Windows? I loaded Summer on Windows 10 in 3.8.0 the same results. What I am missing? I am new to the forum. I was looking forward to seeing your banner on my computer. Things like that happens.

Simple answer, just ignore the warnings and hit F5, the program will work as is.

It simply tells you there are declared variables in the SaveImage library, which actually never are used to hold a value or taking part in any operations. So, the only harm done to the program is wasting a couple bytes of memory (1-8 bytes per variable depending on its type).
Reply
#26
(06-14-2023, 11:11 PM)GareBear Wrote: Hi Terry, I downloaded 'Summer.zip'. Loaded it and got 5 Warnings in SaveImage.BM - Unused variables. Loaded on QB64-PE 3.8.0 and 3.7.0 with the same warnings in Linux OS. What about Windows? I loaded Summer on Windows 10 in 3.8.0 the same results. What I am missing? I am new to the forum. I was looking forward to seeing your banner on my computer. Things like that happens.

The warnings for unused variables comes from Option _Explicit, they are harmless for compiles.
   

Run anyway!
   

Man! you have 3.8 already, good for you!
b = b + ...
Reply
#27
(06-14-2023, 11:02 PM)bplus Wrote: Excellent! @TerryRitchie I recommend showing off some of that extra work you did with the stems yLoc to 230 instead of 280

Compare:

Yeah, I didn't know if I should go for total sunflower overload or let them show a little stem. Smile

If my banner wins you guys can generate different variations and decide which one you like best.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#28
   
Reply
#29

Nice!
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#30
Thumbs Up 
(06-15-2023, 12:34 AM)TerryRitchie Wrote: Nice!

+1 Actually I want to get inside and drive!
b = b + ...
Reply




Users browsing this thread: 44 Guest(s)