News:

Welcome to RetroCoders Community

Main Menu

Gradient Balls

Started by CharlieJV, Jul 11, 2023, 04:47 AM

Previous topic - Next topic

CharlieJV

' This BASIC Anywhere Machine program by Charlie Veniot
' is a port and mod of Dav's QB64pe program
' found at https://qb64phoenix.com/forum/showthread.php?tid=1838&pid=17786#pid17786


johnno56

Nicely done indeed! Bplus had a smallbasic Mastermind game that used spheres like those... I will see if I can find it... So long ago...
May your journey be free of incident.  Live long and prosper.

ZXDunny

#2
I'm not keen on the sticking-plaster approach to the gradient not being suitable for some circles and not others, so I took a bit of a cheeky liberty to rewrite it a tad:

' This BASIC Anywhere Machine program by Charlie Veniot
' is a port and mod of Dav's QB64pe program
' found at https://qb64phoenix.com/forum/showthread.php?tid=1838&pid=17786#pid17786
' small changes by zxdunny

dh = 1000
screen _newimage(1600,dh,23)
declare SUB ball (x, y, size, r, g, b)


DO
    ball (int(RND * dh)+300, int(RND * dh), int(RND * 255) + 25, int(RND * 255), int(RND * 255), int(RND * 255))
    _delay 0.1
LOOP
 
SUB ball (x, y, size, r, g, b)
    _DISPLAY

    FOR s = 0 TO size
    	v=sin((1-s/size)*1.57)
    	c=_RGB32(int(r*v),int(g*v),int(b*v))
        CIRCLE (x, y), s, c
        CIRCLE (x+1, y), s, c
        CIRCLE (x, y+1), s, c
    NEXT
    _DISPLAY
 
END SUB

The 1.57 is Pi/2, but I'm guessing BAM doesn't define PI as a constant? Also I'm assuming that _RGB32 has to have integer parameters and doesn't take floats (or perform the conversion to integer itself) as I had to add the int() call for the rgb scaling.

I do hope you don't mind my submitting this! I do like the more 3D look of a sin-based gradient than one that is simply linear.

CharlieJV

Quote from: ZXDunny on Jul 11, 2023, 01:42 PMI'm not keen on the sticking-plaster approach to the gradient not being suitable for some circles and not others, so I took a bit of a cheeky liberty to rewrite it a tad:

' This BASIC Anywhere Machine program by Charlie Veniot
' is a port and mod of Dav's QB64pe program
' found at https://qb64phoenix.com/forum/showthread.php?tid=1838&pid=17786#pid17786
' small changes by zxdunny

dh = 1000
screen _newimage(1600,dh,23)
declare SUB ball (x, y, size, r, g, b)


DO
    ball (int(RND * dh)+300, int(RND * dh), int(RND * 255) + 25, int(RND * 255), int(RND * 255), int(RND * 255))
    _delay 0.1
LOOP
 
SUB ball (x, y, size, r, g, b)
    _DISPLAY

    FOR s = 0 TO size
        v=sin((1-s/size)*1.57)
        c=_RGB32(int(r*v),int(g*v),int(b*v))
        CIRCLE (x, y), s, c
        CIRCLE (x+1, y), s, c
        CIRCLE (x, y+1), s, c
    NEXT
    _DISPLAY
 
END SUB

The 1.57 is Pi/2, but I'm guessing BAM doesn't define PI as a constant? Also I'm assuming that _RGB32 has to have integer parameters and doesn't take floats (or perform the conversion to integer itself) as I had to add the int() call for the rgb scaling.

I do hope you don't mind my submitting this! I do like the more 3D look of a sin-based gradient than one that is simply linear.

Very very quick work break.

Mind?  Oh heck no, anybody standing tall on other(s) shoulders, that's always a cool thing.  That's how we reach the stars!

In BAM, the function _PI does the trick.

_PI by itself to get the number.

_PI(multiplier) to get an increment/decrement of PI.  So _PI(0.5) for what you're doing.

You cannot view this attachment.

CharlieJV

Quote from: CharlieJV on Jul 11, 2023, 03:26 PMSo _PI(0.5) for what you're doing.


Well, _PI as a function for compatibility with QB64.

Myself, I much prefer the look of _PI / 2  than _PI(0.5)

johnno56

Well, now you've done it! There are now TWO versions of the spheres and I cannot decide which one I like better...!!

Curious... Do you think that this method could be applied to "other" shapes? eg: Rectangles, ellipses and polygons...
May your journey be free of incident.  Live long and prosper.

ZXDunny

Quote from: CharlieJV on Jul 11, 2023, 03:59 PM
Quote from: CharlieJV on Jul 11, 2023, 03:26 PMSo _PI(0.5) for what you're doing.


Well, _PI as a function for compatibility with QB64.

Myself, I much prefer the look of _PI / 2  than _PI(0.5)

I have to agree there. TBH, I don't think _PI(2) is any better :)

But there we are. I have a directional light source demo that I may try porting to BAM for funsies. This is gonna be interesting. Do we have mouse x/y coordinate functions in there?

Quote from: johnno56 on Jul 11, 2023, 06:43 PMWell, now you've done it! There are now TWO versions of the spheres and I cannot decide which one I like better...!!

Curious... Do you think that this method could be applied to "other" shapes? eg: Rectangles, ellipses and polygons...

Actually, take a look at the grassfire transform - https://en.wikipedia.org/wiki/Grassfire_transform - a gradient fill for any arbitrary shape :)

CharlieJV

Quote from: ZXDunny on Jul 11, 2023, 06:46 PMI have to agree there. TBH, I don't think _PI(2) is any better :)

But there we are. I have a directional light source demo that I may try porting to BAM for funsies. This is gonna be interesting. Do we have mouse x/y coordinate functions in there?


Yup.  Ditto on _PI(2).  I much prefer _PI * 2.

_MOUSEX and _MOUSEY functions.  Details in the documentation.

You cannot view this attachment.

CharlieJV

A little FYI on why I tripled the CIRCLE statements:

        CIRCLE (x, y), s, _RGB32(r, g, b)
        CIRCLE (x+1, y), s, _RGB32(r, g, b)
        CIRCLE (x, y+1), s, _RGB32(r, g, b)

The pixels in the BAM console/graphics window are "virtual" pixels, they get bigger as SCREEN resolution gets smaller, and smaller as SCREEN resolution gets bigger, and they get bigger when the browser window size is increased, and they get smaller as the browser window size is decreased.

I suspect deep in the innards of it all, there are rounding issues, some virtual pixels a little smaller than they ought to be, some a little bit bigger than they ought to be.

When we comment out the additional CIRCLE statements, we'll get some gaps between the circles of a sphere, as per this screenshot:

You cannot view this attachment.

A workaround to not have these gaps involves calling those two extra CIRCLE statements, which will fix all the "holes."

I did get a little bit overzealous there.  Instead of two extra CIRCLE statements, we really only need one extra CIRCLE statement as a workaround to fix the "holes".

ALSO: Although I may be imagining things (maybe just the way the randomness played out), it feels like using screen mode 24 gives smoother results that mode 23.

screen _newimage(1600,dh,24)

CharlieJV

Quote from: ZXDunny on Jul 11, 2023, 01:42 PMI'm not keen on the sticking-plaster approach to the gradient not being suitable for some circles and not others, so I took a bit of a cheeky liberty to rewrite it a tad:

' This BASIC Anywhere Machine program by Charlie Veniot
' is a port and mod of Dav's QB64pe program
' found at https://qb64phoenix.com/forum/showthread.php?tid=1838&pid=17786#pid17786
' small changes by zxdunny

dh = 1000
screen _newimage(1600,dh,23)
declare SUB ball (x, y, size, r, g, b)


DO
    ball (int(RND * dh)+300, int(RND * dh), int(RND * 255) + 25, int(RND * 255), int(RND * 255), int(RND * 255))
    _delay 0.1
LOOP
 
SUB ball (x, y, size, r, g, b)
    _DISPLAY

    FOR s = 0 TO size
    	v=sin((1-s/size)*1.57)
    	c=_RGB32(int(r*v),int(g*v),int(b*v))
        CIRCLE (x, y), s, c
        CIRCLE (x+1, y), s, c
        CIRCLE (x, y+1), s, c
    NEXT
    _DISPLAY
 
END SUB

The 1.57 is Pi/2, but I'm guessing BAM doesn't define PI as a constant? Also I'm assuming that _RGB32 has to have integer parameters and doesn't take floats (or perform the conversion to integer itself) as I had to add the int() call for the rgb scaling.

I do hope you don't mind my submitting this! I do like the more 3D look of a sin-based gradient than one that is simply linear.

That is so, oh so, much nicer!

CharlieJV

Quote from: ZXDunny on Jul 11, 2023, 01:42 PMAlso I'm assuming that _RGB32 has to have integer parameters and doesn't take floats (or perform the conversion to integer itself) as I had to add the int() call for the rgb scaling.

Delayed reaction over here ...

Yup, many of the graphics statements/functions misbehave when fed decimal values.

I've got to go through them and them implicitly INT things that need INTing so that we don't have to explicitly do that every time.

I was on the fence for some goofy reason, thinking that maybe I shouldn't do that and let folk decide if how they want to handle things: INT or CINT or whatever.

What was I thinking?  I can have the innards do INT, and if folk want differently, they can do that in their programs.  If the internals to an INT after somebody applies a CINT to a parameter, the INT won't undo the CINT.

CharlieJV

BTW, zxdunny's version, very dinky tweak from me: