PDA

View Full Version : Biomorphs , a Fractal creatures



zak
14-03-2010, 07:33
Hi
those figures resemble the protozoa, look at this page:
http://www.madteddy.com/biomorph.htm
i have tried the quick basic code in this page (i have attached it here) and it display the same figure in the page.
( if you want to run qb45 programs comfortably then use DosBox emulator)
ok, i have tried the same code in thinbasic, and yes it produce the same paramecium like creature, but its nucleus is black and not as the qb output. i am surely miss something, i have a low level of neurotransmiters in my brain neurons.
try other equations from the web there are all sorts of creatures avaiable.

Uses "TBGL"

Begin Const
%constreal = .5
%constimag = 0
%screenheight = 500
%screenwidth = 500
%listPoints = 1
End Const

Dim As Double aspectratio = %screenwidth / %screenheight
Dim As Double ymax = 2.5
Dim As Double ymin = -ymax
Dim As Double xmax = ymax * aspectratio
Dim As Double xmin = -xmax
Dim As Integer ilimit = %screenheight - 1
Dim As Integer jlimit = %screenwidth - 1
Dim x,y,x0,y0,xx,yy As Double
Dim i,j,n As Integer

Function TBMAIN()
Local hWnd As DWord
Local FrameRate As Double
Local width, height As Long

' -- Create and show window
hWnd = TBGL_CreateWindowEx("BioMorphs", 500, 500, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

TBGL_GetWindowClient( hWnd, width, height )

' -- Background color to white
TBGL_BackColor 255, 255, 255, 255

' -- Cache the image to display list
' -- Please note the display lists are garbage collected,
' -- so no need to explicitly create/destroy them
'''''''''''''''''''''''''''''''
TBGL_NewList %listPoints
TBGL_BeginPoly(%GL_POINTS)
For i = 0 To ilimit
For j = 0 To jlimit
x0 = xmin + (xmax - xmin) * j / jlimit
y0 = -ymin - (ymax - ymin) * i / ilimit
x = x0
y = y0
For n = 1 To 100
xx = x * (x * x - 3 * y * y) + %constreal: ' THIS Line And the Next give the cube
yy = y * (3 * x * x - y * y) + %constimag: ' of the Number, plus a constant
x = xx
y = yy
If Abs(x) > 10 Or Abs(y) > 10 Or x * x + y + y > 10 ^ 2 Then
n = 100
End If
Next n
If Abs(x) < 10 Or Abs(y) < 10 Then
TBGL_Color( 0, 0, 0 )
TBGL_Vertex j, i
'PSET (j, i), black
Else
TBGL_Color( 255, 255, 255 )
TBGL_Vertex j, i
'PSET (j, i), white
End If
Next j
Next i

TBGL_EndPoly
TBGL_EndList

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- Main loop
While TBGL_IsWindow(hWnd)
' -- Read the current frame rate.
FrameRate = TBGL_GetFrameRate

' -- As we don't draw a full background, we need to clear the framebuffer
TBGL_ClearFrame

' -- Set the resolution and the coordinate system
TBGL_RenderMatrix2D (0, jlimit, ilimit, 0)

TBGL_CallList %listPoints

'Show the rendered stuff
TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then

Exit While
End If

Wend

TBGL_DestroyWindow
End Function

Petr Schreiber
14-03-2010, 09:16
Hi Zak,

thanks for sharing the code, there was just one detail causing different render.
The %constants in thinBASIC are by default integer numbers.
So assigning:


%constreal = .5

actually assigned 0.

But you can force datatype to constant, so changing the above to:


%constreal = .5 As Double

fixes the issue and the result should be the same as with original code.
Let us know!


Petr

zak
14-03-2010, 09:44
Hi Petr ,
as usual you have solved the problem,
indeed i have tried this same code on a comodore compatible computer many years ago from a paper edition of scientific american magazine i am searching for it now, and it was a bizzare experience that such a simple math can produce those complex figures.
thanks

Petr Schreiber
14-03-2010, 11:00
Hi Zak,

yes, math expressions are full of surprises :)

Here little modification of your code. Original used display lists, which are very good way to cache data and render fast. The problem is that you never know how big memory will be occupied by the list, as it is graphic card vendor dependant.

For this reason I introduced GBuffers in latest beta, which are very deterministic regarding the size, basically just the data you pass in.

Here little sample how to use them:


Uses "TBGL"

Begin Const
%constreal = 0.5 As Double
%constimag = 0
%screenheight = 500
%screenwidth = 500
End Const

Dim As Double aspectratio = %screenwidth / %screenheight
Dim As Double ymax = 2.5
Dim As Double ymin = -ymax
Dim As Double xmax = ymax * aspectratio
Dim As Double xmin = -xmax
Dim As Integer ilimit = %screenheight - 1
Dim As Integer jlimit = %screenwidth - 1
Dim x,y,x0,y0,xx,yy As Double
Dim i,j,n As Integer

Function TBMAIN()
Local hWnd As DWord
Local FrameRate As Double
Local width, height As Long

' -- Create and show window
hWnd = TBGL_CreateWindowEx("BioMorphs", %screenheight, %screenwidth, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX Or %TBGL_WS_DONTSIZE)
TBGL_ShowWindow

TBGL_GetWindowClient( hWnd, width, height )

' -- Background color to white
TBGL_BackColor 255, 255, 255, 255

Dim pixelCount As Long = (ilimit+1)*(jlimit+1)
Dim pixelID As Long
Dim aVertex(pixelCount) As tbgl_tVector2f
Dim aColor (pixelCount) As tbgl_tRGB

' -- Create buffer for 2D points, just static
Dim gbGraphic As DWord = TBGL_GBufferCreate(%TBGL_POINTS, %TBGL_2D)

For i = 0 To ilimit
For j = 0 To jlimit
x0 = xmin + (xmax - xmin) * j / jlimit
y0 = -ymin - (ymax - ymin) * i / ilimit
x = x0
y = y0
For n = 1 To 100
xx = x * (x * x - 3 * y * y) + %constreal ' this Line And the Next give the cube
yy = y * (3 * x * x - y * y) + %constimag ' of the Number, plus a constant
x = xx
y = yy
If Abs(x) > 10 Or Abs(y) > 10 Or x * x + y + y > 10 ^ 2 Then
n = 100
End If
Next n

Incr pixelID
aVertex(pixelID).x = j
aVertex(pixelID).y = i

If Abs(x) < 10 Or Abs(y) < 10 Then
aColor(pixelID).R = 0
aColor(pixelID).G = 0
aColor(pixelID).B = 0
Else
aColor(pixelID).R = 255
aColor(pixelID).G = 255
aColor(pixelID).B = 255
End If
Next j
Next i

' -- Bind the array variables
TBGL_GBufferDefineFromArray(gbGraphic, %TBGL_STATIC, pixelCount, aVertex(1), aColor(1))

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- Main loop
While TBGL_IsWindow(hWnd)
' -- Read the current frame rate.
FrameRate = TBGL_GetFrameRate

' -- As we don't draw a full background, we need to clear the framebuffer
TBGL_ClearFrame

' -- Set the resolution and the coordinate system
TBGL_RenderMatrix2D (0, jlimit, ilimit, 0)

' -- Render the graphic
TBGL_GBufferRender(gbGraphic)

'Show the rendered stuff
TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then

Exit While
End If

Wend

TBGL_DestroyWindow
End Function



Petr

zak
14-03-2010, 11:13
Thanks Petr , your example is working well.
also i ask the readers to change the ymax = 2.5 to ymax = 18 , and they will see the image from afar .

Petr Schreiber
14-03-2010, 11:27
Hi Zak,

I changed the ymax in your code, and added possibility to run using display lists or GBuffers.

On my PC:


MethodFrame rateMemory occupied


Display list
55 FPS
16,0 MB


GBuffer
275 FPS
13,5 MB



So at least on my PC GBuffers show 5x boost in speed, and still some memory savings.


Petr


Uses "TBGL"

%useList = 1 ' <- Change this to 0 to use GBuffers


Begin Const
%constreal = 0.5 As Double
%constimag = 0
%screenheight = 500
%screenwidth = 500
End Const

Dim As Double aspectratio = %screenwidth / %screenheight
Dim As Double ymax = 18
Dim As Double ymin = -ymax
Dim As Double xmax = ymax * aspectratio
Dim As Double xmin = -xmax
Dim As Integer ilimit = %screenheight - 1
Dim As Integer jlimit = %screenwidth - 1
Dim x,y,x0,y0,xx,yy As Double
Dim i,j,n As Integer

Function TBMAIN()
Local hWnd As DWord
Local FrameRate As Double
Local width, height As Long

' -- Create and show window
hWnd = TBGL_CreateWindowEx("BioMorphs", %screenheight, %screenwidth, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX Or %TBGL_WS_DONTSIZE)
TBGL_ShowWindow

TBGL_GetWindowClient( hWnd, width, height )

' -- Background color to white
TBGL_BackColor 255, 255, 255, 255

#IF %useList = 0
Dim pixelCount As Long = (ilimit+1)*(jlimit+1)
Dim pixelID As Long
Dim aVertex(pixelCount) As tbgl_tVector2f
Dim aColor (pixelCount) As tbgl_tRGB

' -- Create buffer for 2D points, just static
Dim gbGraphic As DWord = TBGL_GBufferCreate(%TBGL_POINTS, %TBGL_2D)
#Else
TBGL_NewList 1
TBGL_BeginPoly %GL_POINTS
#EndIf

For i = 0 To ilimit
For j = 0 To jlimit
x0 = xmin + (xmax - xmin) * j / jlimit
y0 = -ymin - (ymax - ymin) * i / ilimit
x = x0
y = y0
For n = 1 To 100
xx = x * (x * x - 3 * y * y) + %constreal ' this Line And the Next give the cube
yy = y * (3 * x * x - y * y) + %constimag ' of the Number, plus a constant
x = xx
y = yy
If Abs(x) > 10 Or Abs(y) > 10 Or x * x + y + y > 10 ^ 2 Then
n = 100
End If
Next n

#IF %useList = 0
Incr pixelID
aVertex(pixelID).x = j
aVertex(pixelID).y = i
#EndIf


If Abs(x) < 10 Or Abs(y) < 10 Then
#IF %useList = 1
TBGL_Color 0,0,0
TBGL_Vertex j, i
#Else
aColor(pixelID).R = 0
aColor(pixelID).G = 0
aColor(pixelID).B = 0
#EndIf
Else
#IF %useList = 1
TBGL_Color 255, 255, 255
TBGL_Vertex j, i
#Else
aColor(pixelID).R = 255
aColor(pixelID).G = 255
aColor(pixelID).B = 255
#EndIf
End If
Next j
Next i
#IF %useList = 1
TBGL_EndPoly
TBGL_EndList
#Else
' -- Bind the array variables
TBGL_GBufferDefineFromArray(gbGraphic, %TBGL_DYNAMIC, pixelCount, aVertex(1), aColor(1))
#EndIf
Dim sheep As Long
Dim fpsAccu As Double
Dim fpsSpan As Long = 100

TBGL_UseVSync(0)
' -- Resets status of all keys
TBGL_ResetKeyState()

' -- Main loop
While TBGL_IsWindow(hWnd)
' -- Read the current frame rate.
FrameRate = TBGL_GetFrameRate
fpsAccu += FrameRate

Incr Sheep
If Sheep > fpsSpan Then
Sheep = 0

TBGL_SetWindowTitle(hWnd, Format$(fpsAccu/fpsSpan, "#.00")+"FPS, rendering via "+IIf$(%useList, "Display List", "GBuffer"))
fpsAccu = 0
End If

' -- As we don't draw a full background, we need to clear the framebuffer
TBGL_ClearFrame

' -- Set the resolution and the coordinate system
TBGL_RenderMatrix2D (0, jlimit, ilimit, 0)

' -- Render the graphic
#IF %useList = 1
TBGL_CallList 1
#Else
TBGL_GBufferRender(gbGraphic)
#EndIf

'Show the rendered stuff
TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then

Exit While
End If

Wend

TBGL_DestroyWindow
End Function

zak
14-03-2010, 12:02
Hi Petr
i have NVIDIA Geforce 7300 GT, my system memory 3 MB, indeed it is 4 MB but the system can't see more than 3 MB.
running you last code have the following results:
Display list : Frame rate :varies between 170 - 260 i can't determine.
memory occupied : 17.328 MB

i have used the method of ctrl-alt-del and looking for thinbasic item

GBuffer: Frame rate: 337 and more stable than display list
memory occupied: 14.692 MB

regards