4D Mandelbrot

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Joel

Betreff: 4D Mandelbrot

BeitragSo, März 11, 2012 14:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe letztlich einen Code verfasst der die Mandelbrotmenge in Quaternionen berechnet, stat wie normalerweise in den Komplexen Zahlen.
Allerdings ist der Rendervorgang etwas langsam.

Das Mandelbrot wird auf die Koordinaten x,y,z und w gerechnet woraus dann ein 3D schnitt gezeigt wird.
Mit den Tasten Hoch/Runter,Links/Rechts,A/Y Bewegt man sich.
Mit den Tasten S/X kann man sich durch die w-Achse bewegen
BlitzMax: [AUSKLAPPEN]
SuperStrict

Const GWIDTH:Int = 400, GHEIGHT:Int = 300
Const stp:Byte = 2

Global GWIDTH2:Float = GWIDTH / 2.0, GHEIGHT2:Float = GHEIGHT / 2.0

Graphics GWIDTH, GHEIGHT

Const Res:Int = 100
Global Voxel:Byte[Res, Res, Res, Res]

Global CamX:Float, CamY:Float, CamZ:Float, CamW:Float
Global CamYaw:Float
CamX = Res / 3
CamY = Res / 2
CamZ = 0
CamW = Res / 2

Const CamSpeed:Float = 4

Global Light:Int

Global Res2:Int = Res / 2
Local Res5:Float = Res / 4

Print ""
Print "Calculate Mandelbrot"
For Local x:Int = 0 Until Res
For Local y:Int = 0 Until Res
For Local z:Int = 0 Until Res
For Local w:Int = 0 Until Res
If Mandelbrot4D(100, (x - Res2) / Res5, (y - Res2) / Res5, (z - Res2) / Res5, (w - Res2) / Res5) Then Voxel[x, y, z, w] = 1
Next
Next
Next
Print x + "/" + Res
Next

Print "Compute Light"
For Local x:Int = 0 Until Res
For Local y:Int = 0 Until Res
For Local z:Int = 0 Until Res
For Local w:Int = 0 Until Res
If voxel[x, y, z, w] > 0
If GetVoxel(x - 1, y, z, w) > 0 Then Light:+1
If GetVoxel(x - 1, y - 1, z, w) > 0 Then Light:+1
If GetVoxel(x - 1, y - 1, z - 1, w) > 0 Then Light:+1
If GetVoxel(x, y - 1, z, w) > 0 Then Light:+1
If GetVoxel(x, y - 1, z - 1, w) > 0 Then Light:+1
If GetVoxel(x, y, z - 1, w) > 0 Then Light:+1
If GetVoxel(x - 1, y, z - 1, w) > 0 Then Light:+1
voxel[x, y, z, w] = 255 - (25 * Light)
Light = 0
EndIf
Next
Next
Next
Next

Print "Finished"

Global millis:Int


While Not KeyHit(KEY_ESCAPE)
If KeyDown(KEY_A)
CamX:+Cos(CamYaw + 90) * CamSpeed
CamZ:+Sin(CamYaw + 90) * CamSpeed
End If
If KeyDown(KEY_Y)
CamX:-Cos(CamYaw + 90) * CamSpeed
CamZ:-Sin(CamYaw + 90) * CamSpeed
End If
CamY:+(KeyDown(KEY_DOWN) - KeyDown(KEY_UP)) * CamSpeed
CamYaw:+(KeyDown(KEY_LEFT) - KeyDown(KEY_RIGHT)) * CamSpeed * 5
CamW:+(KeyDown(KEY_S) - KeyDown(KEY_X))
millis = MilliSecs()
Render()
DrawText "Render Time: " + (MilliSecs() - millis) + "ms", 0, 0
Flip 0
Cls
Wend

Function Render()
For Local x:Int = 0 Until GWIDTH Step stp
For Local y:Int = 0 Until GHEIGHT Step stp
Local PickX:Float = CamX
Local PickY:Float = CamY
Local PickZ:Float = CamZ
Local PickSX:Float = (x - GWIDTH2) / GWIDTH2
Local PickSY:Float = (y - GHEIGHT2) / GHEIGHT2
Local PickSZ:Float = 1

Local Dist:Float = Sqr(PickSX * PickSX + PickSZ * PickSZ)

Local winkel:Float = ATan2(PickSZ, PickSX) + CamYaw
PickSX = Cos(winkel) * Dist
PickSZ = Sin(winkel) * Dist
For Local n:Int = 0 To Res2
PickX:+PickSX
PickY:+PickSY
PickZ:+PickSZ
If GetVoxel(PickX, PickY, PickZ, CamW) > 0
SetColor voxel[PickX, PickY, PickZ, CamW], voxel[PickX, PickY, PickZ, CamW], voxel[PickX, PickY, PickZ, CamW]
DrawRect x, y, stp, stp
Exit
End If
Next
Next
Next
End Function

Function GetVoxel:Byte(x:Int, y:Int, z:Int, w:Int = 50)
If x >= 0 And x < Res And y >= 0 And y < Res And z >= 0 And z < Res
Return Voxel[x, y, z, w]
EndIf
Return 0
End Function

Function Mandelbrot4D:Byte(Iterationen:Int, x:Float, y:Float, z:Float, w:Float, a:Float=0, b:Float=0, c:Float=0, d:Float=0)
Local a1:Float, b1:Float, c1:Float, d1:Float
Local itr:Int = 0
Repeat
If itr = Iterationen Then Return 1

a1 = a * a - b * b - c * c - d * d + x
b1 = 2 * a * b + y
c1 = 2 * a * c + z
d1 = 2 * a * d + w

a = a1
b = b1
c = c1
d = d1

itr:+1

Until a * a + b * b + c * c + d * d >= 4
Return 0
End Function


Da man mit einem 4D-Array keine sehr grosse Auflösung hinbekommt, hier noch eine Version in der die w-Achse nicht berechnet wird BlitzMax: [AUSKLAPPEN]
SuperStrict

Const GWIDTH:Int = 400, GHEIGHT:Int = 300
Const stp:Byte = 2

Global GWIDTH2:Float = GWIDTH / 2, GHEIGHT2:Float = GHEIGHT / 2

Graphics GWIDTH, GHEIGHT

Const Res:Int = 300
Global Voxel:Byte[Res, Res, Res]

Global CamX:Float, CamY:Float, CamZ:Float, CamW:Float
Global CamYaw:Float
CamX = Res / 3
CamY = Res / 2
CamZ = 0
CamW = Res / 2

Const CamSpeed:Float = 4

Global Light:Int

Global Res2:Int = Res / 2
Local Res5:Float = Res / 4

DrawText "Calculate Mandelbrot", 0, 0
Flip 0
For Local x:Int = 0 Until Res
For Local y:Int = 0 Until Res
For Local z:Int = 0 Until Res
If Mandelbrot4D(100, (x - Res2) / Res5, (y - Res2) / Res5, (z - Res2) / Res5, 0) Then Voxel[x, y, z] = 1
Next
Next
Print x + "/" + Res
Next

DrawText "Compute Light", 0, 15
Flip 0
For Local x:Int = 0 Until Res
For Local y:Int = 0 Until Res
For Local z:Int = 0 Until Res
If voxel[x, y, z] > 0
If GetVoxel(x - 1, y, z) > 0 Then Light:+1
If GetVoxel(x - 1, y - 1, z) > 0 Then Light:+1
If GetVoxel(x - 1, y - 1, z - 1) > 0 Then Light:+1
If GetVoxel(x, y - 1, z) > 0 Then Light:+1
If GetVoxel(x, y - 1, z - 1) > 0 Then Light:+1
If GetVoxel(x, y, z - 1) > 0 Then Light:+1
If GetVoxel(x - 1, y, z - 1) > 0 Then Light:+1
voxel[x, y, z] = 255 - (25 * Light)
Light = 0
EndIf
Next
Next
Print x + "/" + Res
Next

Print "Finished"

Global millis:Int


While Not KeyHit(KEY_ESCAPE)
If KeyDown(KEY_A)
CamX:+Cos(CamYaw + 90) * CamSpeed
CamZ:+Sin(CamYaw + 90) * CamSpeed
End If
If KeyDown(KEY_Y)
CamX:-Cos(CamYaw + 90) * CamSpeed
CamZ:-Sin(CamYaw + 90) * CamSpeed
End If
CamY:+(KeyDown(KEY_DOWN) - KeyDown(KEY_UP)) * CamSpeed
CamYaw:+(KeyDown(KEY_LEFT) - KeyDown(KEY_RIGHT)) * CamSpeed * 2
CamW:+(KeyDown(KEY_S) - KeyDown(KEY_X))
millis = MilliSecs()
Render()
DrawText "Render Time: " + (MilliSecs() - millis) + "ms", 0, 0
Flip 0
Cls
Wend

Function Render()
For Local x:Int = 0 Until GWIDTH Step stp
For Local y:Int = 0 Until GHEIGHT Step stp
Local PickX:Float = CamX
Local PickY:Float = CamY
Local PickZ:Float = CamZ
Local PickSX:Float = (x - GWIDTH2) / GWIDTH2
Local PickSY:Float = (y - GHEIGHT2) / GHEIGHT2
Local PickSZ:Float = 1

Local Dist:Float = Sqr(PickSX * PickSX + PickSZ * PickSZ)

Local winkel:Float = ATan2(PickSZ, PickSX) + CamYaw
PickSX = Cos(winkel) * Dist
PickSZ = Sin(winkel) * Dist
For Local n:Int = 0 To Res2
PickX:+PickSX
PickY:+PickSY
PickZ:+PickSZ
If GetVoxel(PickX, PickY, PickZ) > 0
SetColor voxel[PickX, PickY, PickZ], voxel[PickX, PickY, PickZ], voxel[PickX, PickY, PickZ]
DrawRect x, y, stp, stp
Exit
End If
Next
Next
Next
End Function

Function GetVoxel:Byte(x:Int, y:Int, z:Int)
If x >= 0 And x < Res And y >= 0 And y < Res And z >= 0 And z < Res
Return Voxel[x, y, z]
EndIf
Return 0
End Function

Function Mandelbrot4D:Byte(Iterationen:Int, x:Float, y:Float, z:Float, w:Float, a:Float=0, b:Float=0, c:Float=0, d:Float=0)
Local a1:Float, b1:Float, c1:Float, d1:Float
Local itr:Int = 0
Repeat
If itr = Iterationen Then Return 1

a1 = a * a - b * b - c * c - d * d + x
b1 = 2 * a * b + y
c1 = 2 * a * c + z
d1 = 2 * a * d + w

a = a1
b = b1
c = c1
d = d1

itr:+1

Until a * a + b * b + c * c + d * d >= 4
Return 0
End Function

Viel Spass!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group