Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: Hezad on August 06, 2009
-
Heya :) Here is some code to generate a quaternion julia fractal. It's not exactly what it was supposed to represent (a 3D julia fractal), I guess there's an error in the Quaternions multiplication operator ... Anyway, I liked the result :) Image is rendered using Zbuffer for coloring the points in the set.
Oh, if you run this code, I warn you, it's (VERY VERY) very slow :P anyway, you can try to change the C quaternion constant or the 4th dimension splice value (z.a in the main for/next loop).
''
''
''Quaternions library
''
#include "fbgfx.bi"
Const MAX_Z = 555
Const MAX_ITER = 20
Const MAX_NORM = 6
Type Quaternion
' Q = a*1 + b*i + c*j + d*k
as double a,b,c,d
End Type
Operator +(Lh as Quaternion, Rh as Quaternion) as Quaternion
return type(Lh.a+Rh.a,Lh.b+Rh.b,Lh.c+Rh.c,Lh.d+Rh.d)
end operator
Operator -(Lh as Quaternion, Rh as Quaternion) as Quaternion
return type(Lh.a-Rh.a,Lh.b-Rh.b,Lh.c-Rh.c,Lh.d-Rh.d)
end operator
Operator *(Lh as Quaternion, Rh as Quaternion) as Quaternion
return type( Lh.a*Rh.a - Lh.b*Rh.b - Lh.c*Rh.c - Lh.d*Rh.d, _
Lh.a*Rh.b + Lh.b*Rh.a + Lh.c*Rh.d - Lh.d*Rh.c, _
Lh.a*Rh.c + Lh.c*Rh.a + Lh.d*Rh.b - Lh.b*Rh.d, _
Lh.a*Rh.d + Lh.d*Rh.a + Lh.b*Rh.c - Lh.c*Rh.b)
End Operator
screenres 640,480,32,2
dim shared as uinteger ptr scrptr : scrptr = Screenptr
Dim shared as quaternion ptr PosBuffer : PosBuffer = Callocate(640*480,sizeof(quaternion))
Sub render_ZBuffer(i as double, j as double)
static as integer col,ni,nj,XYCoord
ni = (320+int(i*320))
nj = (240+int(240*j))
XYCoord = ni+640*nj
col = 255-(PosBuffer[XYCoord].c + 1) * 127
screenlock
scrptr[XYCoord] = rgb(col,col,col)
screenunlock
end sub
Dim as quaternion z,c
dim as integer nbiter, XYcoord
c = type(-0.3765,-0.767,.154,-.2)
for i as integer = 0 to 639
for j as integer = 0 to 479
XYCoord = i+640*j
PosBuffer[XYCoord].a = 1
PosBuffer[XYCoord].b = 1
PosBuffer[XYCoord].c = 1
next
next
for j as double = -1 to 1 step 1/240
for i as double = -1 to 1 step 1/320
for k as double = -1 to 1 step 1/MAX_Z
z.a = 0.382 : z.b = i : z.c = j : z.d = k
nbiter = 0
do
z = z*z + c
nbiter += 1
loop until ((z.a*z.a+z.b*z.b+z.c*z.c+z.d*z.d) > MAX_NORM*MAX_NORM) or (nbiter>=MAX_ITER)
if nbiter>=MAX_ITER then '' si le point est dans le set
XYCoord = 320+int(i*320)+640*(240+int(j*240))
if PosBuffer[XYCoord].c > k then
PosBuffer[XYCoord].a = i
PosBuffer[XYCoord].b = j
PosBuffer[XYCoord].c = k
Render_ZBuffer(i,j)
exit for
end if
else
screenlock : scrptr[320+int(i*320)+640*(240+int(j*240))] = rgb(25,25,25) : screenunlock
end if
next
next
next
sleep
Deallocate PosBuffer
-
I havent tried out the code but I notice your doing alot of locking and unlocking of the screen buffer, if that anything like doing it in blitz it will be damn slow. How about calcualting all the values into an array or memorybuffer and then drawing the whole thing in one go inside one lock/unlock, that would likely spped it up a fair bit.
-
Nice image, I saw something similar done using pixel shaders, I am not sure who released it, I'll have a look, maybe there is a video link to it..
-
Screenshot looks interesting.
-
Found it!
Maybe this will give you some inspiration Hezad? :)
[youtube]9AX8gNyrSWc[/youtube]
-
Thanks for your answers mates :) Sorry for not answering before, I wasn't at home.
TinDragon:
I havent tried out the code but I notice your doing alot of locking and unlocking of the screen buffer, if that anything like doing it in blitz it will be damn slow. How about calcualting all the values into an array or memorybuffer and then drawing the whole thing in one go inside one lock/unlock, that would likely spped it up a fair bit.
You're right, I just wanted to avoid calculating stuff while the screen is locked, but idk if it's useful in any way.
benny :
thanks :)
Shockie :
ah thanks ! that's awesome !! that's a bit what I wanted to do but I didn't found how to render the quaternion only from it's surface (in my code, I check each point in space like a 2D fractal ...)
-
Have you tried this out with tinyptc / tinyptc_ext ?
with that you dont need to lock and unlock.
-
Clyde, Hezad is using Linux which counts out ptc_ext mate.
-
exactly :) But I'm working on a raytracer right now, I'll try to implement some quaternion stuff inside it (no way to do real time stuff but that would be way more precise ;) )