Mandelbrot Fractal

Started by _PJ_, July 22, 2023, 21:48:15

Previous topic - Next topic

_PJ_

Low-Resolution Mandelbrot Set { Sig[Z^2+c] < 2.0 } Fractal explorer
Limited to 255 iteration depth and the iteration steps are displayed in greyscale

This is quite basic and could benefit from greater controls, more intuitive feedback of the scale of current displayed complex plane ranges. I am thinking of a BMax NG version taking advantage of the MaxUI and multithreading to speed it up as well as 64-bit Double for greater depth and FP accuracy.


Initial Constants can be amended as parameters to adjust scale and speed

Code: BASIC

Const INFINITY_TEST_LIMIT#=2.0
Const ITERATION_LIMIT=256
Const GW=128
Const GH=128

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; COMPLEX Class
Type Complex
	Field Real#
	Field Imaginary#
End Type

Function Subtract.Complex(U.Complex,V.Complex)
	Local Z.Complex=New Complex
	Z\Real#=U\Real#-V\Real#
	Z\Imaginary#=U\Imaginary#-V\Imaginary#
	Return Z
End Function

Function Add.Complex(U.Complex,V.Complex)
	Local Z.Complex=New Complex
	Z\Real#=U\Real#+V\Real#
	Z\Imaginary#=U\Imaginary#+V\Imaginary#
	Return Z
End Function

Function Multiply.Complex(U.Complex,V.Complex)
	Local Z.Complex=New Complex
	Z\Real#=(U\Real#*V\Real#)-(U\Imaginary#*V\Imaginary#)
	Z\Imaginary#=(U\Real#*V\Imaginary#)+(V\Real#*U\Imaginary#)
	Return Z
End Function

Function Conjugate.Complex(Z.Complex)
	Local W.Complex=New Complex
	W\Real#=Z\Real#
	W\Imaginary#=0.0-Z\Imaginary#
	Return W
End Function

Function IsEqual(U.Complex,V.Complex)
	Return (U\Real#=V\Real#) And (U\Imaginary#=V\Imaginary#)
End Function

Function CreateComplex.Complex(Real#,Imaginary#)
	Local Z.Complex=New Complex
	Z\Real#=Real#
	Z\Imaginary#=Imaginary#
	Return Z
End Function

Function PrintComplex(Z.Complex)
	If (Z\Imaginary=0.0)Then Print Z\Real:Return
	Local Operator$="+"
	If (Z\Imaginary<0.0)Then Operator=""
	Print Z\Real#+Operator+Z\Imaginary#+"i"
End Function

Function GraphPlot(a.Complex)
	Plot a\Real#,a\Imaginary#
End Function
;____________________________________________________________________________________________________________________________________________________________

SeedRnd=MilliSecs()



Global FLOPS=0

Graphics GW,GH,32,2
SetBuffer BackBuffer()

Local X
Local Y

Local MX,MY

Local C.Complex
Local Max
Local Timestamp=MilliSecs()
While Not KeyHit(1)
	FLOPS=0
	
	C=New Complex
	C\Real=Float((MX-(GW*0.5))/GW)
	C\Imaginary=Float((MY-(GH*0.5))/GH)
	
	Max=0
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Text 0,GH-12,"WORKING..."
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Flip
	
	LockBuffer; BackBuffer()
	
	Local w=GW-1
	Local h=GH-1
	
	Local fw#=Float(GW)
	Local fh#=Float(GH)
	
	
	For Y=0 To h
		For X=0 To w 
			Local XX#=(1.0/fw)*X
			Local YY#=(1.0/fh)*Y
			
			FLOPS=FLOPS+4
			
			Local Steps=Iterate(XX#,YY#,C) And 255
			
			Local Col= Steps+(Steps Shl 8)+(Steps Shl 16)
			
			If (Steps>Max) Then Max=Steps
			
			WritePixelFast X,(GH-1)-Y,Col;,BackBuffer()
			
		Next
	Next
	
	;Delay 1
	UnlockBuffer; BackBuffer()
	Timestamp=(MilliSecs()-Timestamp)*0.001
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;Text 0,GH-12,Str(FLOPS/Timestamp)+" Flops * Hertz"
	
	Flip
		
	;	DebugLog Max
		
	Delete C
	
	FlushMouse
	WaitMouse()
	MX=MouseX()
	MY=MouseY()
	Cls
	Flip
	
Wend

Function Iterate(ZReal#,Zimaginary#,C.Complex)
	Local Count
	Local Extern
	
	Local Z.Complex=CreateComplex(ZReal#,Zimaginary#)
	
	For Count=1 To ITERATION_LIMIT
		Z.Complex=Algorithm(Z,C)
		
		If ((Magnitude(Z))>INFINITY_TEST_LIMIT#)
			Delete Z
			Return Count
		End If
	Next
	Delete Z
	Return 0
End Function

Function Algorithm.Complex(Z.Complex,C.Complex)
	Local U.Complex=Multiply(Z,Z)
	Local V.Complex=Add(U,C)
	
	FLOPS=FLOPS+2
	
	Delete Z
	Delete U
	
	Return V
End Function

Function Magnitude#(Z.Complex)
	
	FLOPS=FLOPS+3
	
	Return Sqr((Z\Real#*Z\Real#)+(Z\Imaginary#*Z\Imaginary#))
End Function