Gaussian 'blob' animation

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Gaussian 'blob' animation

Post by badidea »

Just for fun. Two 2d-Gaussian surfaces moving around.

Code: Select all

#define dbl double

const SW = 800, SH = 600

type dbl3d
	as dbl x, y, z
end type

sub pset3d(p3d as dbl3d, c as ulong)
	dim as integer x, y
	x = SW \ 2 + p3d.x + p3d.y / 2
	y = SH * (3 / 4) - (p3d.z + p3d.y / 2)
	pset (x, y), c
end sub

'https://en.wikipedia.org/wiki/Gaussian_function#Two-dimensional_Gaussian_function
function gauss2d(x as dbl, y as dbl, x_variance as dbl, y_variance as dbl) as dbl
	return exp(-((x*x)/(2*x_variance) + (y*y)/(2*y_variance)))
end function

screenres SW, SH, 32
width SW \ 8, SH \ 16

dim as ulong c
dim as dbl field_map(-50 to +50, -50 to +50)

dim as dbl x_offs(0 to 1), y_offs(0 to 1), ampl(0 to 1)
dim as dbl t = timer, t_rel
dim as dbl height, brightness
while not multikey(1)
	t_rel = t - timer
	x_offs(0) = 20 * cos(t_rel) 
	y_offs(0) = 20 * sin(t_rel)
	ampl(0) = 50 * sin(t_rel / 1.7)
	x_offs(1) = 10 * -cos(t_rel / 2.3) 
	y_offs(1) = 30 * -sin(t_rel / 3.4)
	ampl(1) = 50 * cos(t_rel / 5.6)
	for xi as integer = lbound(field_map, 1) to ubound(field_map, 1)
		for yi as integer = lbound(field_map, 2) to ubound(field_map, 2)
			field_map(xi, yi) = ampl(0) * gauss2d(xi - x_offs(0), yi - y_offs(0), 400, 100)
			field_map(xi, yi) += ampl(1) * gauss2d(xi - x_offs(1), yi - y_offs(1), 100, 400)
		next
	next
	screenlock
	line(0, 0)-(SW-1, SH-1), 0, bf
	for xi as integer = lbound(field_map, 1) to ubound(field_map, 1)
		for yi as integer = lbound(field_map, 2) to ubound(field_map, 2)
			height = field_map(xi, yi) * 2 + 100
			brightness = abs(field_map(xi, yi) * 2 + 50)
			c = rgb(brightness, brightness, brightness)
			pset3d(type(xi * 4, yi * 4, height), c)
		next
	next
	screenunlock
	sleep 10
wend
getkey
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Gaussian 'blob' animation

Post by UEZ »

Looks very nice but too dark.

Thx for sharing.

Code: Select all

#define dbl double

const SW = 800, SH = 600
Dim Shared As Any Ptr pScrn
Dim Shared As Long pitch

#Define PixelSetScrn(_x, _y, colour)	*Cptr(Ulong Ptr, pScrn + (_y) * pitch + (_x) Shl 2) = (colour)
#Define PixelGetScrn(_x, _y)      		*CPtr(Ulong ptr, pScrn + (_y) * pitch + (_x) Shl 2)
#Define _Alpha(iCol)					((iCol And &hFF000000) Shr 24)		
#Define _Red(iCol)						((iCol And &h00FF0000) Shr 16)		
#Define _Green(iCol)					((iCol And &h0000FF00) Shr 8)		
#Define _Blue(iCol)						((iCol And &h000000FF))

Function ColBlend(col1 As Ulong, col2 As Ulong, blend As Single) As Ulong
	Dim As Single bl = 1 - blend
	Return Rgba(_Red(col1) * blend + _Red(col2) * bl, _Green(col1) * blend + _Green(col2) * bl, _Blue(col1) * blend + _Blue(col2) * bl, _Alpha(col1) * blend + _Alpha(col2) * bl)
End Function

type dbl3d
	as dbl x, y, z
end type

sub pset3d(p3d as dbl3d, c as ulong)
	dim as integer x, y
	x = SW \ 2 + p3d.x + p3d.y / 2
	y = SH * (3 / 4) - (p3d.z + p3d.y / 2)
	'pset (x, y), c
	PixelSetScrn(x, y, ColBlend(c, PixelGetScrn(x, y), _Alpha(c) / 255))
end sub

'https://en.wikipedia.org/wiki/Gaussian_function#Two-dimensional_Gaussian_function
function gauss2d(x as dbl, y as dbl, x_variance as dbl, y_variance as dbl) as dbl
	return exp(-((x*x)/(2*x_variance) + (y*y)/(2*y_variance)))
end function

screenres SW, SH, 32
width SW \ 8, SH \ 16

ScreenInfo , , , , pitch
pScrn = Screenptr()

dim as ulong c
dim as dbl field_map(-50 to +50, -50 to +50)

dim as dbl x_offs(0 to 1), y_offs(0 to 1), ampl(0 to 1)
dim as dbl t = timer, t_rel
dim as dbl height, brightness
while not multikey(1)
	t_rel = t - timer
	x_offs(0) = 20 * cos(t_rel) 
	y_offs(0) = 20 * sin(t_rel)
	ampl(0) = 50 * sin(t_rel / 1.7)
	x_offs(1) = 10 * -cos(t_rel / 2.3) 
	y_offs(1) = 30 * -sin(t_rel / 3.4)
	ampl(1) = 50 * cos(t_rel / 5.6)
	for xi as integer = lbound(field_map, 1) to ubound(field_map, 1)
		for yi as integer = lbound(field_map, 2) to ubound(field_map, 2)
			field_map(xi, yi) = ampl(0) * gauss2d(xi - x_offs(0), yi - y_offs(0), 400, 100)
			field_map(xi, yi) += ampl(1) * gauss2d(xi - x_offs(1), yi - y_offs(1), 100, 400)
		next
	next
	screenlock
	line(0, 0)-(SW-1, SH-1), 0, bf
	for xi as integer = lbound(field_map, 1) to ubound(field_map, 1)
		for yi as integer = lbound(field_map, 2) to ubound(field_map, 2)
			height = field_map(xi, yi) * 2 + 150
			brightness = abs(field_map(xi, yi) * 2 + 150)
			c = rgba(brightness, brightness, brightness, 192)
			pset3d(type(xi * 4, yi * 4, height), c)
		next
	next
	screenunlock
	sleep 10
wend
getkey
Post Reply