## GFX_MATH.bi (Const's, Macro's & Func's)

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
MrSwiss
Posts: 3665
Joined: Jun 02, 2013 9:27
Location: Switzerland

### GFX_MATH.bi (Const's, Macro's & Func's)

Hi all,

over time I've collected, what I consider *essentials* to work with FB's GFX-lib.
I've made it all, into an easy to include .bi file, which I want to share here.
Sources, other than my own stuff, are noted, however, limited to my memory.
(if I've made any mistakes, in quoting sources, please let me know ...)

Contains:
• constants: PI (Π), PI2 (double Π), GolderRatio -- others are used by macro's
• all Macro's are *single line*, aka: #Define (not listed, quite a few)
• two Function's: Contrast(), CContrast()
• updated: 2018-04-12 (added single alpha-/color-channel getters/setters)
Here goes GFX_MATH.bi:

Code: Select all

`' GFX_MATH.bi -- mathematics for fbGFX (Singles only) -- 2016/18, MrSwiss'' update     : 2017-05-06   changed: added Smap (renamed map to Imap)' last update: 2018-04-11/12changed: added color-channel getters/setters'' some math const(s) + macro(s) + conrast Func's -- #Define = single line macro'' forum: https://www.freebasic.net/forum/viewtopic.php?f=7&t=25635&p=231423#Ifndef __GFX_MATH_BI__#Define __GFX_MATH_BI__' from: FB-manual (maybe: Forum??)Const As Single PI      = Atn( 1f ) * 4f   ' semi-circle, in RADiansConst As Single PI2     = Atn( 1f ) * 8f   ' full-circle, RAD' original, by bluatigro (I assume)Const As Single GoldenRatio = ( Sqr(5f) - 1f ) / 2f' original, by FB-manualConst As Single D2R     = pi / 180f          ' conversion factor, DEG --> RADConst As Single R2D     = 180f / pi          ' conversion factor, RAD --> DEG' original, by MrSwiss (I don't want to have to remember the Const's names!)#Define RAD(d)          ( CSng(d * D2R) )   ' conversion macro, DEG --> RAD#Define DEG(r)          ( CSng(r * R2D) )   ' conversion macro, RAD --> DEGRandomize(Timer, 3) ' seed for Rnd(), Mersenne Twister (FB-default)' original, by dodicat, modified for returning defined variable type, by MrSwiss#Define LRange(l, h)    ( CLng(Rnd() * (h - l) + l) )   ' general use, Long    (32bit)#Define LIRange(l, h)   ( CLngInt(Rnd() * (h - l) + l) )' general use, LongInt (64bit)#Define IRange(l, h)    ( CInt(Rnd() * (h - l) + l) )   ' general use, Integer (FBC-bitness)#Define SRange(l, h)    ( CSng(Rnd() * (h - l) + l) )   ' general use, Single  (GFX-Float, 32bit)' original, by dodicat modified: MrSwiss (removed brackets around var's), added brackets _#define Imap(a,b,x,c,d) ( (d - c) * (x - a) \ (b - a) + c ) ' around 'whole body' (readability)#define Smap(a,b,x,c,d) ( (d - c) * (x - a) / (b - a) + c )' -- all Color stuff, original, by MrSwiss --#Define ClrRng(l, h)    ( CULng(Rnd() * (h - l) + l) )  ' Color, aka: ULong' random Color RGB range, ULong (full alpha, always)#Define RndRGB          ( CULng(Rnd() * &hFFFFFF + &hFF000000ul) )' random Color ARGB range, ULong (random Alpha & Color)#Define RndARGB         ( CULng(Rnd() * &hFFFFFFFFul) )' color inverter, not touching/changing of Alpha-Chan.#Define InvClr(c)       ( CULng(c Xor &h00FFFFFF) )' color inverter, incl. Alpha#Define InvAClr(c)      ( CULng(c Xor &hFFFFFFFFul) )' 2018-04-12, function like MACRO's (getters) for alpha-/color-channel's values (UByte, from 32-bit color)#Define ga_ch(c)        ( CULng(c) Shr 24 And 255 )         ' get alpha-channel#Define gr_ch(c)        ( CULng(c) Shr 16 And 255 )         ' get red-channel#Define gg_ch(c)        ( CULng(c) Shr  8 And 255 )         ' get green-channel#Define gb_ch(c)        ( CULng(c)        And 255 )         ' get blue-channel' 2018-04-11, function like MACRO's (setters) for alpha-/color-channel's (32-bit color, ULong)#Define sa_ch(c,a)      ( CULng(c) + ((a And 255) Shl 24) ) ' set alpha-channel#Define sr_ch(c,r)      ( CULng(c) + ((r And 255) Shl 16) ) ' set red-channel#Define sg_ch(c,g)      ( CULng(c) + ((g And 255) Shl  8) ) ' set green-channel#Define sb_ch(c,b)      ( CULng(c) +  (b And 255) )         ' set blue-channel' 2017-04-28, by MrSwiss (simplified version, of below Function: CContrast())' reason: with CContrast() and, many diff. colors, it's too quickly Carnival-like!Function Contrast ( ByVal cin As ULong _    ' param:  'in' ARGB-Color                    ) As ULong              ' result: ARGB-Color (black or white)    ' if NOT full alpha --> set it to full alpha (for easy evaluation)    If CPtr(UByte Ptr, @cin)[3] < 255 Then CPtr(UByte Ptr, @cin)[3] = 255    ' bright half of RGB range --> return black    If cin > &hFF7F7F7F Then Return &hFF000000ul    ' dark half of RGB range   --> return white    Return &hFFFFFFFFulEnd Function' make one random colour over another different: original by dodicat, recoded: _' 2017-04-28, by MrSwiss -- reason: more efficient code & independent of macro'sFunction CContrast( ByVal cin As ULong _    ' param:  'in' ARGB-Color                    ) As ULong              ' result: ARGB-Color     Dim As UByte    a = CPtr(Ubyte Ptr, @cin)[3], _ ' save curr. alpha-chan                    r = CPtr(Ubyte Ptr, @cin)[2], _ ' save curr. red-chan                    g = CPtr(Ubyte Ptr, @cin)[1], _ ' save curr. green-chan                    b = CPtr(Ubyte Ptr, @cin)[0], _ ' save curr. blue-chan                    r2, g2, b2                      ' temp. var's (uninit)    Dim As Boolean  rf, gf, bf                      ' color channels flags    ' minimal required difference from original: 127 / &h7F (aka: 50% of range)    While Not rf    ' run's only: until new red val found        r2 = CUByte(Rnd() * 255) : If Abs(r - r2) > 126 Then rf = TRUE    Wend    While Not gf    ' run's only: until new green val found        g2 = CUByte(Rnd() * 255) : If Abs(g - g2) > 126 Then gf = TRUE    Wend    While Not bf    ' run's only: until new blue val found        b2 = CUByte(Rnd() * 255) : If Abs(b - b2) > 126 Then bf = TRUE    Wend    ' got them all: return result    Return RGBA(r2, g2, b2, a)  ' leave alpha unchanged (use saved original)End Function#EndIf  ' __GFX_MATH_BI__`
and a short Demo (uses Grid.bas), which can be found at the given location, here in the Forum:

Code: Select all

`' Demo1_GFX_MATH_bi.bas -- 2017-05-02, by MrSwiss' last update: 2017-05-02   changed: nothing yet' compile with: -s GUI#Include "GFX_MATH.bi"          ' see: https://freebasic.net/forum/viewtopic.php?f=7&t=25635#Include Once "Grid.bas"        ' see: https://freebasic.net/forum/viewtopic.php?f=7&t=24997' NOTE: if only RGB() is used with GFX_ALPHA_PRIMITIVES, nothing is shown (alpha = 0)Dim As ULong    c1 = RGBA(255,   0,   0, 191), _    ' red 3/4 alpha = 1/4 transparent                c2 = RGBA(127, 127, 127, 255), _    ' grey 100% alpha = opaque (0% trans)                c3 = RGBA(  0,   0, 255, 191)       ' blue (as red)' for program execution controlDim As Boolean  quit = FALSE, sw = TRUE                 ' flags' ===== MAIN =====ScreenRes(641, 641, 32, 2, 64)      ' GFX_ALPHA_PRIMITIVES = &h40 / 64 dec; double buffer'Randomize(Timer, 3)                 ' seed for RND(), set in GFX_MATH.bic2 = RGBA(255, 255, 255, 255)       ' redefine c2 to: white / opaqueDo    ' cell size 68 (square), border 48 = cells: h/v = 8/8 (aka: chessboard)    Grid(640, 640, 68, 48,, c2)     ' grid color = c2 (default = medium-gray)    For j As UInteger = 1 To 8      ' rows (cells vertical)        Var y = j * 68 + 24         ' calc. injection point y (paint, aka: flood-fill)        For i As UInteger = 1 To 8  ' columns (cells horizontal)            Var x = i * 68 + 24     ' calc. injection point x (paint)            If sw Then                Paint (x, y), ClrRng(&h7F7F7F7F, &hFFFFFFFF), c2    ' in GFX_MATH.bi            Else                ' random color RGB range only (100% alpha always)                Paint (x, y), RndRGB, c2    ' in GFX_MATH.bi            EndIf        Next        If Len(InKey()) Then quit = TRUE : Exit For ' exit outer For loop (only)        sw = Not sw                 ' change macro used, every new row    Next    Flip    If quit Then Exit Do    Sleep 1500, 1 : ClsLoop' ===== END-MAIN =====  ' ----- EOF -----`

[edit: 2017-05-06] Another test code, without additional #Includes:

Code: Select all

`' GFX_MATH_Test2.bas -- 2017-05-06, by MrSwiss' last update: 2017-05-06   changed: ---' compile with: -s GUI#Include Once "GFX_MATH.bi"     ' see: https://freebasic.net/forum/viewtopic.php?f=7&p=231423#p231423' for program execution controlDim As Boolean  quit = FALSE    ' flag(s)' ===== MAIN =====ScreenRes(641, 641, 32, 2, 64)  ' GFX_ALPHA_PRIMITIVES = &h40 / 64 dec; double bufferDo    For j As UInteger = 0 To 10         ' rows (steps vertical)        Var y = j * 55                  ' calc. y-axis pos.        For i As UInteger = 0 To 10     ' columns (steps horizontal)            Var x = i * 55              ' calc. x-axis pos.            Var h = IRange(25, 85)      ' get a random height between 25 and 85            Var w = IRange(35, 150)     ' get a random width between 35 and 150            Line (x, y)-Step(w, h), RndARGB, BF ' random color full ARGB range        Next        If Len(InKey()) Then quit = TRUE : Exit For ' exit outer For loop (only)    Next    Flip    If quit Then Exit Do                ' end prog. (if quit = TRUE)    Sleep 1000, 1 : Cls                 ' give user some time, to 'look at it'Loop' ===== END-MAIN =====  ' ----- EOF -----`

Return to “Tips and Tricks”

### Who is online

Users browsing this forum: No registered users and 7 guests