(GDI) Hopalong Fraktal

  • Hi!

    Fasziniert von Fraktalen bin ich zur Zeit. Jetzt mal ein etwas außergewöhnliches Fraktal. Das sogenannte Hopalong, oder zu Deutsch: Hüpfer.

    Das ganze ist mit GDI realisiert und auch relativ schnell. Die Grafik wird auf 4 Werten aufgebaut: a,b,c und num. Num ist die Wertgrenze und a bis c sind die Startwerte. Sie können frei gewählt werden, positiv oder negativ, der Kreativität sind keine Grenzen gesetzt.

    Im Skript kann man die Werte im Array $Frac einstellen. Einfach dort die Randomfunktionen ersetzen, ansonsten wird das Bild zufällig. Zwei verrückte Beispiele hab ich auch noch als Kommentar dringelassen.

    Also viel Spaß damit ;)

    PS: Geportet von SmallBASIC

    //UPDATE: letzte Version war Schrott, ich Depp hab den Zoom vergessen :rolleyes:

    //UPDATE: Speicherfunktion

    //UPDATE: Diverse Korrekturen von Marsi

  • ganz nett ;D
    sieht gut aus^^

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

  • Moin,

    Bei sowas ist es sinnvoll die Funktionen möglichst kurz zu halten, damit der Interpreter nicht so viel interpretiert.

    hab auf die Schnelle nur eine kleinigkeit gefunden die das ganze um ca. 25% beschleunigt.

    Das Monstrum:

    [autoit]

    Func SGN($i)
    If $i < 0 Then
    Return -1
    ElseIf $i = 0 Then
    Return 0
    ElseIf $i > 0 Then
    Return 1
    EndIf
    EndFunc ;==>SGN

    [/autoit]


    Der kleine Bruder:

    [autoit]

    Func SGN($i)
    Return ($i>0)-($i<0)
    EndFunc ;==>SGN

    [/autoit]


    Wenn man diesen Einzeiler jetzt direkt einbaut entfällt zusätzlich noch ein Funktionsaufruf.
    Bei mir hat das ca. 25% ausgemacht.

    lg
    M

  • Vorschläge:

    1. Statt das GUI zu löschen und neu zu erstellen, nur um den Titel zu ändern, kann man auch einfach einfach WinSetTitle nehmen.
    - Jetzt ist aber das bild nicht mehr schön schwarz: BitBlt -> BLACKNESS hilft.

    [autoit]

    ;GUIDelete($Form1)
    ;$Form1 = GUICreate("Fractal: Hopalong (Hüpfer) | a=" & $Frac[0] & ", b=" & $Frac[1] & ", c=" & $Frac[2] & ", num=" & $Frac[3], 1000, 600, -1, -1)
    ;GUISetState(@SW_SHOW)
    ;GUISetBkColor(0)
    ; Ersetzen durch:
    WinSetTitle($Form1, '', "Fractal: Hopalong (Hüpfer) | a=" & $Frac[0] & ", b=" & $Frac[1] & ", c=" & $Frac[2] & ", num=" & $Frac[3])
    DllCall($gdi32, "bool", "BitBlt", "handle", $dc, "int", 0, "int",0, "int", 1000, "int", 600, "handle", 0, "int", 0, "int", 0, "dword", $BLACKNESS)

    [/autoit]


    - Jetzt klappt das mit dem DC nicht mehr.
    Richtig. Das DC holt man sich nun EIN Mal und nicht jedes Mal^^

    2. Der $Divider wird nicht verändert. Eine erneute Deklaration ist nicht nötig.

    3. Auch wenn es im Prinzip eine Nebensache ist. Eine Schleife ohne Sleep verbraucht viel Prozessorlast und damit Strom.
    Die Do schleife wird durch GuiGetMsg gelenkt. Bei den _Ispressed Abfragen kann man z.B. ein AND Sleep(10) dranhängen und schon ist alles schön.

    4. Du öffnest 2 Dlls und ergatterst (nur noch) ein DC. Trotzdem wird keines der Drei Sachen am Ende wieder freigegeben.

    Berichtigt könnte das etwa so aussehen.

    Skript
    [autoit]

    ; Hüpfer Fraktal Generator
    ; minx 2012
    ; GDI

    [/autoit] [autoit][/autoit] [autoit]

    ; Du kannst die Fraktalwerte a,b,c dargestellt durch den Array "$Frac"
    ; beliebig auswählen. Der Divider gibt die Größendivision an, je kleiner
    ; desto näher ist das Bild.

    [/autoit] [autoit][/autoit] [autoit]

    #include <Misc.au3>
    #include <Array.au3>
    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;-------- Begin changes ---------------------------------------------------------------------------------
    Dim $Frac[4] = [Random(-100, 100, 1), Random(-10.100, 0.100, 1), Random(-100, 100, 1), Random(0, 500000, 1)]
    Local $Divider = 2
    ;-------- Stop chaning here -----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $BLACKNESS = 0x00000042

    [/autoit] [autoit][/autoit] [autoit]

    $Form1 = GUICreate("Fractal: Hopalong (Hüpfer) | a=" & $Frac[0] & ", b=" & $Frac[1] & ", c=" & $Frac[2] & ", num=" & $Frac[3], 1000, 600, -1, -1)
    GUISetState(@SW_SHOW)
    GUISetBkColor(0)

    [/autoit] [autoit][/autoit] [autoit]

    $user32 = DllOpen("user32.dll")
    $gdi32 = DllOpen("gdi32.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $dc = GetDC($Form1)
    Draw($Frac[0], $Frac[1], $Frac[2], $Frac[3], $Divider)

    [/autoit] [autoit][/autoit] [autoit]

    Do

    [/autoit] [autoit][/autoit] [autoit]

    If _IsPressed("52") Then

    [/autoit] [autoit][/autoit] [autoit]

    While _IsPressed("52") And Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($gdi32, "bool", "BitBlt", "handle", $dc, "int", 0, "int", 0, "int", 1000, "int", 600, "handle", 0, "int", 0, "int", 0, "dword", $BLACKNESS)
    WinSetTitle($Form1, '', "Fractal: Hopalong (Hüpfer) | a=" & $Frac[0] & ", b=" & $Frac[1] & ", c=" & $Frac[2] & ", num=" & $Frac[3])

    [/autoit] [autoit][/autoit] [autoit]

    Dim $Frac[4] = [Random(-100, 100, 1), Random(-10.100, 0.100, 1), Random(-100, 100, 1), Random(0, 500000, 1)]
    Draw($Frac[0], $Frac[1], $Frac[2], $Frac[3], $Divider)

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf _IsPressed("53") Then

    [/autoit] [autoit][/autoit] [autoit]

    While _IsPressed("53") And Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ClipPut(_ArrayToString($Frac, ", "))
    MsgBox(0, "", "Put to Clipboard")

    [/autoit] [autoit][/autoit] [autoit]

    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Until GUIGetMsg() = -3

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_ReleaseDC($Form1, $dc)
    DllClose($gdi32)
    DllClose($user32)

    [/autoit] [autoit][/autoit] [autoit]

    Func pix($dc, $x, $y, $color)
    DllCall($gdi32, "long", "SetPixel", "long", $dc, "long", $x, "long", $y, "long", $color)
    EndFunc ;==>pix

    [/autoit] [autoit][/autoit] [autoit]

    Func GetDC($handle)
    $aRet = DllCall($user32, "int", "GetDC", "hwnd", $handle)
    Return $aRet[0]
    EndFunc ;==>GetDC

    [/autoit] [autoit][/autoit] [autoit]

    Func Draw($a = 10, $b = 10, $c = 10, $num = 100000, $Divider = 2)
    Local $iTimer = TimerInit()
    $j = $a
    $k = $b
    $x = 0
    $y = 0
    $xx = 0
    $xp = 0
    $yp = 0
    $r = 0
    $i = 0
    $xoffs = 1000
    $yoffs = 600
    $color = 0xAA
    For $i = 1 To $num
    $color = 0xAA * $i
    $xx = $y - (($x > 0) - ($x < 0)) * Sqrt(Abs($k * $x - $c))
    $y = $j - $x
    $x = $xx
    $xp = $x * $Divider + $xoffs
    $yp = $y * $Divider + $yoffs
    pix($dc, $xp / $Divider, $yp / $Divider, $color)
    Next
    ConsoleWrite('Zeit pro 10k Px: ' & Round(TimerDiff($iTimer) / $Frac[3] * 10000, 2) & @CRLF)
    EndFunc ;==>Draw

    [/autoit]


    .
    .