Mandelbrot- What am I doning wrong?

BlitzMax Forums/BlitzMax Programming/Mandelbrot- What am I doning wrong?

Sveinung(Posted 2005) [#1]
I have tryed to update a BB3D mandelbrot routin.
Something is screwed up...colors!!!
Where are they?

Can someone please help me?

Here is the code:
Strict

AppTitle = "Mandelbrot"

'vars
Global maxval:Float = 128.0
Global sx:Float = -2.025
Global sy:Float = -1.125
Global ex:Float = 0.6
Global ey:Float = 1.125

Global x1:Float = 640.0
Global y1:Float = 480.0
Global xy:Float = x1/y1

Global xstart:Float = sx
Global ystart:Float = sy
Global xend:Float = ex
Global yend:Float = ey

Global xzoom:Float = (xend - xstart) / x1
Global yzoom:Float = (yend - ystart) / y1
Global fac:Float = 0.99

'display
Graphics x1,y1,0

xend = xend*fac
xstart = xstart*fac
yend = yend*fac
ystart = ystart*fac

xzoom = (xend - xstart) / x1
yzoom = (yend - ystart) / y1
	
mandelbrot()
	
Flip()
FlushMem()
	
WaitKey
End

Function mandelbrot()
	Local x:Float
	Local y:Float
	
	Local h:Float
	Local old:Float
	Local b:Float
	
	For x = 0 To x1 - 1
		For y = 0 To y1 - 1
			h = DotCol(xstart + xzoom * x,ystart + yzoom * y)
			'Print h
			If h <> old
				b = 1.0 - h * h
				HSB2RGB(h,0.8,b) 
				old = h
			EndIf
			Plot x,y
		Next
	Next
EndFunction

Function DotCol(xval:Float,yval:Float)
	Local r:Float
	Local i:Float
	Local j:Float
	Local m:Float
	
	While (j < maxval) And (m < 4.0)
		j = j + 1
		m = r * r - i * i
		i = 2.0 * r * i + yval
		r = m + xval
	Wend
	'Print j
	'j = j / maxval
	Return j
EndFunction

Function HSB2RGB(hue:Float,sat:Float,bri:Float)
	Local dof:Float
	Local red:Float
	Local green:Float
	Local blue:Float
	
	If bri = 0 Then SetColor 0,0,0
	If sat = 0 Then SetColor bri*255,bri*255,bri*255
	
	
	
	
	If hue < 1.0/6.0
		dof = hue
		red = bri
		blue = bri * (1.0 - sat)
		green = blue + (bri - blue) * dof * 6.0
		SetColor red*255,green*255,blue*255
	Else
		If hue < 2.0/6.0
			dof = hue - 1.0/6.0
			green = bri
			blue = bri * (1.0 - sat)
			red = green - (bri - blue) * dof * 6.0
			SetColor red*255,green*255,blue*255
		Else
			If hue < 3.0/6.0
				dof = hue - 2.0/6.0
				green = bri
				red = bri * (1.0 - sat)
				blue = red + (bri - red) * dof * 6.0
				SetColor red*255,green*255,blue*255
			Else
				If hue < 4.0/6.0
					dof = hue - 3.0/6.0
					blue = bri
					red = bri * (1.0 - sat)
					green = blue - (bri - red) * dof * 6.0
					SetColor red*255,green*255,blue*255
				Else
					If hue < 5.0/6.0
					dof = hue - 4.0/6.0
					blue = bri
					green = bri * (1.0 - sat)
					red = green + (bri - green) * dof * 6.0
					SetColor red*255,green*255,blue*255
				Else
					dof = hue - 5.0/6.0
					red = bri
					green = bri * (1.0 - sat)
					blue = red - (bri - green) * dof * 6.0
					SetColor red*255,green*255,blue*255
				EndIf
			EndIf
		EndIf
	EndIf
EndIf
EndFunction


Regards
Sveinung


Scott Shaver(Posted 2005) [#2]
hue:4.00000000 sat:0.800000012 bri:-15.0000000
red:-15.0000000 grn:-2.99999976 blu:213.000000
hue:6.00000000 sat:0.800000012 bri:-35.0000000
red:-35.0000000 grn:-6.99999952 blu:832.999939
hue:8.00000000 sat:0.800000012 bri:-63.0000000
red:-63.0000000 grn:-12.5999994 blu:2104.20020
hue:128.000000 sat:0.800000012 bri:-16383.0000
red:-16383.0000 grn:-3276.59985 blu:9983801.00

your red and green values are all negative and the blue value way off the charts. 0 to 255 are the allow values.


TartanTangerine (was Indiepath)(Posted 2005) [#3]
Definately something to do with the dotcol function. But you probably knew that already.


ImaginaryHuman(Posted 2005) [#4]
HSV conversion should be simple enough. It starts off with the red at 255 and the others at 0. Green increases to 255. Then red falls to 0. Then blue increases to 255. Then green falls to 0. Then red increases to 255. Then blue falls to 0.

At least that's what seems to happen.

So you can indeed convert it to RBG using 6 steps, one each to handle each component going up or down. It should be simple. Maybe it'd be easier not to use floats?


Scott Shaver(Posted 2005) [#5]
the hue never comes out less than 1, so the inner most else statement is the one that always gets executed. looks like anyway.


Sveinung(Posted 2005) [#6]
@Indiepath.T
Yes, I think you'r right and yes I know. But what I do not know.

@Scott Shaver
Any ideas why that happens?

Here is the BB3D code
; Project: Mandelbrot - Speedtest
; Start: Tuesday, September 09, 2003
; Blitz3D - Linker Version 1.64


Global maxiter#=128 ; max iterations
SX# = -2.025 ; start value real
SY# = -1.125 ; start value imaginary
EX# = 0.6    ; End value real
EY# = 1.125  ; End value imaginary

x1# = 640    ; ScreenX
y1# = 480    ; ScreenY
xy# = x1# / y1#; x/y-ratio

   Graphics 640, 480, 16, 2
   xstart# = SX#
   ystart# = SY#
   xende# = EX#
   yende# = EY#

   xzoom# = (xende# - xstart#) / x1#
   yzoom# = (yende# - ystart#) / y1#
   fac#=0.999

  SetBuffer BackBuffer()
  While Not KeyDown(1)
      Cls
      xende# = xende#*fac#
      xstart#=xstart#*fac#
      ystart#=ystart#*fac#
      yende#=yende#*fac#
      xzoom# = (xende# - xstart#) / x1#
      yzoom# = (yende# - ystart#) / y1#
      mandelbrot(x1#, y1#, xstart#, ystart#, xzoom#, yzoom#)
      Locate 0,0
      thistime# = MilliSecs()
      Print "Speed: " + Str$(Int(x1#*y1# / (1+(thistime#-lasttime#)))) + " Kpix/sec"
      lasttime#=thistime#
      Flip
   Wend
End

; ------------------------------------------------------------- ;
; -=#  Mandelbrot  #=-
; ------------------------------------------------------------- ;
; calculate all points
Function mandelbrot(x1#, y1#, xstart#, ystart#, xzoom#, yzoom#)
; Local x, y, h, b, old, col
   LockBuffer BackBuffer()
   For x = 0 To x1#-1
      For y = 0 To y1#-1
         h# = DotsColor#(xstart# + xzoom# * x, ystart# + yzoom# * y) ; Color value
         If h# <> old#
            b# = 1.0 - h# * h# ; brightness
            col = HSBtoRGB(h#, 0.8, b#)
            old# = h#
         EndIf
         WritePixelFast x, y, col
      Next
   Next
   UnlockBuffer BackBuffer()
End Function


; ------------------------------------------------------------- ;
; -=#  DotsColor  #=-
; ------------------------------------------------------------- ;
; Color value from 0.0 To 1.0 by iterations
Function DotsColor#(xval#, yval#)
; Local r, i, j, m
   While (j# < maxiter#) And (m# < 4.0)
      j#=j#+1.0
      m# = r# * r# - i# * i#
      i# = 2.0 * r# * i# + yval#
      r# = m# + xval#
   Wend
   j# = j# / maxiter#
   Return j#
End Function

; ------------------------------------------------------------- ;
; -=#  RGB-Function - Come on, that's an important one...  #=-
; ------------------------------------------------------------- ;
Function RGB(red, green, blue)
   Return (red Shl 16) + (green Shl 8) + blue
End Function


; ------------------------------------------------------------- ;
; -=#  HSB2RGB  #=-
; ------------------------------------------------------------- ;
Function HSBtoRGB(hue#, saturation#, brightness#)
; Local red, green, blue, domainOffset // hue Mod 1/6

   If brightness# = 0 Then Return 0
   If saturation# = 0 Then Return RGB(Int(brightness#*255), Int(brightness#*255), Int(brightness#*255))

   ; Select not with <> allowed, have to use If here...
   If hue#  < 1.0/6.0
      ; red domain; green ascends
      domainOffset# = hue#
      red#   = brightness#
      blue#  = brightness# * (1.0 - saturation#)
      green# = blue# + (brightness# - blue#) * domainOffset# * 6
   Else
      If hue#  < 2.0/6.0
         ; yellow domain; red descends
         domainOffset# = hue# - 1.0/6.0
         green# = brightness#
         blue#  = brightness# * (1.0 - saturation#)
         red#   = green# - (brightness# - blue#) * domainOffset# * 6.0
      Else
         If hue#  < 3.0/6.0
            ; green domain; blue ascends
            domainOffset# = hue# - 2.0/6.0
            green# = brightness#
            red#   = brightness# * (1.0 - saturation#)
            blue#  = red# + (brightness# - red#) * domainOffset# * 6.0
         Else
            If hue#  < 4.0/6.0
               ; cyan domain; green descends
               domainOffset# = hue# - .5
               blue#  = brightness#
               red#   = brightness# * (1.0 - saturation#)
               green# = blue# - (brightness# - red#) * domainOffset# * 6.0
            Else
               If hue#  < 5.0/6.0
                  ; blue domain; red ascends
                  domainOffset# = hue# - 5.0/6.0
                  blue#  = brightness#
                  green# = brightness# * (1.0 - saturation#)
                  red#   = green# + (brightness# - green#) * domainOffset# * 6.0
               Else
                  ; magenta domain; blue descends
                  domainOffset# = hue# - 5.0/6.0
                  red#   = brightness#
                  green# = brightness# * (1.0 - saturation#)
                  blue#  = red# - (brightness# - green#) * domainOffset# * 6.0
               EndIf
            EndIf
         EndIf
      EndIf
   EndIf
   Return RGB(red# * 255.0, green# * 255.0, blue# * 255.0)
End Function


Sveinung


klepto2(Posted 2005) [#7]
Try adding 'SetGraphicsDriver GLMax2DDriver()' before the Graphics command.
The Gl driver catch the negative values for colors.
The DX driver not.
You can see a post of mark in the bug forum.

http://www.blitzbasic.com/Community/posts.php?topic=48646


Scott Shaver(Posted 2005) [#8]
okay so I converted the b3d code over to B+ and it works. I converted the BMax code over to B+ and is still doesn't work. I wanted to see if there was an operator precendence problem. There isn't.

One thing your missing is the

j = j / maxval

line in the DotDCol function is commented out but that just gets us a red screen instead of blue. Other than that the code looks the same.


Scott Shaver(Posted 2005) [#9]
I know what it is! The DotCol function is returning an int it should return a float

Function DotCol:Float(xval:Float,yval:Float)
Local r:Float
Local i:Float
Local j:Float
Local m:Float

While (j < maxval) And (m < 4.0)
j = j + 1.0
m = (r * r) - (i * i)
i = ((2.0 * r) * i) + yval
r = m + xval
Wend

j = j / maxval
Return j
EndFunction


Sveinung(Posted 2005) [#10]
Scott your the MAN!!!
Thanks

Works fine now!

Sveinung


MacSven(Posted 2005) [#11]
Works great! I want to see the picture in realtime rendering.