PDA

View Full Version : TB Mandelbrot Time



peter
07-12-2013, 20:41
Hi,

Not that fast!


DWord hdc,hwin
hwin=Canvas_Window("Mandel",10,10,640,480)
Canvas_Attach(hwin,0,%TRUE)
Canvas_Font("verdana",16,%CANVAS_FONTSTYLE_BOLD)


Single lx, ly, x, y, a2, b2, a, b, z, c, x2, y2
Long tick, tack, t


Canvas_Clear 0
DrawText 260,40,"MOMENT....",Rgb 255,255,255
Canvas_Redraw


tick = GetTickCount
lx=3/640
ly=2/480


For x=0 To 640-1
For y=0 To 480-1
a=0: b=0: c=0
x2 = lx*x-2
y2 = ly*y-1
While c <50
a2 = a*a-b*b
b2 = 2*a*b
a = a2+x2
b = b2+y2
z = a*a+b*b
If z >=4 Then Exit While
c=c+1
Wend
If c = 50 Then
Canvas_SetPixel x,y, 0
ElseIf c <17 Then
Canvas_SetPixel x,y, Rgb(0,245-((17-c)*3),0)
ElseIf c <33 Then
Canvas_SetPixel x,y, Rgb(0,245,((c-16)*16)-16)
Else
Canvas_SetPixel x,y, Rgb(0,641-(c*12),((c-32)*15))
End If
Next
Next


tack = GetTickCount
t = (tack-tick)/1000


DrawText 0, 0,"Press Escape To Exit ",Rgb(0,0,255)
DrawText 0,20,"Time: " & Str$(t) & " seconds",Rgb(0,0,255)


Canvas_Redraw
Canvas_WaitKey
Canvas_Window End hwin


Sub DrawText(x,y As Long, txt As String, col As Long)
Canvas_Color(col,-2)
Canvas_SetPos(x,y)
Canvas_Print(txt)
End Sub

peter
07-12-2013, 21:33
Here is an OxygenBasic version.

mike lobanovsky
08-12-2013, 03:12
Here's another one, yet slower but plotting in real time:


Uses "UI"

Declare Sub GetClientRect Lib "USER32.DLL" Alias "GetClientRect" (ByVal hWnd As DWord, ByVal lpRect As RECT Ptr)
Declare Function GetDC Lib "USER32.DLL" Alias "GetDC" (ByVal hWnd As DWord) As Long
Declare Sub ReleaseDC Lib "USER32.DLL" Alias "ReleaseDC" (ByVal hWnd As DWord, ByVal hDC As DWord)
Declare Sub SetPixel Lib "GDI32.DLL" Alias "SetPixel" (ByVal hDC As DWord, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long)

Dim rc As RECT
Dim MaxIters As Long = 50
Dim XRes, YRes As Long

Dim colors(MaxIters + 2) As Long
Dim hDC, hDlg As DWord
Dim t As Long

Dialog New 0, "Mandelbrot",-1,-1, 426, 295, _
%WS_POPUP Or %WS_VISIBLE Or %WS_CAPTION Or %WS_SYSMENU Or %WS_MINIMIZEBOX Or %WS_MAXIMIZEBOX To hDlg

Dialog Show Modeless hDlg

FillColorTable
GetClientRect hDlg, rc

XRes = rc.nRight
YRes = rc.nBottom

hDC = GetDC(hDlg)
t = GetTickCount

GenMandelbrot -2.1, -1.25, 0.6, 1.25

MsgBox hDlg, Format$(GetTickCount - t) & " ticks"
ReleaseDC hDlg, hDC

Sub GenMandelbrot(xMn As Double, yMn As Double, xMx As Double, yMx As Double)
Dim iX, iY As Long
Dim cx, cy, dx, dy As Double

dx = (xMx - xMn) / XRes
dy = (yMx - yMn) / YRes

For iY = 0 To YRes
cy = yMn + iY * dy
For iX = 0 To XRes
cx = xMn + iX * dx
SetPixel hDC, iX, iY, colors(MIterate(cx, cy) + 1)
Next
Next
End Sub

Function MIterate(cx As Double, cy As Double) As Long
Dim iters As Long
Dim X As Double = cx
Dim Y As Double = cy
Dim X2 As Double = X * X
Dim Y2 As Double = Y * Y
Dim temp As Double

While (iters <= MaxIters) And (X2 + Y2 < 4)
temp = cx + X2 - Y2
Y = cy + 2 * X * Y
Y2 = Y * Y
X = temp
X2 = X * X
iters += 1
Wend

Return iters
End Function

Sub FillColorTable()
Dim r, g, b As Long
Dim rd, gd, bd As Long
Dim rr, gg, bb As Long
Dim i, j, wid As Long

Dim clr(4) As Long
clr(2) = Rgb(0, 255, 0)
clr(3) = Rgb(255, 255, 0)
clr(4) = Rgb(255, 0, 0)

wid = MaxIters / 3

For j = 0 To 2
toRGB(clr(j + 1), r, g, b)
toRGB(clr(j + 2), rr, gg, bb)
rd = (rr - r) / (wid + 1)
gd = (gg - g) / (wid + 1)
bd = (bb - b) / (wid + 1)
For i = 0 To wid
colors(j * wid + i + 1) = Rgb(r, g, b)
r += rd
g += gd
b += bd
Next
Next
colors(MaxIters + 2) = 0
End Sub

Sub toRGB(c As Long, ByRef r As Long, ByRef g As Long, ByRef b As Long)
r = c And &HFF
g = (c And &HFF00) / &H100
b = (c And &HFF0000) / &H10000
End Sub

RobbeK
08-12-2013, 13:29
Great stuff !!


attached - "greased lightning speed" Dynamic O2 -- bmp transfer , real time adjusting .. (Julia however, easy to convert into Mandelbrot)


best

Rob

peter
08-12-2013, 14:02
Thank you Mike, RobbeK

Mike,
I like your Mandelbrot, looks good for me.

RobbeK,
Your animated Mandelbrot looks great as well.

mike lobanovsky
08-12-2013, 16:23
Wow Rob,


Your interactive TV is amazing! :)

Can I have your permission to port it to FBSL and publish with due attribution of course? It's a pity we don't have a built-in Canvas for persistent drawing though. We have to use low-level API's for a memory backbuffer plus BitBlt (slower) or work directly with the bmp's DIB section pixel data array (faster). But the effect and speed will be as smooth and fast as your original.


Regards,

peter
08-12-2013, 16:39
Hi,

here's Mike's Mandelbrot, translate to OxygenBasic.

John Spikowski
08-12-2013, 22:12
Peter,

Thanks for the Mandelbrot O2 example. I'm only able to post the resulting time dialog as I'm not quick enough to capture the graphic generated. (don't blink) Can you post another version of this that retains the generated fractal? I'm running under Wine so the Windows version of this should even be faster.

http://files.allbasic.info/O2/o2mandelbrot.png

peter
08-12-2013, 22:52
Okay, here is the source code.

RobbeK
08-12-2013, 23:51
Hi Mike,

Sure -- but the timer events were coded by Eros , and the Canvas_Bitmap byRef was new for TB 1.9.10 then.
Attached , IIRC my first BMP linking thing < 1.9.10 (I made something similar in Freebasic and Freepascal to gain some speed )

best, Rob
(those glitter pixels were added later IIRC :cool: )

OOps , always forget to ask -- your DynC does it lazy evaluation ??? -- I really need this for some mathematical related progs ..

ErosOlmi
09-12-2013, 08:32
Sure -- but the timer events where coded by Eros , and the Canvas_Bitmap byRef was new for TB 1.9.10 then.


You can do what you prefer with the code I write and publish, always.

mike lobanovsky
09-12-2013, 13:19
Eros, Rob, Peter and John,

Thanks for the feedback!

@Peter:

Your code does run fast. However, the colors don't seem to be correct. Please see the attached snapshots for my TB code and your O2 code. That's because TB arrays are always Option Base 1 and your code seems to use Option Base 0 and thus has the colors shifted up by one. You have to change
...
SetPixel hDC, iX, iY, colors(MIterate(cx, cy) + 1)
...
colors(j * wid + i + 1) = Rgb(r, g, b)
...
colors(MaxIters + 2) = 0
...
to
...
SetPixel hDC, iX, iY, colors(MIterate(cx, cy))
...
colors(j * wid + i) = Rgb(r, g, b)
...
colors(MaxIters + 1) = 0
...
to have the black spike on the left side of the fractal drawn exactly as TB draws it.

@John:

No, it won't be faster in a genuine Windows environment because the code uses an ordinary SetPixel() WinAPI to plot the pixels. Your Toshiba's CPU uses hardware virtualization for GDI calls under Wine so the difference will most probably be undetectable. OTOH plotting would be slower if done in Wine's DirectX or OpenGL (= wrapper around Wine's DirectX) because modern nVidia and ATI drivers and Windows sources are closed and your Linux fellows have so far been unable to crack their hardware acceleration technologies, well, mostly. :)

[EDIT]

@Rob:

Oh, I forgot to answer your question. FBSL's BASIC has usual "eager" (a.k.a. "inclusive") And and Or as well as their "lazy" (a.k.a. "exclusive", a.k.a. "short-circuited") AndAlso and OrElse equivalents for lazy evaluation.

FBSL's DynC has naturally lazy && and || logic operators only.

zlatkoAB
09-12-2013, 18:31
here is my version in o2 ,it is under second

RobbeK
09-12-2013, 21:38
Something in Freebasic (with Firefly RAD)

best Rob

BMP -> Screen with Put command
(hit Update and then AnimX p.e. -- for a new center point, first button then a mouse-click)

RobbeK
09-12-2013, 21:55
Thanks Mike,

I surely will have a look at FBSL -- (it can call functions from DLL's etc... ?)

best Rob

mike lobanovsky
09-12-2013, 22:14
Gentlemen,

Thanks a lot, I admired (and appreciated too) the both fractals!

Rob, it has kernel32.dll, user32.dll and gdi32.dll always preloaded, so that you can call their API's as if they were part of the language vocabulary. You can also map any other DLL(s) in its (their) entirety with just a single preprocessor directive, #DllImports YourFovorite.dll. And it doesn't use function declarations; call the API's however you wish just stay reasonable not to run into GPF's. :)

mike lobanovsky
13-12-2013, 07:41
There's been some interest as to whether I notice that message boxes tend to smear the fractal picture of TB and FBSL Mandelbrots rendered unbuffered directly into the screen window's hDC. Yes, I do but the problem isn't mine.

Windows system dialogs such as Open/Save dialog boxes, message boxes, etc. are "blocking" which means they suspend main program flow until closed with a button click or canceled. Under Windows XP, all dialog boxes except MessageBox() which the MsgBox() function is built around in both TB and FBSL have a CS_SAVEBITS style. This style gives a window an ability to automatically save its background before it pops up and restore it again after it closes. Since XP message boxes lack this style, an attempt to drag them around an unbuffered window will smear the window while its WM_PAINT message handling is blocked by the message box.

There are several techniques to bypass the blocking nature of XP message boxes but all of them require message box window subclassing which is by no means simple. Adding such code would bloat the sample whose main goal was not to show the beauty of the fractal but rather yield the relevant benchmark results.

Vista+ message boxes are more liberal in this regard. Since the overwhelming majority of users are on Windows 7 and up these days, adding special-case message box handling to a sample that exists only here and now would be a plain waste of coding time and effort.