Ich hab hier im Forum schon einige Fraktal-Scripts gesehen, und da wollte ich es einmal selbst versuchen.
Diese 4 Programme sind dabei herausgekommen, ich würde mich über Rückmeldungen freuen ;).
Für jedes Script wird die GDIP.au3 benötigt, da ich es für blödsinnig hielt so viele Funktionen manuell in jedes Script zu kopieren. (Falls ihr je gedacht habt, dass die standard UDF GDIPlus.au3 unvollständig scheint, werdet ihr den Download nicht bereuen ^^.)
Drachenkurve
http://de.wikipedia.org/wiki/Drachenkurve
[autoit]#include <GDIP.au3>
[/autoit] [autoit][/autoit] [autoit]$iWidth = 1000
$iHeight = 1000
$iDistance = 50
$iIterations = 13 ;Bitte vorsichtig erhöhen, da ALLE Koordinaten des Fraktals zum selben Zeitpunkt im Speicher sind.
$hWnd = GUICreate("GDI+ Dragon-Curve | Iterations: " & $iIterations, $iWidth, $iHeight)
GUISetState()
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
$hPen = _GDIPlus_PenCreate(0xFF000000, 1)
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddLine($hPath, 1, 0, 0, 0)
_GDIPlus_PathAddLine($hPath, 0, 0, 0, 1)
_GDIPlus_PathAddLine($hPath, 0, 1, 1, 1)
_GDIPlus_PathAddLine($hPath, 1, 1, 1, 2)
For $iI = 1 To $iIterations
$aPoint = _GDIPlus_PathGetLastPoint($hPath)
$hPathBuffer = _GDIPlus_PathClone($hPath)
$hMatrix_R = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix_R, $aPoint[0], $aPoint[1])
_GDIPlus_MatrixRotate($hMatrix_R, 90)
_GDIPlus_MatrixTranslate($hMatrix_R, -$aPoint[0], -$aPoint[1])
_GDIPlus_PathTransform($hPathBuffer, $hMatrix_R)
_GDIPlus_PathReverse($hPathBuffer)
_GDIPlus_PathAddPath($hPath, $hPathBuffer, False)
_GDIPlus_PathDispose($hPathBuffer)
_GDIPlus_MatrixDispose($hMatrix_R)
Next
Do
$aBounds = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
If $aBounds[2] > $aBounds[3] Then
$nScale = ($iWidth - $iDistance * 2) / $aBounds[2]
Else
$nScale = ($iHeight - $iDistance * 2) / $aBounds[3]
EndIf
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixScale($hMatrix, $nScale, $nScale)
_GDIPlus_PathTransform($hPath, $hMatrix)
_GDIPlus_MatrixDispose($hMatrix)
$aBounds = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
Until Abs(($iWidth - $iDistance * 2) - $aBounds[2]) <= 10 Or Abs(($iHeight - $iDistance * 2) - $aBounds[3]) <= 10
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0] + $iWidth / 2 - $aBounds[2] / 2, -$aBounds[1] + $iHeight / 2 - $aBounds[3] / 2)
_GDIPlus_PathTransform($hPath, $hMatrix)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_GraphicsDrawPath($hBuffer, $hPath, $hPen)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_PenDispose($hPen)
_GDIPlus_PathDispose($hPath)
_GDIPlus_Shutdown()
While GUIGetMsg() <> -3
WEnd
Koch-Kurve
http://de.wikipedia.org/wiki/Koch-Kurve
[autoit]#include <GDIP.au3>
[/autoit] [autoit][/autoit] [autoit]$iWidth = 800
$iHeight = 300
$iDistance = 10
$nAngle = 60
$iIterations = 8 ;Bitte vorsichtig erhöhen, da ALLE Koordinaten des Fraktals zum selben Zeitpunkt im Speicher sind.
$hWnd = GUICreate("GDI+ Koch-Curve | Iterations: " & $iIterations, $iWidth, $iHeight)
GUISetState()
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
$hPen = _GDIPlus_PenCreate(0xFF000000, 1)
$hPath = _GDIPlus_PathCreate()
;~ _GDIPlus_PathStartFigure($hPath)
_GDIPlus_PathAddLine($hPath, 0, 0, 1, 0)
For $iI = 1 To $iIterations
$hPathBuffer = _GDIPlus_PathClone($hPath)
$aPoint = _GDIPlus_PathGetLastPoint($hPath)
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix, $aPoint[0], $aPoint[1])
_GDIPlus_MatrixRotate($hMatrix, -$nAngle)
_GDIPlus_PathTransform($hPathBuffer, $hMatrix)
_GDIPlus_PathAddPath($hPath, $hPathBuffer, True)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_PathDispose($hPathBuffer)
$hPathBuffer = _GDIPlus_PathClone($hPath)
_GDIPlus_PathReverse($hPathBuffer)
$aPoint = _GDIPlus_PathGetLastPoint($hPath)
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixSetElements($hMatrix, -1, 0, 0, 1, $aPoint[0] * 2, 0)
_GDIPlus_PathTransform($hPathBuffer, $hMatrix)
_GDIPlus_PathAddPath($hPath, $hPathBuffer, True)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_PathDispose($hPathBuffer)
Next
;~ _GDIPlus_PathCloseFigure($hPath)
[/autoit] [autoit][/autoit] [autoit]Do
$aBounds = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
If $aBounds[2] > $aBounds[3] Then
$nScale = ($iWidth - $iDistance * 2) / $aBounds[2]
Else
$nScale = ($iHeight - $iDistance * 2) / $aBounds[3]
EndIf
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixScale($hMatrix, $nScale, $nScale)
_GDIPlus_PathTransform($hPath, $hMatrix)
_GDIPlus_MatrixDispose($hMatrix)
$aBounds = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
Until Abs(($iWidth - $iDistance * 2) - $aBounds[2]) <= 10 Or Abs(($iHeight - $iDistance * 2) - $aBounds[3]) <= 10
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0] + $iWidth / 2 - $aBounds[2] / 2, -$aBounds[1] + $iHeight / 2 - $aBounds[3] / 2)
_GDIPlus_PathTransform($hPath, $hMatrix)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_GraphicsDrawPath($hBuffer, $hPath, $hPen)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_PenDispose($hPen)
_GDIPlus_PathDispose($hPath)
_GDIPlus_Shutdown()
While GUIGetMsg() <> -3
WEnd
Sierpinski-Dreieck
http://de.wikipedia.org/wiki/Sierpinski-Dreieck
[autoit]#include <GDIP.au3>
#include <Array.au3>
$iWidth = 800
$iHeight = 800
$iIterations = 8 ;Bitte vorsichtig erhöhen, da ALLE Koordinaten des Fraktals zum selben Zeitpunkt im Speicher sind.
[/autoit] [autoit][/autoit] [autoit]$hWnd = GUICreate("GDI+ Sierpinski-Triangle | Iterations: " & $iIterations, $iWidth, $iHeight)
GUISetState()
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)
_GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, 2)
_GDIPlus_GraphicsClear($hBuffer, 0xFFFFFFFF)
$hBrush = _GDIPlus_BrushCreateSolid()
[/autoit] [autoit][/autoit] [autoit]Global $aCoord[3 ^ ($iIterations + 1) + 1][2] = [[3]]
$aCoord[1][0] = 0
$aCoord[1][1] = 0
$aCoord[2][0] = $iWidth
$aCoord[2][1] = 0
$aCoord[3][0] = $iWidth / 2
$aCoord[3][1] = Sqrt($iWidth ^ 2 - ($iWidth / 2) ^ 2)
For $iI = 1 To $iIterations
$aOld = $aCoord
$aCoord[0][0] = 0
For $i = 1 To $aOld[0][0] Step 3
$nTriBX = $aOld[$i + 2][0] - $aOld[$i][0]
$nTriCX = ($aOld[$i + 2][0] - $aOld[$i][0]) / 2
$nTriCY = ($aOld[$i + 2][1] - $aOld[$i][1]) / 2
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0]
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1]
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriBX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1]
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriCX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1] + $nTriCY
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriBX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1]
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i + 1][0]
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1]
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriBX + $nTriCX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1] + $nTriCY
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriCX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1] + $nTriCY
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i][0] + $nTriBX + $nTriCX
$aCoord[$aCoord[0][0]][1] = $aOld[$i][1] + $nTriCY
$aCoord[0][0] += 1
$aCoord[$aCoord[0][0]][0] = $aOld[$i + 2][0]
$aCoord[$aCoord[0][0]][1] = $aOld[$i + 2][1]
Next
Next
Dim $aTmp[4][2] = [[3]]
For $i = 1 To $aCoord[0][0] Step 3
$aTmp[1][0] = $aCoord[$i][0]
$aTmp[1][1] = $iHeight - $aCoord[$i][1]
$aTmp[2][0] = $aCoord[$i + 1][0]
$aTmp[2][1] = $iHeight - $aCoord[$i + 1][1]
$aTmp[3][0] = $aCoord[$i + 2][0]
$aTmp[3][1] = $iHeight - $aCoord[$i + 2][1]
_GDIPlus_GraphicsFillPolygon($hBuffer, $aTmp, $hBrush)
Next
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight)
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_Shutdown()
While GUIGetMsg() <> -3
WEnd
Sierpinski-Dreieck v2.0
Diese Version basiert auf der verarbeitung von Bitmaps in einem IFS. D.h. es können auch Bilder oder Ellipsen als Grundobjekt zur Konstruktion des Fraktals verwendet werden (dazu muss lediglich eine Zeile im Code verändert werden). Die entsprechende Stelle findet ihr in Zeile 22-24.
[autoit]#include <GDIP.au3>
[/autoit] [autoit][/autoit] [autoit]$iWidth = 1150
$iHeight = Sqrt($iWidth ^ 2 - ($iWidth / 2) ^ 2)
$iIterations = 5 ;Bitte vorsichtig erhöhen, da ALLE Koordinaten des Fraktals zum selben Zeitpunkt im Speicher sind.
$hWnd = GUICreate("GDI+ Sierpinski-Triangle | Iterations: " & $iIterations, $iWidth, $iHeight)
GUISetState()
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap1 = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
$hBitmap2 = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
$hBuffer1 = _GDIPlus_ImageGetGraphicsContext($hBitmap1)
$hBuffer2 = _GDIPlus_ImageGetGraphicsContext($hBitmap2)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer1, 2)
_GDIPlus_GraphicsSetInterpolationMode($hBuffer1, 2)
_GDIPlus_GraphicsSetInterpolationMode($hBuffer2, 2)
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
;~ Dim $aPoints[4][2] = [[3],[0, 0],[$iWidth, 0],[$iWidth / 2, $iHeight]]
;~ _GDIPlus_GraphicsFillPolygon($hBuffer1, $aPoints)
_GDIPlus_GraphicsFillEllipse($hBuffer1, $iWidth / 2 - $iHeight / 2, 0, $iHeight, $iHeight) ;Durch beliebige geometrische Figur ersetzen. Bilder sind auch möglich.
For $iI = 1 To $iIterations
If Mod($iI, 2) Then
$hBuffer = $hBuffer2
$hBitmap = $hBitmap1
Else
$hBuffer = $hBuffer1
$hBitmap = $hBitmap2
EndIf
_GDIPlus_GraphicsClear($hBuffer, 0)
_GDIPlus_GraphicsDrawImageRect($hBuffer, $hBitmap, 0, 0, $iWidth / 2, $iHeight / 2)
_GDIPlus_GraphicsDrawImageRect($hBuffer, $hBitmap, $iWidth / 2, 0, $iWidth / 2, $iHeight / 2)
_GDIPlus_GraphicsDrawImageRect($hBuffer, $hBitmap, $iWidth / 4, $iHeight / 2, $iWidth / 2, $iHeight / 2)
Next
If Mod($iIterations + 1, 2) Then
$hBuffer = $hBuffer2
$hBitmap = $hBitmap1
Else
$hBuffer = $hBuffer1
$hBitmap = $hBitmap2
EndIf
_GDIPlus_GraphicsTranslateTransform($hGraphics, $iWidth / 2, $iHeight / 2)
_GDIPlus_GraphicsRotateTransform($hGraphics, 180)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, -$iWidth / 2, -$iHeight / 2, $iWidth, $iHeight)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_GraphicsDispose($hBuffer1)
_GDIPlus_GraphicsDispose($hBuffer2)
_GDIPlus_BitmapDispose($hBitmap1)
_GDIPlus_BitmapDispose($hBitmap2)
_GDIPlus_Shutdown()
While GUIGetMsg() <> -3
WEnd
Jedes dieser Fraktale wird nach dem IFS Prinzip generiert. (Das Grundobjekt wird durch eine endliche Anzahl von Funktionen, die aus einer Matrix und einem Verschiebungsvektor bestehen jeweils kopiert, dann verkleinert, rotiert und verschoben. Dieser Vorgang wird je nach gewünschter Iterationstiefe beliebig oft wiederholt.) Dabei macht man sich die Selbstähnlichkeit der Fraktale zunutze.