Code archives/Graphics/IFS Fractal Viewer 2

This code has been declared by its author to be Public Domain code.

Download source code

IFS Fractal Viewer 2 by Andy_A2015
Lot of IFS fractals
This the main program, it requires the folder 'IFS Data'
with all of the parameter files inside (see next post).

For your efforts you will be rewarded with over 100 IFS fractals to view at your leisure.

====================================
If you run it with out the data files you get a nice error 
message asking if you want to report the error to Microsoft.
====================================

Yeah, it's a bit of a kludge but, this way I can post the data with the program and not having to worry about some cloud
drive server going belly up. Resulting in a 404 for the data.



; ===============================================
; Iterated Function System (IFS) Fractal Viewer 2
; Andres Amaya Jr.
; Denver, CO
; 2015.02.15
; ===============================================

AppTitle "IFS Fractals II"
Graphics 1024,768,32,2
SetBuffer BackBuffer()
Dim a#(1),b#(1),c#(1),d#(1),e#(1),f#(1)
Dim p#(1)
Dim rr%(24), gg%(24), bb%(24), hxc%(24)
Dim work$(1,1)
Dim hx8$(3)

Global cx#, cy#, band#, coff#, xMult#, yMult#
Global numRows%, xOffset%, yOffset%
cx = 512.0: cy = 384.0: band = 17.0: coff = 1.0

;Dimension these two arrays to
;exceed number of parameter files
Dim picName$(200), si%(200)

fontVerdana14% = LoadFont("Verdana",14,True)
fontVerdana48% = LoadFont("verdana",48,True,True,True)

;there are currently 135 IFS parameter
;files in this distribution
numFiles = getNames()
Dim name$(numFiles), pos%(numFiles,1)

getLocs(numFiles)
SeedRnd MilliSecs()
For i% = 1 To 2000:j%=Rand(1,100):Next

palette()

Repeat
	Cls
	Color 60,91,175
	SetFont fontVerdana48
	Text 50,14,"IFS Fractal Viewer II"
	SetFont fontVerdana14
	instruct()
	showNames(numFiles)
	Flip
	choice = scan(numFiles)
	If choice <> 0 Then
		Cls
		st = MilliSecs()
		readData(choice,numFiles)
		display(choice)
		et = MilliSecs()-st
		Color 80, 158, 238
		Text 5, 5,picName$(choice)
		;Text 5,25,et+"ms" ;<------ un-comment to display render time
		Flip
		WaitMouse()
	End If
	If KeyHit(1) Then
		FreeFont fontVerdana14
		FreeFont fontVerdana48
		End
	End If
Forever

Flip

WaitMouse()
End 

Function getNames()
	Local folder$, file$, fname$
	Local curDir%, ft%, count%

	folder$ = CurrentDir()+"/IFS Data"
	curDir = ReadDir(folder$)
	Repeat
		file$ = NextFile$(curDir)
		If file$ = "" Then Exit
		ft = FileType(folder$+"/"+file$)
		If ft <> 2 And file$<>"." And file$<>".." Then
			count = count + 1
			;strip path from file
			fname$ = justName$(file$)
			;strip the extension from file
			fname$ = justNameEx$(fname$)
			;store the name for later use
			picName$(count) = fname$
			;check for specific fractals to be rendered differently
			If Left(fname$,2)="fd" Then si(count)=1
			If fname$ = "fracFern" Then si(count)=2
		End If
	Forever
	Return count
	ChangeDir( CurrentDir$() )
End Function

Function getLocs(numFiles)
	Local i%, y1%, y2%, y3%, y4%

	For i = 1 To numFiles
		;store the positions of the display boxes for each column
		If i < 36 Then
			pos(i,0) =  20 : pos(i,1) = y1+87
			y1 = y1 + 19
		End If
		If i > 35 And i < 71 Then
			pos(i,0) = 175 : pos(i,1) = y2+87
			y2 = y2 + 19
		End If
		If i > 70 And i < 106 Then
			pos(i,0) = 330 : pos(i,1) = y3+87
			y3 = y3 + 19
		End If
		If i > 105 Then
			pos(i,0) = 485 : pos(i,1) = y4+87
			y4 = y4 + 19
		End If
	Next
End Function

Function instruct()
	Local t$
	wrapText(870,89, "Instructions",135, 0,0,0, 255,224,200,1)
	
	t = "Click on one of the selections to display a particular fractal. /n/ "
	t=t+"After the fractal has been rendered, click anywhere on the fractal screen to get back to this "
	t=t+"screen. /n/ Click the [Exit] button to terminate.
	wrapText(640,114, t,365, 0,0,0, 255,224,200)
	
	wrapText(870,250, "Attributions:",135, 0,0,0, 208,208,208, 1)
	
	t = "Fractals beginning with 'fd' are from 'F-Design v3.08' (DOS) by Doug Nelson. "
	t=t+"These fractals are unique in that he centered the fractal on the screen using the parameters. "
	t=t+"This means that ONLY scaling is applied to fit perfectly on a 1024x768 window. /n/ "

	t=t+"Fractals begining with 'frac' are from Windows version of FractInt: 'WinFract_20-04-p09'. /n/ "
	t=t+"Fractals Bmc0884x, DC022b6c, Sq0002d, Sq441, and Td081 are in the same WinFract_20-04-p09 distribution "
	t=t+"by Anthony Hanmer (frac205.ifs) /n/ "

	t=t+"Fractals beginning with 'rs'are from an old QB listing 'RS-IFS-Programm von Robert Seidel (7/1995)' "
	t=t+"Most of these are unique, but some were 'from FractInt' /n/ "

	t=t+ "Fractals beginning with 'tcl' are from wiki.tcl.tk. Many of these are repeats but, the unique thing about "
	t=t+"these fractals are that the probabilities are always equal. This also has the effect of not being as "
	t=t+"detailed versus using weighted probabilities as do the other sources. /n/ "

	t=t+ "Fractals fractIntDragon, Levy Dragon, and Heighway Dragon are Python recipes from www.activestate.com /n/ "

	t=t+ "'wikipediaFern' is from Wikipedia.com /n/ 'ifsMaple' is from www.hiddendimension.com"

	wrapText(640,275, t,365, 0,0,0, 208,208,208)

End Function

Function showNames(numFiles%)
	Local i%

	For i = 1 To numFiles
		drawbox(picName$(i),pos(i,0),pos(i,1),135,17, 40,61,139, 255,255,208)
	Next
	drawbox("Exit",986,5,33,19, 255,0,0, 255,255,255)
End Function

Function scan(numFiles%)
	Local mx%, my%, i%, choice%

	WaitMouse()

	If MouseHit(1) Then
		mx = MouseX()
		my = MouseY()
		For i = 1 To numFiles
			If pnr(mx,my,pos(i,0),pos(i,1),135,17) Then
				hilite(pos(i,0),pos(i,1),135,17,255,160,32)
				Flip
				Delay 200
				FlushMouse()
				choice = i
				Exit
			End If
		Next
		If pnr(mx,my,986,5,33,19) Then
			hilite(986,5,33,19,255,255,255)
			Flip
			Delay 300
			FreeFont fontVerdana14
			FreeFont fontVerdana48
			End
		End If
		Return choice
	End If
	If KeyHit(1) Then
		FreeFont fontVerdana14
		FreeFont fontVerdana48
		End
	End If
End Function

Function readData(choice%, numFiles%)
	Local fileName$, in$
	Local fin%, i%

	If choice <1 Or choice>numFiles Then Return

	fileName$ = "IFS Data\"+picName$(choice)+".ifs"
	fin = ReadFile(fileName$)
	in$ = ReadLine(fin)
	numRows = Word$(in$,1)
	Dim a(numRows), b(numRows), c(numRows)
	Dim d(numRows), e(numRows), f(numRows)
	Dim p(numRows)
	xMult = Word$(in$,2)
	yMult = Word$(in$,3)
	xOffset = Word$(in$,4)
	yOffset = Word$(in$,5)
	For i = 1 To numRows
		in$ = ReadLine(fin)
		a(i) = Word$(in$,1)
		b(i) = Word$(in$,2)
		c(i) = Word$(in$,3)
		d(i) = Word$(in$,4)
		e(i) = Word$(in$,5)
		f(i) = Word$(in$,6)
		p(i) = Word$(in$,7)
		p(i) = p(i) + p(i-1)
	Next
	CloseFile(fin)
End Function

Function display(choice%)
	Local k%, j%, i%, xp%, yp%, clr%
	Local xalt#, yalt#, x#, y#, pct#

	xalt=0.5 : yalt=0.5
	LockBuffer()
	For k = 1 To 10000
		For j = 1 To 5
			pct=Rnd(0.0, 1.0)
			For i = 1 To numRows
				If pct <= p(i) Then Exit
			Next
			If i > numRows Then i = numRows
			x = a(i) * xalt + b(i) * yalt + e(i)
			y = c(i) * xalt + d(i) * yalt + f(i)
			xp = Int(x*xMult) + xOffset 

			If si(choice)=1 Then
				;image doesn't require inversion
				yp=Int(y*yMult)+yOffset
			Else
				;yup, invert the image
				yp = (768-Int(y*yMult)) + yOffset
			End If
			If si(choice)=2 Then
				clr = Int(yp/32)
			Else
				clr = Int(Sqr((cx-xp)*(cx-xp) + (cy-yp)*(cy-yp))/band + coff) Mod 24
			End If
			If xp>=0 And xp<1024 And yp>=0 And yp<768 Then
				WritePixelFast(xp,yp,hxc(clr))
			End If
	        xalt = x : yalt = y
    	Next
	Next
	UnlockBuffer()
End Function

Function justName$(fileName$)
;=====================================================================
; Strip full path info from fileName$ - only name of file+ext is
; returned. If fileName$ not found - return null string
;=====================================================================
	Local nPos%, i%, lastPos%

	If fileName$ <> "" Then
		nPos = 1
		For i = 1 To 99
			nPos = Instr(fileName$,"\",nPos)
			If nPos <> 0 Then
				lastPos = nPos + 1
				nPos = lastPos
			Else
				;No more back whacks EXIT the For...Next loop
				Exit
			End If
		Next
		Return Right(fileName$, Len(fileName$)-lastPos+1) 
	Else
		Return ""
	End If
End Function 

Function justNameEx$(filename$)
;=====================================================================
; Strips file extension from fileName$ - only name of file without file
; extension is returned. If filename not found - return null string
;=====================================================================
	Local nPos%, i%, lastPos%

	;PART ONE: Remove any path info from filename$
	If fileName$ <> "" Then
		nPos = 1
		For i = 1 To 99
			nPos = Instr(fileName$,"\",nPos)
			If nPos <> 0 Then
				lastPos = nPos + 1
				nPos = lastPos
			Else
				;No more back whacks. EXIT the For...Next loop
				Exit
			End If
		Next
		fileSansPath$ = Right(filename$,Len(filename$)-lastPos+1)
	Else
		fileSansPath$ = ""
		Return ""
	End If
	;PART TWO: If fileSansPath$ is NOT null,
	;the extract file name w/o file extension
	If fileSansPath$ = "" Then Return
	dpos% = Instr(filename$,".",1)
	strLen% = Len(filename$)
	If dpos Then
		Return Left(filename$, strLen-(strLen-dpos) -1 )
	Else
		Return filename$
	End If
End Function

Function Word$(string2Chk$, n, delimiter$=",")
	Local count%, findDelimiter%, position%, current$

	count = 0
	findDelimiter = 0
	position = 1
	If n > 0 Then
		string2Chk$  = Trim(string2Chk$)
		Repeat
			findDelimiter% = Instr(string2Chk$,delimiter$,position)
			If findDelimiter <> 0 Then
				current$ = Mid$(string2Chk$,position,findDelimiter-position)
				count = count + 1
				position = findDelimiter + 1
				If count = n Then findDelimiter = 0
			End If
		Until findDelimiter = 0
		If (count < n) And (position <= Len(string2Chk$)) Then
			current$ = Mid$(string2Chk$,position, Len(string2Chk$) - position+1)
			count = count + 1
			If count < n Then current$ = ""
		End If
	End If
	Return current$
End Function

Function wrapText%(x%, y%, msg$, wide%, fr%, fg%, fb%, br%, bg%, bb%, center% = 0)
;====================================================================================
; This function wraps text inside of a rounded rectangle with the option to center
; the wrapped text within the rounded rectangle.
;====================================================================================
; x,y = upperleft coordinates of the rounded rectangle
; msg$ = text string that you wish to place in rounded rectangle
; wide = maximum width of button in pixels
; fr, fg, fb = text color (RGB triplet)
; br, bg, bb = button color (RGB triplet)
; center = when 'center' = 1 then each line of text is centered
;		the default setting is zero. (no centering)
;====================================================================================
;NB: placing /n/ in your text will insert a new line at that position.
;	If at the beginning of message string must be in form of "/n/{space}blah blah"
;	If in middle of message string must be in form of "blah{space}/n/{space} blah"
;	If at the end of message string must in form of "blah blah{space}/n/"
;====================================================================================
	Local rad%, initX%, initY%, txtHigh%, count%, nxtWord$, flag%, txtCenter%
	Local tLine$, temp$, lineCount%, boxWide%, boxHigh%, pad%, tLen%

	Dim work$(100,1)
	pad = 10
	rad = 7  ;radius of rounded corner - values 2 To 26 recommended
	diam = rad + rad ;diameter of circles used to make rounded corners
	initX = x : initY = y
	txtWide = wide - pad*2
	txtHigh = StringHeight(msg$) ;height of current font in pixels
	x = x : y = y + pad
	Repeat
		count = count + 1
		nxtWord$ = Word$(msg$, count, " ")
		If Lower(Trim(nxtWord$)) = "/n/" Then newLine = 1
		tLine$ = temp$
		If Word$(msg$,count+1," ") = "" Then
			temp$ = temp$ + nxtWord$
		Else
			temp$ = temp$ + nxtWord$ + " "
		End If
		If (StringWidth(temp$) >= txtWide) Or (newLine = 1) Then
			tLine$ = Trim(tLine$)
			lineCount = lineCount+1
			work$(lineCount,0) = Str(x)+" "+Str(y)
			work$(lineCount,1) = tLine$
			If newLine = 1 Then
				newLine = 0
				count = count + 1
				lineCount = lineCount + 1
				y = y + txtHigh
			End If
			y = y + txtHigh
			temp$ = ""
			count = count-1
		End If
	Until nxtWord$ = ""
	tLine$ = Trim(tLine$)
	If work$(lineCount,1) <> tLine$ Then
		lineCount = lineCount + 1
		work$(lineCount,0) = Str(x)+" "+Str(y)
		work$(lineCount,1) = tLine$
	End If
	boxWide = wide
	boxHigh = lineCount * txtHigh + pad*2
	Color br, bg, bb
	Oval initX, initY, diam, diam, True
	Oval initX, initY+boxHigh-diam-1, diam, diam, True
	Oval initX+boxWide-diam-1, initY, diam, diam, True
	Oval initX+boxWide-diam-1, initY+boxHigh-diam-1, diam, diam, True
	Rect initX, initY+rad, boxWide-1, boxHigh-diam-1, True
	Rect initX+rad, initY, boxWide-diam-1, boxHigh-1, True
	Color fr, fg, fb
	For i = 1 To lineCount
		x = Word$(work$(i,0),1," ")
		y = Word$(work$(i,0),2," ")
		If center = 1 Then
			tLen = StringWidth(work$(i,1))
			txtCenter = (boxWide - tLen) Shr 1
			x = x + txtCenter
		Else 
			x = x + pad
		End If
		Text x, y, work$(i,1)
	Next
	Dim work$(1,1)
End Function

Function drawBox (msg$,x%,y%,w%=168,h%=17,rbox%=255,gbox%=255,bbox%=255, rtext%=0,gtext%=0,btext%=0)
	Color rbox,gbox,bbox
	Rect x,y,w,h,True
	Color rtext,gtext,btext
	Text x+3,y+2,msg$
End Function

Function hilite(x,y,w,h,r,g,b)
	Color r,g,b
	Rect x-2,y-2,w+4,h+4,False
	Rect x-1,y-1,w+2,h+2,False
End Function

Function pnr(px, py, rx, ry, rw, rh)
;====================================================================================
;   Function "Point In Rectangle"
;====================================================================================
; This function checks to see if the point (px,py) is within the specified rectangle.
;
; If the point is inside the rectangle a value of 1 is returned.
;
; If the point is NOT inside the rectangle a value of 0 (zero) is returned.
;====================================================================================
; px = the X coord of the point in question
; py = the Y coord of the point in question
; rx = Upper  Left X coord of rectangle
; ry = Upper  Left Y coord of rectangle
; rw =  width of rectangle
; rh = height of rectangle
;====================================================================================
    Return ((px>=rx) And (px<=(rx+rw-1)) And (py>=ry) And (py<=(ry+rh-1)))
End Function

Function h2d$(hx$)
	Local hi%, lo%
	
	hx$ = Upper(hx$)
	hi = Asc( Left(hx$,1))-48
	lo = Asc(Right(hx$,1))-48
	If hi>10 Then hi=hi-7
	If lo>10 Then lo=lo-7
	Return hi Shl 4 Or lo
End Function

Function palette()
	Local i%, j%, count%
	Local triplet$
	hx8$(1)="0000FF4000FF7D00FFBE00FFFF00FFFF00BEFF007DFF0040"
	hx8$(2)="FF0000FF4000FF7D00FFBE00FFFF00BEFF007DFF0040FF00"
	hx8$(3)="00FF0000FF4000FF7D00FFBE00FFFF00BEFF007DFF0040FF"
	count = 0
	For i = 1 To 3
		For j = 1 To 43 Step 6
			triplet$ = Mid(hx8$(i),j,6)
			rr(count) = h2d$(Mid(triplet$,1,2))
			gg(count) = h2d$(Mid(triplet$,3,2))
			bb(count) = h2d$(Mid(triplet$,5,2))
			hxc(count) = rr(count) Shl 16 Or gg(count) Shl 8 Or bb(count)
			count = count + 1
		Next
	Next
End Function

Comments

Andy_A2015
This is the data folder which has all of the parameter values for each of the IFS fractals

Copy and paste this code into the SAME folder where you saved the IFS Fractal viewing code.

If you just pasted and ran the viewing code, the file is the
in the '.tmp' folder of your Blitz installation.

Run the pasted code and you will find 'IFSdata.7z' has been written to that folder.

Use 7zip do decompress the file using the 'Extract Here' option.

The folder 'IFS Data' is now ready to use by the viewer.

Run the viewer.



virtlands2015
Hi Andy_A, It's amazingly fast and clever. Thanks. :)




Guy Fawkes2015
WOW! AMAZING! =D


Andy_A2015
Thanks guys

I may have found more parameters for some new fractals. I'll probably post them as individual text files. Just save to the 'IFS Data' folder and they'll be good to go.


virtlands2015
Following is a view of some antique software known as Fractint.

Fractint --> http://www.nahee.com/spanky/www/fractint/fractint.html
VirtualBox --> https://www.virtualbox.org/
VMWare Player --> https://my.vmware.com/web/vmware/free#desktop_end_user_computing/vmware_player/7_0



-----------------------------------------------------------------------------------

For some reason, I can't run Winfract on Windows 8.1 .
The OS won't let me run it, but I can run Fractint inside a Virtual machine.


Guy Fawkes2015
Cool! =D


Andy_A2015
You might try downloading 'winfract'. It's the Windows version of fractint. Runs great, no need for virtual machine.


zoqfotpik2015
Wow, this is very cool. IFS fractals are completely, utterly bizarre.

If you don't mind, what documents did you read when coding this?


zoqfotpik2015
Try Xaos if all you want is super-fast mandelbrot zooms. Think it might be GPU accelerated but I'm not sure-- maybe not, come to think of it


Andy_A2015
I started with Wikipedia and started following links until I had enough info to start coding. Funny is that it only takes very simple math to view the IFS fractals. What requires effort is designing something in particular (i.e. not something at random).


virtlands2015
Funny is that it only takes very simple math to view the IFS fractals.

...I know, a lot of times it's mostly the GUI (pronounced "gooey") that takes most of the programming effort.

A handful of fractal math & complex numbers is easy to imagine from scratch, but it's the graphical interface that becomes the time hog. (=_=)


Code Archives Forum