Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Hezad on August 06, 2009

Title: Playing with quaternions
Post 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).

Code: [Select]
''
''
''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
Title: Re: Playing with quaternions
Post by: TinDragon on August 07, 2009
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.
Title: Re: Playing with quaternions
Post by: Shockwave on August 07, 2009
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..
Title: Re: Playing with quaternions
Post by: benny! on August 07, 2009
Screenshot looks interesting.
Title: Re: Playing with quaternions
Post by: Shockwave on August 08, 2009
Found it!

Maybe this will give you some inspiration Hezad? :)

[youtube]9AX8gNyrSWc[/youtube]
Title: Re: Playing with quaternions
Post by: Hezad on August 10, 2009
Thanks for your answers mates :) Sorry for not answering before, I wasn't at home.

TinDragon:
Quote
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 ...)
Title: Re: Playing with quaternions
Post by: Clyde on August 10, 2009
Have you tried this out with tinyptc / tinyptc_ext ?
with that you dont need to lock and unlock.
Title: Re: Playing with quaternions
Post by: Shockwave on August 10, 2009
Clyde, Hezad is using Linux which counts out ptc_ext mate.
Title: Re: Playing with quaternions
Post by: Hezad on August 13, 2009
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 ;) )