Here is the code for the Mandelbulb. I've used cubes to visualise in 3d. Notice I have only create a new vector3 once and recycled them in the program due to getting error probably down to going over the DBPro limit with vectors. You will need IanM MatrixUtilsfor this to run. Try changing the contstant values of MAXITERATIONS, N and DIMEN. The higher the values, the longer it will take to process. Loads of things can enhance and do with this, maybe add ray marching etc. Camera logic is not great at the moment and will update at some point.
Rem Project: MandelBulb_test03
Rem Created: Monday, December 02, 2024
Rem ***** Main Source File *****
#constant DIMEN 128
#constant maxiterations 20
#constant n 16
#constant true 1
#constant false 0
`#constant maxobjects 1166 ` DIMEN = 32 MAXITERATIONS = 10 N = 8
`#constant maxobjects 34417 ` DIMEN = 128 MAXITERATIONS = 20 N = 8
type Pvector
x#
y#
z#
endtype
`dim Mandelbulb(maxobjects) as Pvector
dim Mandelbulb() as Pvector
Setup()
Draw()
do
if scancode()=17
levelMoveCameraUp(0, 10.0)
endif
`S key
if scancode()=31
levelMoveCameraDown(0, 10.0)
endif
`A key
if scancode()=30
levelMoveCameraLeft(0, 10.0)
endif
`D key
if scancode()=32
levelMoveCameraRight(0, 10.0)
endif
control camera using arrowkeys 0,10.0,10.0
if inkey$()=","
dec camz#, 10.0
endif
if inkey$()="."
inc camz#, 10.0
endif
if inkey$()="n"
dec camx#, 10.0
endif
if inkey$()="m"
inc camx#, 10.0
endif
rotate camera 0,camx#,camy#,camz#
sync
loop
end
function Setup()
sync on : sync rate 0 : sync
set display mode 640,480,32
autocam off
global camx#
global camy#
global camz#
camx# = camera angle x()
camy# = camera angle y()
camz# = camera angle z()
Position Camera 0,0,-500
Point Camera 0,0,0
make object cube 1,1
set object normals 1
fix object pivot 1
`create the required vectors once only and reuse- otherwise you can get runtime error probably due to over limit of vec3 you can have
zeta = new vector3( 0, 0, 0)
c = new vector3()
edge as boolean
objcount = 0
for i = 0 to DIMEN
for j = 0 to DIMEN
edge = false
for k = 0 to DIMEN
x# = map(i, 0 , DIMEN, -1.0, 1.0 )
y# = map(j, 0 , DIMEN, -1.0, 1.0 )
z# = map(k, 0 , DIMEN, -1.0, 1.0 )
set vector3 zeta,0,0,0
`n = 8
`n = 16 ` fractal death star :-)
`maxiterations = 10
`maxiterations = 20
iteration = 0
while (true)
spherical(c, x vector3(zeta), y vector3(zeta), z vector3(zeta))
newx# = (x vector3(c)^n) * sin(y vector3(c)*n) * cos(z vector3(c)*n)
newy# = (x vector3(c)^n) * sin(y vector3(c)*n) * sin(z vector3(c)*n)
newz# = (x vector3(c)^n) * cos(y vector3(c)*n)
set vector3 zeta, newx#+x#, newy#+y#, newz#+z#
inc iteration
cr# = x vector3(c)
if cr# > 2
if edge
edge = false
endif
exit
endif
if iteration > maxiterations
if not edge
edge = true
array insert at bottom (Mandelbulb())
Mandelbulb().x#=x#*100.0 : Mandelbulb().y#=y#*100.0 : Mandelbulb().z#=z#*100.0
`Mandelbulb(objcount).x#=x#*100.0 : Mandelbulb(objcount).y#=y#*100.0 : Mandelbulb(objcount).z#=z#*100.0
`inc objcount
endif
exit
endif
endwhile
next k
next j
next i
endfunction
function spherical(c, x#, y#, z#)
r# = sqrt(x#*x# + y#*y# + z#*z#)
`ATANFULL - This command will return the angle of two points in degrees between 0 and 360.
theta# = atanfull(sqrt(x#*x#+y#*y#),z#)
phi# = atanfull(y#,x#)
set vector3 c,r#,theta#,phi#
endfunction
function Draw()
ac = array count(MandelBulb())
o=2
for i = 0 to ac
clone object o,1,0
set object normals o
fix object pivot o
`color object o,rgb(rnd(255),rnd(255),rnd(255))
color object o,rgb(255,255,255)
position object o,MandelBulb(i).x#, MandelBulb(i).y#, MandelBulb(i).z#
inc o
next i
delete object 1
endfunction
function map(n1 as float , oldlow as float , oldhigh as float , newlow as float , newhigh as float )
r as float
n1=n1+0.0 : oldlow=oldlow+0.0 : oldhigh=oldhigh+0.0 : : newlow=newlow+0.0 : newhigh=newhigh+0.0
r = ( ( n1 - oldlow ) / (oldhigh - oldlow) ) * (newhigh - newlow) + newlow
endfunction r
function levelMoveCameraUp(camID as integer, dist as float)
local sx as float
local sy as float
local sz as float
sx = camera angle x(camID)
sy = camera angle y(camID)
sz = camera angle z(camID)
rotate camera camID, wrapvalue(sz-90), 0 , 0
move camera camID, dist
rotate camera camID, sx, sy, sz
endfunction
function levelMoveCameraDown(camID as integer, dist as float)
local sx as float
local sy as float
local sz as float
sx = camera angle x(camID)
sy = camera angle y(camID)
sz = camera angle z(camID)
rotate camera camID, wrapvalue(sx+90), 0, 0
move camera camID, dist
rotate camera camID, sx, sy, sz
endfunction
function levelMoveCameraRight(camID as integer, dist as float)
local sx as float
local sy as float
local sz as float
sx = camera angle x(camID)
sy = camera angle y(camID)
sz = camera angle z(camID)
rotate camera camID, 0, wrapvalue(sy+90), 0
move camera camID, dist
rotate camera camID, sx, sy, sz
endfunction
function levelMoveCameraLeft(camID as integer, dist as float)
local sx as float
local sy as float
local sz as float
sx = camera angle x(camID)
sy = camera angle y(camID)
sz = camera angle z(camID)
rotate camera camID, 0, wrapvalue(sy-90), 0
move camera camID, dist
rotate camera camID, sx, sy, sz
endfunction