1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 5. Dezember 2010 um 15:22
    Zitat

    Bei einem 2000x2000 Bild 15 ms rechendauer.

    hehe, bei der "Rechendauer" ist der gesamte FASM-Kram noch dabei, das heisst incl. Programm Assemblieren!
    Bei meinem Referenz-P3 mit 1,2Ghz dauert z.B. das Assemblieren genauso lange wie das die eigentliche ASM-Programmlaufzeit!
    Mal schauen, was die SSE-Befehle bringen, ich hoffe, ich habe in der nächsten Woche bissl mehr Zeit...
    Aber Faktor 2-3 sollte mindestens dabei rauskommen.
    Aber auch mein selbstausgedachter Algorithmus ist nicht der langsamste, ein Referenzprogramm in C# hab ich jedenfalls schonmal um Faktor 50 abgehängt. Der prüft jedes Pixel des Buffers erstmal, ob es überhaupt im Viereck liegt. Das dauert... :D

    Da der ASM-Code threadsicher ist, könnte man natürlich auch mehrere Kerne einbinden! Dazu muss der Assemblercode nicht geändert werden, das funktioniert auch direkt aus AutoIt!

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 4. Dezember 2010 um 20:24

    Funktion steht soweit, ich hab bissl getestet und mir ist kein Grafik-Bug mehr aufgefallen.
    Einschränkend muss man allerdings sagen, dass nur "richtige" Trapezoide verwendet werden dürfen, soll heissen, konvexe konkave Vierecke (bei denen ein Eckpunkt innerhalb des Dreiecks der anderen drei Eckpunkte liegt) werden nicht dargestellt!
    Die Abfrage dahingehend ist noch nicht implementiert, also ist es (noch) nicht möglich, die "Rückseite" eines Bildes zu betrachten :rolleyes:

    Anbei der grob zusammengehackte Code. Bin gerade dabei, alles bissl zu straffen und aufzuhübschen. Dann wird es auch eine FASM-lose AutoIt-Funktion geben, und natürlich auch eine DLL, um die Funktion in anderen Programmen nutzen zu können.

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlusConstants.au3>
    #include <StructureConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <array.au3>
    #include <GDIConstants.au3>
    #include <AssembleIt.au3>

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

    Opt("GuiOnEventMode", 1)

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

    ;Global $aDrag[5][2] = [[0, 0],[1, 1],[800, 50],[700, 530],[500, 450]]
    ;Global $aDrag[5][2] = [[0, 0],[15,10],[700, 300],[720, 330],[11, 380]]
    ;Global $aDrag[5][2] = [[0, 0],[35, 100],[100, 35],[750, 350],[110, 380]]
    ;Global $aDrag[5][2] = [[0, 0],[10, 30],[700, 30],[700, 500],[10, 500]]
    Global $aDrag[5][2] = [[0, 0],[10, 30],[175, 30],[175, 157],[10, 157]]
    ;Global $aDrag[5][2] = [[0, 0],[587, 67],[693, 79],[715, 434],[89, 461]]
    ;Global $aDrag[5][2] = [[0, 0],[200, 67],[450, 67],[500, 100],[300, 150]]

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

    ;Global $aDrag[5][2] = [[0, 0],[140, 99],[554, 99],[750, 350],[99, 454]]
    ;Global $aDrag[5][2] = [[0, 0],[135, 108],[140, 100],[658, 347],[429, 454]]
    ;Global $aDrag[5][2] = [[0, 0],[91, 242],[696, 172],[705, 447],[91, 314]]
    ;Global $aDrag[5][2] = [[0, 0],[35, 107],[693, 79],[715, 434],[89, 461]]
    ;Global $aDrag[5][2] = [[0, 0],[35, 30],[45, 25],[715, 334],[489, 491]]

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

    Global $minx, $miny, $maxx, $maxy, $struct_float, $ptr_orginal, $bi, $b_buffer, $struct_buffer, $h
    Global $b_buffer = 800, $h_buffer = 540, $struct_koord

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

    $hGui = GUICreate("DrawImage_4Points Test", 800, 580)
    GUISetOnEvent(-3, "_Exit")
    GUICtrlCreateButton("render with higher precision", 200, 550, 200, 20)
    GUICtrlSetOnEvent(-1, "_Render")
    GUICtrlCreateLabel("precision:", 410, 550, 80, 20, 0x0002)
    $cSlider = GUICtrlCreateSlider(500, 545, 100, 25)
    GUICtrlSetData(-1, 25)
    GUICtrlSetOnEvent(-1, "_Slider")
    $cLabel = GUICtrlCreateLabel("0.25", 610, 550, 50, 20)

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

    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($b_buffer, $h_buffer, $hGraphics)
    $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)

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

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState()

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

    $hBrush = _GDIPlus_BrushCreateSolid(0x8800FF00)
    $hPen = _GDIPlus_PenCreate(0xFFFF0000)

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

    $sFile = FileOpenDialog("open image", "", "(*.jpg;*.bmp;*.png;*.tif;*.gif)")
    $hImage = _GDIPlus_ImageLoadFromFile($sfile)
    Global $iwidth, $iheight
    Local $ptr_orginal
    Local $hDC_orginal = getDCfromfile($sfile, $ptr_orginal) ;GDI+ lädt auch jpg

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

    Global $struct = DllStructCreate("dword[" & $iwidth * $iheight & "]", $ptr_orginal)
    ;global $himagefile="mona-lisa.jpg"

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

    _ReDraw(0.02)

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

    $iIndex = 0
    While 1
    $aInfo = GUIGetCursorInfo($hGui)

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

    If Not $aInfo[2] Then $iIndex = 0
    Switch $iIndex
    Case 0
    If $aInfo[2] Then
    For $I = 1 To 4
    If $aInfo[0] > $aDrag[$I][0] - 5 And $aInfo[0] < $aDrag[$I][0] + 5 And $aInfo[1] > $aDrag[$I][1] - 5 And $aInfo[1] < $aDrag[$I][1] + 5 Then
    $iIndex = $I
    Sleep(100)
    ExitLoop
    EndIf
    Next
    EndIf
    Case Else
    $aDrag[$iIndex][0] = $aInfo[0]
    $aDrag[$iIndex][1] = $aInfo[1]
    _ReDraw(0.02)
    EndSwitch

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

    Sleep(20)
    WEnd

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

    Func _projective_mapping($hbitmap_1, $hImage, $1x, $1y, $2x, $2y, $3x, $3y, $4x, $4y) ;eck-koordinaten projektion, obere linke und untere rechte Ecke Orginal

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

    ;struct aufbauen, in der sämtliche für das ASM-Programm wichtigen Werte gesammelt werden.
    ;so muss nur noch die Startadresse dieser Struct an das ASM-Programm übergeben werden
    $struct_float = DllStructCreate("align 16;float _var[8];uint _pos[8];ptr _buffer;ptr _orginal;int _b_buffer;int b_orginal; uint size") ;die 8 variablen und die 8 koordinaten

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

    $bi = _GDIPlus_ImageGetWidth($hImage)
    $h = _GDIPlus_ImageGetHeight($hImage)

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

    $u = 1 ;koordinaten oben rechts im $image
    $v = 1
    $2x = $2x - 1 ;breite und höhe sind eins kleiner, wenn man von 0 anfängt zu zählen...
    $3x = $3x - 1
    $3y = $3y - 1
    $4y = $4y - 1

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

    $BitmapData = _GDIPlus_BitmapLockBits($hbitmap_1, 0, 0, $b_buffer, $h_buffer, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

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

    ;struct mit Daten füllen
    Global $ptr_buffer = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap.
    ; Global $struct_buffer = DllStructCreate("dword [" & $b_buffer * $h_buffer & "]", $ptr_buffer)
    DllStructSetData($struct_float, 3, $ptr_buffer, 1)
    DllStructSetData($struct_float, 4, $ptr_orginal, 1)
    DllStructSetData($struct_float, 5, $b_buffer, 1)
    DllStructSetData($struct_float, 6, $bi, 1)
    DllStructSetData($struct_float, 7, $bi*$h, 1)

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

    Dim $bl[8] = [$u, $bi, $bi, $u, $v, $v, $h, $h] ;lösungen der 8 Gleichungen (Eck-Koordinaten Orginalbild)
    Dim $a[8][8] = [ _ ;8 gleichungen in Matrix
    [$1x, $1y, 1, 0, 0, 0, -$1x * $u, -$1y * $u], _ ;Eckpunkte Transformiertes Rechteck
    [$2x, $2y, 1, 0, 0, 0, -$2x * $bi, -$2y * $bi], _
    [$3x, $3y, 1, 0, 0, 0, -$3x * $bi, -$3y * $bi], _ ;Eckpunkte Transformiertes Rechteck
    [$4x, $4y, 1, 0, 0, 0, -$4x * $u, -$4y * $u], _
    [0, 0, 0, $1x, $1y, 1, -$1x * $v, -$1y * $v], _ ;Eckpunkte Transformiertes Rechteck
    [0, 0, 0, $2x, $2y, 1, -$2x * $v, -$2y * $v], _
    [0, 0, 0, $3x, $3y, 1, -$3x * $h, -$3y * $h], _
    [0, 0, 0, $4x, $4y, 1, -$4x * $h, -$4y * $h]] ;Eckpunkte Transformiertes Rechteck

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

    $s = _solve_linear_quad($a, $bl) ;8 lineare Gleichungen lösen

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

    For $I = 1 To 8 ;struct mit daten aus dem gleichungslöser füllen
    DllStructSetData($struct_float, 1, $s[$I - 1], $I)
    Next
    ;~ Dim $m[5]
    ;~ Dim $b[5]

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

    ;geraden 4-1 und 3-2 y=mx+b

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

    ;~ If $4x = $1x Then ;falls gerade senkrecht
    ;~ $m[4] = 1.234e9 ;irgendeinen wert generieren zum kennzeichnen
    ;~ Else ;ansonsten
    ;~ $m[4] = ($4y - $1y) / ($4x - $1x)
    ;~ $b[4] = $1y - $m[4] * $1x
    ;~ EndIf

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

    ;~ If $3x = $2x Then
    ;~ $m[2] = 1.234e9
    ;~ Else
    ;~ $m[2] = ($3y - $2y) / ($3x - $2x)
    ;~ $b[2] = $2y - $m[2] * $2x
    ;~ EndIf
    ;~ ;geraden 1-2 und 3-4 y=mx+b
    ;~ If $2x = $1x Then
    ;~ $m[1] = 1.234e9
    ;~ Else
    ;~ $m[1] = ($2y - $1y) / ($2x - $1x)
    ;~ $b[1] = $1y - $m[1] * $1x
    ;~ EndIf

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

    ;~ If $3x = $4x Then
    ;~ $m[3] = 1.234e9
    ;~ Else
    ;~ $m[3] = ($3y - $4y) / ($3x - $4x)
    ;~ $b[3] = $3y - $m[3] * $3x
    ;~ EndIf

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

    ;$struct_koord = DllStructCreate("uint[8]"); struct für die x- und y-koordinaten

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

    ;kleinstes und grösstes x und y finden, um nicht die gesamte bitmap durchzurechnen, sondern
    ;nur den Teil, der von dem quadrilateral belegt ist
    ;~ Global $minx = 1e9, $miny = 1e9, $maxx = 0, $maxy = 0
    ;~ Dim $sx[5] ;Eckpunkte x
    ;~ Dim $sy[5] ;Eckpunkte y

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

    For $I = 1 To 4
    DllStructSetData($struct_float, 2, Eval($I & "x"), $I * 2 - 1);struct füllen
    DllStructSetData($struct_float, 2, Eval($I & "y"), $I * 2);1x,1y,2x,2y,3x...
    ;~ If Eval($I & "x") < $minx Then $minx = Eval($I & "x");minimum und maximum finden
    ;~ If Eval($I & "x") > $maxx Then $maxx = Eval($I & "x")
    ;~ If Eval($I & "y") > $maxy Then $maxy = Eval($I & "y")
    ;~ If Eval($I & "y") < $miny Then
    ;~ $miny = Eval($I & "y")
    ;~ $indexL = $I ;index ist die aktuelle Koordinate, L=linksrum R=rechtsrum gezählt von der minimalen (obersten) y-Position
    ;~ EndIf
    ;~ $sx[$I] = Eval($I & "x") ;adresse punkt1
    ;~ $sy[$I] = Eval($I & "y") ;adresse punkt1
    Next
    $time = TimerInit()
    ; $_assembleit_flag = 0
    $ret = _AssembleIt("ptr", "_quadrilateral", "ptr", DllStructGetPtr($struct_float))
    ;MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$ret' & @lf & @lf & 'Return:' & @lf & $ret) ;### Debug MSGBOX
    $mtime = TimerDiff($time)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Mtime = ' & $mtime & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

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

    ;~ $indexR = $indexL ;rechte seite nächster punkt
    ;~ $mR = $m[$indexR] ;steigung rechte gerade
    ;~ $bR = $b[$indexR]
    ;~ $indexR += 1 ;gerade zum nächsten Punkt im Uhrzeigersinn
    ;~ If $indexR = 5 Then $indexR = 1
    ;~ $indexL = $indexL - 1 ;linke seite vorheriger punkt
    ;~ If $indexL = 0 Then $indexL = 4
    ;~ $mL = $m[$indexL] ;steigung linke gerade
    ;~ $bl = $b[$indexL]
    ; MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$ret' & @LF & @LF & 'Return:' & @LF & $ret) ;### Debug MSGBOX

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

    ;MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$indexL' & @LF & @LF & 'Return:' & @LF & $indexL) ;### Debug MSGBOX
    ; _arraydisplay($s)
    ;~ For $py = $miny To $maxy Step 1
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : p = ' & $py & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ If $py = $sy[$indexL] Then ;nächsten punkt links gefunden
    ;~ If $sy[$indexL] <> $maxy Then ;nur, wenn nächster schnittpunkt nicht der unterste ist..
    ;~ $indexL = $indexL - 1 ;linke seite
    ;~ If $indexL = 0 Then $indexL = 4
    ;~ ; msgbox(0,$indexL&" sy="&$sy[$indexL]&" ymax="&$maxy,"linke seite nächsten punkt gefunden")
    ;~ $mL = $m[$indexL] ;steigung linke gerade
    ;~ $bl = $b[$indexL]
    ;~ EndIf
    ;~ EndIf
    ;~ If $mL = 1.234e9 Or $mL = 0 Then
    ;~ $xL = $sx[$indexL]
    ;~ Else
    ;~ $xL = Int(($py - $bl) / $mL) ;von rechter grenze
    ;~ EndIf
    ;~ ; MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$xL' & @LF & @LF & 'Return:' & @LF & $xL) ;### Debug MSGBOX
    ;~ ;if $sx[$indexL]=$sx[$index then $xR=$sx[$indexL]

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

    ;~ If $mR = 1.234e9 Or $mR = 0 Then ;falls steigung 0 oder unendlich
    ;~ $xR = $sx[$indexR]
    ;~ Else
    ;~ $xR = Int(($py - $bR) / $mR);...bis zur linken
    ;~ EndIf
    ;~ ; MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$xR' & @LF & @LF & 'Return:' & @LF & $xR) ;### Debug MSGBOX
    ;~ ;if $sy[$indexR]=$py then $xR=$sx[$indexR]

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

    ;~ For $px = $xL To $xR
    ;~ $X = Round(($s[0] * $px + $s[1] * $py + $s[2]) / ($s[6] * $px + $s[7] * $py + 1))
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $X = ' & $X & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ $Y = Round(($s[3] * $px + $s[4] * $py + $s[5]) / ($s[6] * $px + $s[7] * $py + 1))
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Y = ' & $Y & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ $col = DllStructGetData($struct, 1, ($Y - 1) * $bi + $X) ;farbe aus bild holen
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bi = ' & $bi & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $col = ' & $col & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ DllStructSetData($struct_buffer, 1, $col, $py * $b_buffer + $px + 1)
    ;~ ;MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$py * $b_buffer + $px + 1' & @lf & @lf & 'Return:' & @lf & hex($py * $b_buffer + $px + 1)) ;### Debug MSGBOX
    ;~ Next

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

    ;~ If $xR = $sx[$indexR] And $sy[$indexR] = $py Then ;auf rechter Seite nächsten Schnittpunkt gefunden
    ;~ ; msgbox(0,$indexR,"schnittpunkt gefunden")

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

    ;~ If $sy[$indexR] <> $maxy Then ;nur, wenn nächster schnittpunkt nicht der unterste ist..

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

    ;~ $mR = $m[$indexR] ;steigung rechte gerade
    ;~ $bR = $b[$indexR]
    ;~ $indexR += 1 ;gerade zum nächsten Punkt im Uhrzeigersinn
    ;~ If $indexR = 5 Then $indexR = 1
    ;~ ; msgbox(0,$indexR,"nächster schnittpunkt ist "&$indexR)
    ;~ EndIf
    ;~ EndIf
    ;~ Next

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

    ;~ $t = TimerInit()
    _GDIPlus_BitmapUnlockBits($hbitmap_1, $BitmapData)

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

    EndFunc ;==>_projective_mapping

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

    Func _quadrilateral()
    _("use32")
    _("org " & FasmGetBasePtr($Fasm))
    _("jmp _los")
    _("align 4")
    ; Alle Variablen deklarieren und für SIMD an 16 Bytegrenzen ausrichten = alignen

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

    _("_m1 dd 12345678") ;y=m*x+b geradengleichung
    _("_m2 dd 12345678") ;m=(x2-x1)/(y2-y1)
    _("_m3 dd 12345678") ;addresse _m3=_m1+(4*(index-1))
    _("_m4 dd 12345678") ;
    _("_b1 dd 0.0") ;b=y-m*x
    _("_b2 dd 0.0")
    _("_b3 dd 0.0") ;
    _("_b4 dd 0.0")
    _("_mR dd 0.0") ;
    _("_bR dd 0.0") ;
    _("_mL dd 0.0") ;
    _("_bL dd 0.0") ;
    _("_indexL dd 0")
    _("_indexR dd 0")
    _("_minx dd 100000")
    _("_miny dd 100000")
    _("_maxx dd 1")
    _("_maxy dd 1")
    _("_eins dd 1")
    _("_vier dd 4") ;30
    _("_xL dd 0")
    _("_xR dd 0")
    _("_ptr_var dd 8 dup(0)") ;ptr variablen aus gleichungslöser
    _("_ptr_posxy dd 8 dup(0)") ;ptr auf liste eckpunkte
    _("_buffer dd 0") ;pointer auf den backbuffer
    _("_orginal dd 0") ;pointer auf die orginal bitmap
    _("_b_buffer dd 0") ;breite backbuffer
    _("_b_orginal dd 0") ;breite backbuffer
    _("_size_orginal dd 0") ;breite backbuffer

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

    _("_px dd 0") ;koordinaten im backbuffer
    _("_py dd 0")
    _("_x dd 0") ;koordinaten im orginal
    _("_y dd 0")

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

    ; _("_ausgleich dd 0.001")

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

    _("_los:")
    _("finit") ;coproinit 27

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

    ;struct auflösen, macht weniger arbeit...
    _("mov esi,dword[esp+4]")
    _("mov ecx,21") ;breite backbuffer
    _("mov edi,_ptr_var")
    _("rep movsd")

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

    ;~ _("mov eax,esi");dword[_b_orginal]")
    ;~ _("ret") ;breite backbuffer

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

    ;minimum und maximum der koordinaten bestimmen
    _("mov ebx,_ptr_posxy")
    _("mov ecx,4") ;for $i=3 to 1 step -1
    _("_minmax:")
    _("mov eax,dword[ebx+(ecx-1)*4*2]") ;x-koordinate holen
    _("cmp eax,dword[_minx]") ;mit minx vergleichen
    _("jg @f") ;wenn grösser, weiter
    _("mov dword[_minx],eax") ;wenn kleiner, dann speichern
    _("@@:")
    _("cmp eax,dword[_maxx]") ;mit maxx vergleichen
    _("jl @f") ;wenn kleiner, weiter
    _("mov dword[_maxx],eax") ;wenn grösser, dann speichern
    _("@@:")
    _("mov eax,dword[ebx+(ecx-1)*4*2+4]") ;y-koordinate holen
    _("cmp eax,dword[_miny]") ;mit miny vergleichen
    _("jg @f") ;wenn grösser, weiter
    _("mov dword[_miny],eax") ;wenn kleiner, dann speichern
    _("mov dword[_indexL],ecx") ;wenn kleiner, dann speichern
    _("@@:")
    _("cmp eax,dword[_maxy]") ;mit maxy vergleichen
    _("jl @f") ;wenn kleiner, weiter
    _("mov dword[_maxy],eax") ;wenn grösser, dann speichern
    _("@@:")
    _("loop _minmax") ;solange, bis ecx=0

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

    ;~ _("mov eax,dword[_maxx]")
    ;~ _("ret")

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

    ;geradengleichungen werden gebraucht, um die bei gegebenen y (zeile)
    ;die anfangs und endpunkte (x) der pixelzeile im viereck zu finden

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

    ;$m4 = ($4y - $1y) / ($4x - $1x)
    ;If $4x = $1x Then ;falls gerade senkrecht
    ; $m[4] = 1.234e9 ;irgendeinen wert generieren zum kennzeichnen
    ;Else ;ansonsten
    ; $m[4] = ($4y - $1y) / ($4x - $1x)
    ; $b[4] = $1y - $m[4] * $1x
    ;EndIf
    _("")
    _("")
    _("mov ecx,_ptr_posxy") ;koordinaten
    _("")
    _("mov eax,dword[ecx+4*6]") ;4x
    ;_("ret")

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

    _("cmp eax,dword[ecx+4*0]") ;ist 4x=1x
    _("je @f") ;wenn gleich, dann springe zum nächsten lokalen label
    _("fild dword[ecx+4*7]") ;st0=4y
    _("fisub dword[ecx+4*1]") ;st0=(4y-1y)
    _("fild dword[ecx+4*6]") ;st0=4x st1=(4y-1y)
    _("fisub dword[ecx+4*0]") ;st0=(4x-1x)
    _("fdivp") ;st0=m4
    _("fst dword[_m4]") ;st0=m4
    ;$b1 = $1y - $m1 * $1x
    _("fimul dword[ecx+4*0]") ;st0=m1*1x
    _("fisubr dword[ecx+4*1]") ;st0=1y-m1*1x = b1
    _("fstp dword[_b4]") ;b1 speichern, fpstack clean

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

    ;$m2 = ($3y - $2y) / ($3x - $2x)
    ;If $3x = $2x Then
    ; $m[2] = 1.234e9
    ;Else
    ; $m[2] = ($3y - $2y) / ($3x - $2x)
    ; $b[2] = $2y - $m[2] * $2x
    ;EndIf
    _("@@:") ;lokales label
    _("mov eax,dword[ecx+4*4]") ;3x
    _("cmp eax,dword[ecx+4*2]") ;ist 3x=2x
    _("je @f") ;wenn gleich, dann springe zum nächsten lokalen label
    _("fild dword[ecx+4*5]") ;st0=3y
    _("fisub dword[ecx+4*3]") ;st0=(3y-2y)
    _("fild dword[ecx+4*4]") ;st0=3x st1=(3y-2y)
    _("fisub dword[ecx+4*2]") ;st0=(3x-2x)
    _("fdivp") ;st0=m2
    _("fst dword[_m2]") ;st0=m2
    ;$b2 = $2y - $m2 * $2x
    _("fimul dword[ecx+4*2]") ;st0=m2*2x
    _("fisubr dword[ecx+4*3]") ;st0=2y-m2*2x = b2
    _("fstp dword[_b2]") ;b2 speichern, fpstack clean
    _("")

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

    ;$m1 = ($2y - $1y) / ($2x - $1x)
    _("@@:") ;lokales label
    _("mov eax,dword[ecx+4*2]") ;2x
    _("cmp eax,dword[ecx+4*0]") ;ist 2x=1x
    _("je @f") ;wenn gleich, dann springe zum nächsten lokalen label
    _("fild dword[ecx+4*3]") ;st0=2y
    _("fisub dword[ecx+4*1]") ;st0=(2y-1y)
    _("fild dword[ecx+4*2]") ;st0=2x st1=(2y-1y)
    _("fisub dword[ecx+4*0]") ;st0=(2x-1x)
    _("fdivp") ;st0=m1
    _("fst dword[_m1]") ;st0=m1
    ;$b3 = $1y - $m3 * $1x
    _("fimul dword[ecx+4*0]") ;st0=m1*1x
    _("fisubr dword[ecx+4*1]") ;st0=1y-m1*1x = b1
    _("fstp dword[_b1]") ;b1 speichern, fpstack clean
    _("")

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

    ;$m3 = ($3y - $4y) / ($3x - $4x)
    _("@@:") ;lokales label
    _("mov eax,dword[ecx+4*4]") ;3x
    _("cmp eax,dword[ecx+4*6]") ;ist 3x=4x
    _("je @f") ;wenn gleich, dann springe zum nächsten lokalen label
    _("fild dword[ecx+4*5]") ;st0=3y
    _("fisub dword[ecx+4*7]") ;st0=(3y-4y)
    _("fild dword[ecx+4*4]") ;st0=3x st1=(3y-4y)
    _("fisub dword[ecx+4*6]") ;st0=(3x-4x)
    _("fdivp") ;st0=m4
    _("fst dword[_m3]") ;st0=m4
    ;$b4 = $3y - $m4 * $3x
    _("fimul dword[ecx+4*4]") ;st0=m4*3x
    _("fisubr dword[ecx+4*5]") ;st0=3y-m4*3x = b4
    _("fstp dword[_b3]") ;b4 speichern, fpstack clean
    _("@@:") ;lokales label 108
    _("")

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

    ;minx/maxx und miny/maxy finden

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

    ;~ $indexR = $indexL ;rechte seite nächster punkt
    ;~ $mR = $m[$indexR] ;steigung rechte gerade
    ;~ $bR = $b[$indexR]
    ;~ $indexR += 1 ;gerade zum nächsten Punkt im Uhrzeigersinn
    ;~ If $indexR = 5 Then $indexR = 1

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

    _("mov eax,dword[_indexL]")
    _("mov dword[_indexR],eax")
    _("call _mR_und_bR")

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

    _("")
    _("add eax,1")
    _("cmp eax,5")
    _("cmove eax,dword[_eins]")
    _("mov dword[_indexR],eax") ;$indexR += 1
    _("")
    _("")
    ;$indexL = $indexL - 1 ;linke seite vorheriger punkt
    ;If $indexL = 0 Then $indexL = 4
    ;$mL = $m[$indexL] ;steigung linke gerade
    ;$bl = $b[$indexL]
    _("mov eax,dword[_indexL]")
    _("sub eax,1")
    _("cmp eax,0")
    _("cmove eax,dword[_vier]")
    _("mov dword[_indexL],eax") ;$indexL -= 1
    _("call _mL_und_bL")
    _("")

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

    ;variablen in speicher schreiben
    _("mov eax,_buffer") ; & DllStructGetPtr($struct_float) + 64) ;pointer auf den buffer holen
    _("mov eax,dword[eax]")
    _("mov dword[_buffer],eax")

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

    ;register mit den laufvariablen laden
    _("mov edx,dword[_miny]")
    _("sub edx,1") ;miny-1 ;;for ymin to ymax
    _("mov esi,dword[_orginal]") ; & DllStructGetPtr($struct_float) + 68) ;pointer auf orginal bitmap
    _("mov eax,[_b_buffer]") ; & DllStructGetPtr($struct_float) + 72) ;pointer breite buffer
    _("mov dword[_b_buffer],eax")
    _("mov eax,dword[_b_orginal]") ; & DllStructGetPtr($struct_float) + 76) ;pointer breite orginal
    _("mov dword[_b_orginal],eax")
    _("mov edi,dword[_buffer]");pointer auf den backbuffer
    _("mov ebx,_ptr_var") ; & DllStructGetPtr($struct_float));pointer auf die die 8 variablen

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

    _(".start:") ;hier gehts los
    ;edx = zeilenzähler
    ;ecx = aktuelle position x-koordinate in der zeile
    _(".y_loop:") ;for py=ymin to ymax
    _("add edx,1") ;py, zeilenzähler
    _("mov dword[_py],edx")

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

    _("cmp edx,dword[_maxy]") ;wenn letzte Zeile erreicht, ende
    _("ja .ende") ; 133
    ;schnittpunkt der aktuellen zeile mit der geraden zwischen 2 punkten bestimmen
    ;ergibt die rechte und die linke x-koordinate in der zeile, in der die transformierten Pixel sind

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

    ; If $py = $sy[$indexL] Then ;nächsten punkt links gefunden
    ; If $sy[$indexL] <> $maxy Then ;nur, wenn nächster schnittpunkt nicht der unterste ist..
    ; $indexL = $indexL - 1 ;linke seite
    ; If $indexL = 0 Then $indexL = 4
    ; ; msgbox(0,$indexL&" sy="&$sy[$indexL]&" ymax="&$maxy,"linke seite nächsten punkt gefunden")
    ; $mL = $m[$indexL] ;steigung linke gerade
    ; $bl = $b[$indexL]
    ; EndIf
    ; EndIf
    _("mov eax,dword[_indexL]") ;
    _("lea ebx,[_ptr_posxy+8*(eax-1)+4]");ebx =adresse y-koordinate des linken eckpunktes
    _("mov ebx,dword[ebx]") ;wert y-koordinate
    _("cmp ebx,dword[_py]") ;vgl y-koordinate des nächsten punktes mit aktueller y-koordinate sy[indexR]
    _("jne .xLxR_berechnen") ;wenn nicht, x-koordinaten berechnen
    _("cmp ebx,dword[_maxy]") ;nur, wenn nächster schnittpunkt nicht der unterste ist..
    _("je .xLxR_berechnen") ;wenn nächster schnittpunkt der unterste ist, dann sind wir im letzten feld
    _("sub eax,1") ;indexL -= 1
    _("cmovz eax,dword[_vier]");If $indexL = 0 Then $indexL = 4
    _("mov dword[_indexL],eax");indexL speichern
    _("call _mL_und_bL") ;mL und bL berechnen
    _(".xLxR_berechnen:") ;linke und rechte x-koordinate berechnen _xL und _xR

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

    ;***********************************************************************************************************************
    ;If $mL = 1.234e9 Or $mL = 0 Then
    ; $xL = $sx[$indexL]
    ;Else
    ; $xL = Int(($py - $bl) / $mL) ;von linker grenze
    ;EndIf
    _("cmp dword[_mL],12345678"); steigung unendlich?
    _("je @f") ;ja, dann nächstes label
    _("cmp dword[_mL],0") ;steigung 0? ;150
    _("je @f") ;ja, dann nächstes label
    _("jmp .getXL")
    _("@@:") ;$xL = $sx[$indexL]
    ; _("mov eax,dword[_indexL]"); UNNÖTIG, falls eax = indexL
    _("lea ebx,[_ptr_posxy+8*(eax-1)]");ebx =adresse x-koordinate des linken eckpunktes
    _("mov ebx,dword[ebx]") ;x-koordinate
    _("mov dword[_xL],ebx") ;speichern

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

    _("jmp .xR_berechnen") ;_xR berechnen
    _(".getXL:") ;$xL = Int(($py - $bL) / $mL) ;von linker grenze
    _("fild dword[_py]")
    _("fsub dword[_bL]")
    _("fdiv dword[_mL]")
    _("fistp dword[_xL]")
    _("")
    _(".xR_berechnen:") ;164

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

    ;If $mR = 1.234e9 Or $mR = 0 Then ;falls steigung 0 oder unendlich
    ; $xR = $sx[$indexR]
    ;Else
    ; $xR = Int(($py - $bR) / $mR);...bis zur rechten
    ;EndIf
    _("cmp dword[_mR],12345678"); steigung unendlich?
    _("je @f") ;ja, dann nächstes label
    _("cmp dword[_mR],0") ;steigung 0?
    _("je @f") ;ja, dann nächstes label
    _("jmp .getXR")
    _("@@:") ;$xR = $sx[$indexR]
    _("mov eax,dword[_indexR]");
    ;_("mov ebx,_ptr_posxy") ; & DllStructGetPtr($struct_float) + 32);pointer auf koordinaten
    _("lea ebx,[_ptr_posxy+8*(eax-1)]");ebx =adresse x-koordinate des linken eckpunktes
    _("mov ebx,dword[ebx]") ;x-koordinate
    _("mov dword[_xR],ebx") ;speichern
    _("jmp .xL_to_xR_loop") ;
    _(".getXR:") ;$xR = Int(($py - $bR) / $mR);...bis zur rechten
    _("fild dword[_py]")
    _("fsub dword[_bR]")
    _("fdiv dword[_mR]")
    _("fistp dword[_xR]")
    _("")
    ;****************************************************schleife xL to xR************
    _(".xL_to_xR_loop:") ;for $x = xL to $xR
    _("mov ecx,dword[_xL]") ;linke seite 184
    _("mov ebx,_ptr_var") ; & DllStructGetPtr($struct_float));pointer auf die a()-variablen
    _("mov dword[_py],edx")

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

    _(".x_loop:")
    _("add ecx,1") ;px
    _("cmp ecx,dword[_xR]") ;ist xR rechter Rand erreicht?
    _("ja .nextline") ;ja, dann nextline (ggf xR + xL anpassen)

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

    ;***************************

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

    _("mov dword[_px],ecx") ;abspeichern
    _("")
    _("fild dword[_py]") ;st0=py
    _("fild dword[_px]") ;st0=px st1=py

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

    ;x=int($s[0] * $px + $s[1] * $py + $s[2]) / ($s[6] * $px + $s[7] * $py + 1) bissl floatingpoint
    _("fld dword[ebx+4*0]") ;st0=s[0] st1=px st2=py
    _("fmul st0,st1") ;st0=s[0]*px
    _("fld dword[ebx+4*1]") ;st0=s[1] st1=s[0]*px st2=px st3=py
    _("fmul st0,st3") ;st0=s[1]*py st1=s[0]*px st2=px st3=py
    _("faddp") ;st0=s[1]*py+s[0]*px st1=px st2=py
    _("fadd dword[ebx+4*2]") ;st0=s[1]*py+s[0]*px+s[2] st1=px st2=py
    _("fld dword[ebx+4*6]") ;st0=$s[6] st1=s[1]*py+s[0]*px+s[2] st2=px st3=py
    _("fmul st0,st2") ;st0=$s[6]*px st1=s[1]*py+s[0]*px+s[2] st2=px st3=py
    _("fld dword[ebx+4*7]") ;st0=s[7] st1=$s[6]*px st2=s[1]*py+s[0]*px+s[2] st3=px st4=py
    _("fmul st0,st4") ;st0=s[7]* py st1=$s[6]*px st2=s[1]*py+s[0]*px+s[2] st3=px st4=py
    _("faddp ") ;st0=s[7]*py+$s[6]*px st1=s[1]*py+s[0]*px+s[2] st1=px st2=py
    _("fld1")
    _("faddp ") ;st0=s[1]*py+s[0]*px+s[2] st1=s[7]*py+$s[6]*px+1 st2=px st3=py
    _("fxch st1") ;
    _("fdiv st0,st1") ;st0=st0/st1 st1=s[7]*py+$s[6]*px+1 st2=px st3=py
    _("fistp dword[_x]") ;abspeichern als integer st0=px st1=py
    _("")
    ;$Y = Int(($s[3] * $px + $s[4] * $py + $s[5]) / ($s[6] * $px + $s[7] * $py + 1))
    _("fld dword[ebx+4*3]") ;st0=s[3] st1=s[7]*py+$s[6]*px+1 st2=px st3=py
    _("fmul st0,st2") ;st0=s[3]*px
    _("fld dword[ebx+4*4]") ;st0=s[4] st1=s[3]*px st2=s[7]*py+$s[6]*px+1 st3=px st4=py
    _("fmul st0,st4") ;st0=s[4]*py st1=s[3]*px st2=s[7]*py+$s[6]*px+1 st3=px st4=py
    _("faddp") ;st0=s[4]*py+s[3]*px st1=s[7]*py+$s[6]*px+1 st2=px st3=py
    _("fadd dword[ebx+4*5]") ;st0=s[4]*py+s[3]*px+s[5] st1=s[7]*py+$s[6]*px+1 st2=px st3=py
    _("fdivrp st1,st0") ;st0=y st1=px st2=py
    _("fistp dword[_y]") ;abspeichern als integer st0=px st1=py 111
    _("FUCOMPP") ;pop, pop => stack clean!

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

    ;~ _("mov eax,dword[_y]")
    ;~ _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    ;~ _("jnz .x_loop") ;wenn negativ, jump 162

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

    ;~ _("mov eax,dword[_x]")
    ;~ _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    ;~ _("jnz .x_loop") ;wenn negativ, jump

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

    ;$col = DllStructGetData($struct, 1, ($Y+1) * $b + $X) ;farbe aus bild holen
    _("mov eax,dword[_b_orginal]")
    _("push edx") ;sichern, mul zerstört edx
    _("mov edx,dword[_y]") ;eax=$b*y
    _("sub edx,1") ;eax=$b*y
    _("mul edx") ;eax=$b*y
    _("add eax,dword[_x]") ;eax=$b*y+x
    _("sub eax,1")
    _("pop edx") ;

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

    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz .x_loop") ;wenn negativ, jump

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

    _("cmp eax,dword[_size_orginal]") ;addresse grösser als bitmap?
    _("ja .x_loop")

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

    _("shl eax,2") ;4 byte = 1 pixel! daher anzahl der byte vervierfachen
    _("mov eax,dword[esi+eax]") ;pixelfarbe holen aus ursprungsbitmap
    _("push eax") ;pixelfarbe sichern

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

    ;DllStructSetData($struct_buffer, 1, $col, $py * $b_buffer + $px+1)
    _("mov eax,dword[_py]")
    _("push edx") ;sichern
    _("mul dword[_b_buffer]") ;mal breite
    _("pop edx") ;sichern
    _("add eax,dword[_px]") ;eax=$py * $b_buffer + $px +1
    _("add eax,1")
    ;~ _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    ;~ _("jnz .popeax")

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

    _("mov edi,dword[_buffer]");pointer auf den backbuffer
    _("shl eax,2") ;4 byte = 1 pixel! daher anzahl der byte vervierfachen
    _("add edi,eax") ;edi=adresse pixel im buffer
    _("pop eax") ;farbe holen
    _("mov [edi],eax") ;pixel in buffer schreiben
    _("jmp .x_loop") ;next x

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

    _(".nextline:")
    ;If $xR = $sx[$indexR] And $sy[$indexR] = $py Then ;auf rechter Seite nächsten Schnittpunkt gefunden
    ; msgbox(0,$indexR,"schnittpunkt gefunden")
    ; If $sy[$indexR] <> $maxy Then ;nur, wenn nächster schnittpunkt nicht der unterste ist..
    ; $mR = $m[$indexR] ;steigung rechte gerade
    ; $bR = $b[$indexR]
    ; $indexR += 1 ;gerade zum nächsten Punkt im Uhrzeigersinn
    ; If $indexR = 5 Then $indexR = 1
    ; msgbox(0,$indexR,"nächster schnittpunkt ist "&$indexR)
    ;EndIf
    ;EndIf
    _("mov eax,dword[_indexR]") ;
    _("mov ebx,_ptr_posxy") ; & DllStructGetPtr($struct_float) + 32);pointer auf koordinaten
    _("lea ebx,[ebx+8*(eax-1)]");ebx =adresse x-koordinate des linken eckpunktes
    _("mov ebx,dword[ebx]") ;wert x-koordinate

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

    _("cmp ebx,dword[_xR]") ;vgl x-koordinate aktueller x-koordinate sx[indexR]
    _("jne .y_loop") ;wenn nicht, nächste zeile
    _("mov ebx,_ptr_posxy") ; & DllStructGetPtr($struct_float) + 32);pointer auf koordinaten
    _("lea ebx,[ebx+8*(eax-1)+4]");ebx =adresse y-koordinate sy[indexR]
    _("mov ebx,dword[ebx]") ;wert y-koordinate
    _("cmp ebx,dword[_py]") ;vgl y-koordinate aktueller y-koordinate sy[indexR]
    _("jne .y_loop") ;wenn nicht, nächste zeile

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

    _("cmp ebx,dword[_maxy]") ;nur, wenn nächster schnittpunkt nicht der unterste ist..
    _("je .y_loop") ;wenn nächster schnittpunkt der unterste ist, dann sind wir im letzten feld
    ;rechten schnittpunkt gefunden
    _("call _mR_und_bR") ;mL und bL berechnen
    _("mov eax,dword[_indexR]") ;
    _("add eax,1") ;indexR += 1
    _("cmp eax,5") ;GGF RAUSWERFEN; DA UNNÖTIG!!!!!!!
    _("cmovz eax,dword[_eins]");If $indexR = 5 Then $indexR = 1
    _("mov dword[_indexR],eax");indexR speichern
    _("jmp .y_loop") ;next y

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

    _("")
    _(".ende:")
    _("ret")

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

    ;~ _("")
    ;~ _(".popeax:")
    ;~ _("pop eax")
    ;~ _("mov eax,1010101010")
    ;~ _("ret")
    ;~ _("jmp .x_loop")

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

    ;****************************************************funktionen**********
    _("_mL_und_bL:") ;eax muss _indexL sein
    _("lea ebx,[_m1+4*(eax-1)]")
    _("mov ebx,[ebx]")
    _("mov [_mL],ebx") ; $mL = $m[$indexL]
    _("lea ebx,[_b1+4*(eax-1)]");adresse _bx ausrechnen
    _("mov ebx,[ebx]")
    _("mov [_bL],ebx") ; $bL = $b[$indexL]
    _("ret ")

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

    _("_mR_und_bR:") ;eax muss indexR sein
    _("lea ebx,[_m1+4*(eax-1)]")
    _("mov ebx,[ebx]")
    _("mov [_mR],ebx") ; $mR = $m[$indexR]
    _("lea ebx,[_b1+4*(eax-1)]")
    _("mov ebx,[ebx]")
    _("mov [_bR],ebx") ; $bR = $b[$indexR]
    _("ret")
    _("")

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

    EndFunc ;==>_quadrilateral

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

    ;GDI+ wird nur verwendet, um andere Dateien als das BMP-Format zu laden
    Func getDCfromfile($bmpfile, ByRef $ptr) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($bmpfile)
    Local $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    $iwidth = _GDIPlus_ImageGetWidth($hBitmap)
    $iheight = _GDIPlus_ImageGetHeight($hBitmap)

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

    Local $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -$iheight)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32)
    Local $hdc = _WinAPI_GetDC(0)
    Local $hcdc = _WinAPI_CreateCompatibleDC($hdc)
    Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'ptr', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 1, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    ; select object
    _WinAPI_SelectObject($hcdc, $adib[0])
    ; copy the content of the bitmap into the buffer ...
    _WinAPI_GetDIBits($hdc, $hbmp, 0, $iheight, $adib[4], DllStructGetPtr($tBMI), 1)
    ; create the a dllstruct with the pointer $aDIB[4]
    Local $stride = 3 * $iwidth + Mod($iwidth, 4) ;number of bytes in one line (filled with some bytes, because it must be a multiple of four!)
    $tbits = DllStructCreate('byte[' & $stride * $iheight & ']', $adib[4])
    $ptr = DllStructGetPtr($tbits)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($adib[0])
    Return $hcdc ;MemoryDC of bitmap
    EndFunc ;==>getDCfromfile

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

    Func _solve_linear_quad($a, $b) ;matrix,lösung Gaußsches Eliminationsverfahren, löst x gleichungen mit x unbekannten
    ;by Andy
    Local $n, $t
    Dim $Y[UBound($b)] ;ergebnisse
    $n = UBound($a) - 1 ;anzahl der zeilen/spalten
    ;falls erforderlich, zeilen und spalten tauschen
    If $a[0][0] = 0 Then ;wenn erster koeffizient = 0, dann kann das system nicht starten => spalten tauschen ggf zeilen tauschen
    For $k = 0 To $n ;jede zeile
    For $j = 0 To $n ;alle spalten in dieser Zeile testen
    If $a[$k][$j] <> 0 Then
    For $m = 0 To $n ;treffer, die erste spalte mit der j. tauschen
    $t = $a[$m][$j] ;sichern
    $a[$m][$j] = $a[$m][0] ;mit erster spalte tauschen
    $a[$m][0] = $t
    Next
    For $j = 0 To $n ;zeilen tauschen
    $t = $a[0][$j] ;sichern
    $a[0][$j] = $a[$k][$j] ;mit erster spalte tauschen
    $a[$k][$j] = $t
    Next
    $t = $b[0] ;ergebnisse auch tauschen
    $b[0] = $b[$k]
    $b[$k] = $t
    ExitLoop 2
    EndIf
    Next
    Next
    EndIf

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

    If $a[0][0] = 0 Then Return SetError(1, 0, 1)

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

    ;endlich rechnen :)
    For $I = 0 To $n ;alle zeilen
    If $a[$I][$I] <> 0 Then
    ;erstes element auf 1 bringen indem man gesamte zeile durch erstes Element teilt
    For $k = $I To $n
    $t = $a[$k][$I] ;erstes element merken
    If $t <> 0 Then ;nur, wenn das erste element ungleich null ist...
    For $j = $I To $n
    $a[$k][$j] /= $t ;alle zeilenmitglieder durch erstes element teilen
    Next
    ;b durch i teilen
    $b[$k] /= $t ;ergebnis natürlich auch
    EndIf
    Next
    ; _ArrayDisplay($a, "oben " & $I)
    ;zeile i von allen weiteren zeilen subtrahieren, erstes element wird zu 0
    For $k = $I + 1 To $n
    If $a[$k][$I] <> 0 Then ;wenn null, dann überspringen
    For $j = $I To $n
    $a[$k][$j] -= $a[$I][$j] ;die i.zeile von der aktuellen zeile subtrahieren
    Next
    $b[$k] -= $b[$I] ;ergebnisse natürlich auch
    EndIf
    Next
    ; _ArrayDisplay($a, "unten " & $I)
    Else ;null in aktueller spalte
    ;zeilen tauschen
    ; msgbox(0,$i,"null gefunden")
    For $k = $I + 1 To $n
    If $a[$k][$I] <> 0 Then ;zeile tauschen
    For $j = $I To $n ;zeilen tauschen
    $t = $a[$I][$j] ;sichern
    $a[$I][$j] = $a[$k][$j] ;mit erster spalte tauschen
    $a[$k][$j] = $t
    Next
    $t = $b[$I] ;ergebnisse auch tauschen
    $b[$I] = $b[$k]
    $b[$k] = $t
    EndIf
    ;erstes element auf 1 bringen indem man gesamte zeile durch erstes Element teilt
    For $k = $I To $n
    $t = $a[$k][$I] ;erstes element merken
    If $t <> 0 Then ;nur, wenn das erste element ungleich null ist...
    For $j = $I To $n
    $a[$k][$j] /= $t ;alle zeilenmitglieder durch erstes element teilen
    Next
    ;b durch i teilen
    $b[$k] /= $t ;ergebnis natürlich auch
    EndIf
    Next
    ; _ArrayDisplay($a, "oben1 " & $I)
    ;zeile i von allen weiteren zeilen subtrahieren, erstes element wird zu 0
    For $k = $I + 1 To $n
    If $a[$k][$I] <> 0 Then ;wenn null, dann überspringen
    For $j = $I To $n
    $a[$k][$j] -= $a[$I][$j] ;die i.zeile von der aktuellen zeile subtrahieren
    Next
    $b[$k] -= $b[$I] ;ergebnisse natürlich auch
    EndIf
    Next
    ;_ArrayDisplay($a, "unten1 " & $I)

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

    Next
    EndIf
    Next

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

    ;alle parameter bestimmen durch rückwärtseinsetzen

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

    $Y[$n] = $b[$n] ;letzter ist bereits bekannt
    For $I = $n - 1 To 0 Step -1
    For $j = $n To $I + 1 Step -1
    $b[$I] -= $a[$I][$j] * $Y[$j]
    Next
    $Y[$I] = $b[$I]
    Next
    Return $Y
    EndFunc ;==>_solve_linear_quad
    Exit

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

    Func _ReDraw($fPrecision)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
    _projective_mapping($hBmpBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1])
    ;_GDIPlus_GraphicsDrawImage_4Points($hGfxBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1], $fPrecision)
    For $I = 1 To 4
    _GDIPlus_GraphicsFillRect($hGfxBuffer, $aDrag[$I][0] - 5, $aDrag[$I][1] - 5, 10, 10, $hBrush)
    _GDIPlus_GraphicsDrawRect($hGfxBuffer, $aDrag[$I][0] - 5, $aDrag[$I][1] - 5, 10, 10, $hPen)
    Next
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    ; MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$hGraphics' & @lf & @lf & 'Return:' & @lf & $hGraphics) ;### Debug MSGBOX

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

    EndFunc ;==>_ReDraw

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

    Func _Slider()
    GUICtrlSetData($cLabel, GUICtrlRead($cSlider) / 100)
    EndFunc ;==>_Slider

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

    Func _Render()
    Local $fPrecision = GUICtrlRead($cSlider) / 100
    SplashTextOn("Rendering with precision " & $fPrecision, "please wait", 250, 50)
    _ReDraw($fPrecision)
    SplashOff()
    EndFunc ;==>_Render

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

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    Func _Exit()
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Die AutoIt-Variante ist auskommentiert.

    Verfahren:
    Eckpunkte einlesen und zwischen den benachbarten Eckpunkten eine Geradengleichung y=mx+b erstellen. Das führt zu den Steigungen "_m" und den y-Achsenabschnitten "_b"
    Kleinster y(x)-Wert und grösster y(x)-Wert aus den Eckpunkten berechnen.
    Den "höchsten" Eckpunkt (kleinstes y(x) ) herausfinden.
    Nun hab ich mir was einfallen lassen^^
    Ich habe 2 Indizes erstellt, R und L (rechts und links), und den Geradengleichungen zugeordnet, einmal "linksrum" bis zur Koordinate mit dem grössten y-Wert, und einmal "rechtsrum"
    Somit brauchte ich nur, wenn die nächste Zeile (y) zu bestimmen war, den x-Wert der beiden Geradengleichungen aus dem (bekannten) y zu bestimmen, das führte zu xL und xR. Alle Punkte zwischen xL und xR sind immer innerhalb des Trapezoids! Somit entfällt die Abfrage, ob ein Punkt innerhalb des Vierecks ist, völlig!
    Die x-Koordinaten zwischen xL und xR werden mithilfe der Formel ausgerechnet und die entsprechende Pixelfarbe aus der Orginalbitmap gezogen.

    Wer eine Zeichnung braucht um das zu kapieren, soll sich melden^^

    Die "Zeile" der x-Koordinaten bietet sich natürlich für SSE2 (128 Bit berechnung) an, damit könnte man 4 Pixel auf einen Schlag berechnen, zzt mach ich das schön "langsam" nach der Reihe :D
    Schaumamal, was da noch geht...
    Bei den derzeitigen Grössen der Bitmap (s. Beispiel) ist bei mir die komplette Berechnung per ASM in ca 10ms erledigt, plus das locken (das dauert irre lange imho) der Bitmap und dem Gleichungslöser (3ms)

  • Happy Birthday BugFix!

    • Andy
    • 4. Dezember 2010 um 09:46

    Uhhhhhhh....da hab ich doch tatsächlich den Geburtstag vom "King" versaubeutelt...
    Alles Liebe und Gute und vieeeel Gesundheit weiterhin verbunden mit den glücklichsten Herzwünschen zum Geburtstag nachträglich!

    Zitat

    und dann hab ich die Bande gleich wieder 'entsorgt'

    hehe, "Verwandschaft ist wie die Alpen, je weiter sie weg sind, desto schöner werden sie!" 8o

  • Happy Birthday Pee und Funkey

    • Andy
    • 4. Dezember 2010 um 09:40

    Beiden auch von mir einen glücklichen Herzwunsch zum Geburtstag!
    Feiert schön!

  • Stuttgart 21

    • Andy
    • 3. Dezember 2010 um 11:53

    Oscar
    ich gebe dir in der Sache Recht, aber Matthias´ "Aussage" kann ich (und viele meiner Freunde aus dem Ausland) nachvollziehen!
    In Frankreich würde kein Mensch auf die Strasse gehen für S21, DORT (und in anderen Ländern auch) wird für WICHTIGE Sachen auf die Strasse gegangen! Wichtig im Sinne von wichtig für die Gemeinschaft! Kein Schwein protestiert hierzulande gegen höhere Steuern, immer niedrigere Renten, hohe Spritkosten oder andere Sachen, die ALLE betreffen. Aber wenn es irgendwo darum geht sich um pillepalle aufzuregen, finden sich hierzulande immer einige Demonstrierer...
    Genau aus diesem Grund haben hierzulande auch die Damen und Herren Politiker nichts zu befürchten, denn Gegenwind aus großen Teilen der Bevölkerung ist absolut in keinster Weise zu erwarten! Bei einer Staatsverschuldung von ca 50% vom Nettoinlandsprodukt und einer jährlichen 16%igen Zinslast aus 1 Billion Euro wird sich um "Pillepalle" von 2-3 Milliarden Mehrkosten für einen Bahnhof aufgeregt....Hurra Deutschland!

    Noch zu erwähnen ist, ich habe neulich an einer Vorlesung einer Rechtsanwältin teilgenommen, die 2002 an der Einladung der Beteiligten/Betroffenen (u.a. auch aller Parteien) zu einem Symposium mit Thema S21 beteiligt war. Sämtliche Pläne usw waren dort zur Einsicht offen im Rahmen des Planfeststellungesverfahrens.
    14 Tage lang war eine Halle gemietet und gekommen ist ....niemand! Die Einladungen wurden an mehrere hundert Personen/Gesellschaften persönlich verschickt, in der Tagespresse gab es mehrere Artikel um die Bevölkerung zu informieren. Einige derer, die heute das Maul extrem aufreissen, hatten es 2002 nichtmal nötig, die persönliche Einladung mit einem 3-Zeiler ABZUSAGEN. Mal ehrlich, soll man solche "Aktivisten" ernst nehmen?

  • ini zu langsam, Alternative zu ini

    • Andy
    • 3. Dezember 2010 um 11:07
    Zitat

    Bei 100 Datensätzen dauerte es mit listview 1,2 seks ohne etwa 0,4 seks.

    Mach dir mal Gedanken über ein "passendes" Dateiformat. Eine mehrere MB große Datei ist in Mikrosekunden in den Speicher zu laden. Um 1000 Datensätze in ein Array zu packen braucht AutoIt auch nur einige Millisekunden.
    Alternativ könntest du, wenns wirklich auf Geschwindigkeit ankommt, den Dateiinhalt in eine Struct schreiben und hast somit 2 Fliegen mit einer Klappe geschlagen.
    Da dllstructgetdata() genauso schnell ist wie der Zugriff auf ein Array, ist der gesamte Aufwand (Daten schreiben in Array) eingespart.

    Zitat

    wenn du mal ein Testset bauen/beschreiben könntest, dann könnte man einen kleinen Contest machen, wie es schnell geht :)

    DAFÜR! :thumbup:

    /EDIT/ Das Listview ist leider der Flaschenhals, hab da schon einiges versucht um Geschwindigkeit rauszuholen (auch in Assembler), leider erfolglos, da die Windowsfunktionen (API) sehr aufwendig sind.

  • ini zu langsam, Alternative zu ini

    • Andy
    • 2. Dezember 2010 um 17:42

    Hi,
    Sinn und Zweck einer INI ist das INI-tialisieren von Daten beim Programmstart. Eine INI ist nicht primär dazu gemacht, als Datenbank zu fungieren. Wobei ich mich aber wundere, da der Inhalt einer kürzlich gelesenen Datei eigentlich im Cache steht und von dort aus extrem fix gelesen wird...
    Ausser du schreibst einen Wert und damit den kompletten Datei-Inhalt bei jedem Schreibvorgang auf die Platte, aber wer macht sowas?

    Verfahren:
    Dateiinhalt der INI beim Programmstart in den Speicher lesen, Daten im Speicher bearbeiten (Schreiben/Lesen) und dann die Daten beim Beenden des Programms wieder in die INI-Datei schreiben. So wirds gemacht, und das ist superschnell, da völlig unabhängig vom Datenformat der Datei....

  • Umfrage für CPU-Kauf

    • Andy
    • 2. Dezember 2010 um 09:32
    Zitat

    aber ist es nicht so dass mit so einem Prozessor für zukünftige Programme vorsorgt ?

    naja, die "erweiterten" Prozessorbefehle (SSE,MMX) gibt es seit dem ersten Pentium-Prozessor. Alles andere ist Uralt-Technik aus den 80er Jahren und seitdem unverändert! 99,9% aller Programme heutzutage nutzen das Potential der aktuellen Prozessoren NICHT! Und daran wird sich auch in Zukunft nicht viel ändern....
    Frag mal gestandene C++-Programmierer, wieso sie ausschliesslich mit den "Standard"-80386-Bibliotheken arbeiten und nicht mit den schon seit 10 Jahren von den Compilerherstellern bereitgestellten "optimierten" (SSE/MMX) Bibliotheken. Da wird von den Prozessorherstellern mit den allerfeinst (hand)optimierten Programmen gebenchmarkt, nur damit der Käufer nachher nur 20% dieser Leistung mit den "Standard"-Programmen nutzt.

    Red Hat hat in der letzten Woche einen Linuxkernel angekündigt, der (oh Wunder) eine "optimierte" Grafik-Lib verwendet, welche die Dekodierung z.B. eines JPG in der Hälfte der Zeit durchführt. Diese Lib gibts seit 2002....
    Soviel zum Thema Hardware als "Vorsorge für zukünftige Programme"...

    Mein Tip, Preislimit setzen, wenn primär gespielt werden soll, lieber Geld in die Graka als in den Prozessor stecken (ein 2.3 GHZ-Dualcore reicht dann locker aus) und beim selbstprogrammieren Bibliotheken verwenden, welche die aktuellen Prozessorfeatures auch ausnutzen. Dann reicht idR auch ein "antiker" Prozessor aus, um aktuelle Programmtechnische Probleme superschnell zu lösen.

  • leeren speicherlatz überschreiben

    • Andy
    • 30. November 2010 um 12:10

    Hi,
    die hier vorgestellten Methode (Dateien auf die Platte schreiben und danach löschen) funktioniert so nur bei einer komplett LEEREN Platte! Wieso?
    Windows schreibt Daten in Cluster und markiert diese, egal wie "voll" diese Cluster sind, als belegt. Beispiel:
    Clustergrösse 512 Byte, wird beschrieben mit 512 großen "A"´s, also AAAAAAAAAAAAAAAAAAAAAAAAAAA......
    Wenn man diese Datei nun "löscht", wird nur der Eintrag aus der Dateizuordnungstabelle gelöscht, die Daten bleiben auf der Platte erhalten!
    Speichert man nun eine "kleine" Datei, dann werden diese Daten an den Anfang des Clusters geschrieben. Bsptext: "Hallo, das ist ein Test!!"
    Im Cluster sieht es nun so aus:
    Hallo, das ist ein Test!!AAAAAAAAAAAAAAAAAAAAAAAAAAA.....
    D.h. "hinter" sämtlichen Datenfragmenten kann man ohne weiteres Teile der vorher gespeicherten Daten ermitteln! Da Windows permanent auf der Platte "rumrödelt" und Cluster beschreibt, ist keinesfalls sichergestellt, dass beim Schreiben der Cluster beschrieben wird, der gerade vorher gelöscht wurde!

    Abhilfe:
    Cluster lesen, Nutzdaten extrahieren (Infos aus der FAT), Cluster mit z.B. "FU!"´s vollfüllen, Nutzdaten dann wieder in den Cluster schreiben. Das geht auch mit AutoIt, jedenfalls unter XP.

    Wenn man nun also bei einer länger benutzten gefüllten Platte "einfach" nur die Platte mit einer Datei vollschreibt und danach wieder löscht, werden NUR die vorher dort belegten Cluster überschrieben. Sämtliche Daten, die in den belegten Clustern "hinter" den Nutzdaten liegen, sind davon unbeeindruckt! Ich würde dieses "Risiko" jedenfalls nicht eingehen! Dafür ist mir die Datei-Lese/Schreib-Philosophie von Windows zu suspekt. Platte komplett neu aufsetzen (partitionieren und richtig formatieren, alle Daten futsch!) und danach mit einem auch von den Forensikern als "sicher" geltenden Tools bearbeiten ist da die einzige Abhilfe!


    /EDIT/ DAS HIER ff. bietet noch etwas zum Thema, u.a. auch Scriptbeispiele

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 29. November 2010 um 09:29

    Zwischenbericht:
    Bekannte Grafikbugs sind entfernt (kamen vom Gleichungslöser), ein bissl hänge ich in den Seilen mit 2 Punkten:

    Erstens, bei extrem verzerrten Vierecken wird aufgrund von Rundungsfehlern (hab schon 80 Bit Genauigkeit) durch Multiplikation von sehr großen mit sehr kleinen Zahlen die "letzte Pixelreihe" nicht exakt berechnet. Man sieht das, wenn man das Viereck so verzerrt, dass nur noch die letzten 5-6 Pixelreihen "im Vordergrund" sichtbar sind (dementsprechend vergrössert). Aber ich denke, damit kann man leben! Die unterste Pixelreihe ist dann nur noch halb so hoch....

    Zweitens, ich habe einige Versuche gemacht um eine schnelle Methode zu finden um festzustellen, ob sich ein Punkt in dem transformierten Viereck/Dreieck befindet. Das ist relativ aufwendig, zzt. bin ich dabei, mich zeilenweise "innerhalb" des transformierten Vierecks (begrenzt durch 4 Geraden y=mx+b) zu bewegen. Das scheint besser zu sein. Weiterhin hab ich den Assemblerteil schon teilweise von Floatingpoint-Berechnung auf Integer umgestellt, das fetzt speedmässig richtig! Jetzt ist sogar reichlich Zeit für Firlefanz wie z.B. bilineare Filter!

    Ziel ist, ein Video in Echtzeit zu "transformieren". Dann mache ich aber den Gleichungslöser auch komplett in Assembler, das ist nur Fleissarbeit...
    6 Videos auf UEZ´s rotierendem Würfel, muhaaaaa^^
    Ich bitte daher um bissl Geduld, habe zzt. mehrere Baustellen, aber vor Weihnachten wird das sicher was....
    Überlegt euch mal eine 3D-Anwendung z.b. Darstellung von Texturen auf einem Mesh. :rolleyes:

    Bin grade nicht zuhause, aber in den nächsten Tagen stelle ich die neue Version (ohne Fasm) schon mal online....

  • problem bei vergleich mit if then

    • Andy
    • 28. November 2010 um 10:15
    Zitat

    ich habe hier 2stunden gesucht


    schau mal in den Beitrag, der in meiner Signatur verlinkt ist :rolleyes:

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 27. November 2010 um 21:51

    hmm, ich hab mal zum testen ein Rechteck gebastelt und dieses dann auf
    Global $aDrag[5][2] = [[0, 0],[10, 30],[700, 30],[700, 500],[10, 500]]
    gelegt. Und auch nicht mit dem Assemblercode gerechnet, nur mit dem AutoItcode.
    Also ein Rechteck(Ursprung) auf ein Rechteck(Transformation). Das seltsame ist dabei, die Transformation ist schief! Eine Ecke verschieben (einige Pixel weiter, also kein Rechteck als Ziel) und es ist "richtig"....
    /EDIT/ Bitmap gelöscht
    Ich habe festgestellt, dass bei bestimmten Koordinaten die Transformationsvariablen (die 8 Unbekannten) "seltsame" Werte annehmen. Ich habe den Gleichungslöser im Verdacht.... :huh:

    /EDIT/ ja, genau, der Gleichungslöser wars! Der hatte alle Grafikbugs zu verantworten....

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 27. November 2010 um 19:57
    [autoit]

    $u = 1 ;koordinaten oben rechts im $image
    $v = 1

    [/autoit]

    in Zeile 87/88 ändern, beseitigt das "überlappen"

    /EDIT/ muss asmcode bissl ändern

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 27. November 2010 um 19:50
    Zitat

    Wie ist es, wenn du $GDIP_ILMUSERINPUTBUF bei BitLock benutzt?

    hab schon einiges getestet, scheinbar wird jeder GDI-Funktion im System mitgeteilt, dass ab nun bestimmte Bytes im Speicher gelockt sind ^^ ....und das dauert ;)

    Zitat

    2 Bugs sind mir aufgefallen:
    1) konnte ich leider nicht mehr reproduzieren,

    yepp, hatte ich auch, als ich das Script das erste mal auf einem Rechner gestartet hatte...aber nur beim ersten Mal....

    Zitat

    ps.: Du includest in deinen ASM-Scripts immer die Datei GDIConstants.au3, welche aber standartmässig nicht bei AutoIt dabei ist.

    uups, ich drücke F2 für OrganizeIncludes, hab nie geguckt, was der da einbindet!
    Kann auch sein, dass ich nicht die allerneueste Version der GDI+-Includefiles habe....

  • problem bei vergleich mit if then

    • Andy
    • 27. November 2010 um 19:42

    Hallo!
    Du hast die Datentypen bei deinem Vergleich nicht beachtet. Zzt vergleichst du STRING mit NUMBER...
    Um das anzupassen, d.h 2 Zahlen miteinander zu vergleichen, ändere Zeile 110 in

    [autoit]

    $ergebnis1= number(StringReplace ( $ergebnis, "|", " " ))

    [/autoit]
  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 27. November 2010 um 19:15

    sodele, erste lauffähige ASM-Version, unoptimiert! Gebraucht werden zzt. noch die FASM.au3 und AssembleIt.au3.

    Ich hab die Schnittstelle zu GDI jetzt so gelöst wie bereits beschrieben, ziemlich "sauber".
    d.h. ihr könnt einfach eukalyptus´Funktion
    _GDIPlus_GraphicsDrawImage_4Points($hGfxBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1], $fPrecision)
    mit
    _projective_mapping($hBmpBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1])
    ersetzen! Wenn DAS nicht fein ist :D

    Was mich ehrlich gesagt bissl aufregt, ist die Schwierigkeit, an einen Pointer zu den Pixeln einer HBITMAP zu kommen.
    In GDI+ gibts da mehrere Möglichkeiten, alle bis auf _GDIPlus_BitmapLockBits legen Kopien der Bitmp an.
    Ich weiss nicht was _GDIPlus_BitmapLockBits grossartig macht, aber es ist alles andere als performant! Habs interessehalber mal durchgespielt, bei grossen Bitmaps dauert es die Hälfte der Zeit zu locken(+unlocken), die andere Hälfte geht für den gesamten restlichen AutoIt-Code drauf! Inclusive der Berechnung der 8 Unbekannten + sämtliche Initialisierungen.

    Der Assemblercode schreibt nur die Pixel in den Buffer (wie gesagt noch unoptimiert). Probiert mal aus, und schreibt, was man noch verbessern könnte/sollte.
    Ich setz mich mal dran und bringe den ASM-Code in eine Form, bei der man keine weiteren ASM-Includes und den ASM-Quellcode (FASM.au3) mehr braucht.

    Btw, die Funktion _solve_linear_quad($a, $b) ist ein von mir erstellter Gleichungslöser für lineare quadratische Gleichungssysteme. Erst wollte ich den auch in Assembler schreiben, aber der geht auch in AutoIt-Code superfix!
    100 Gleichungen mit 100 Unbekannten löst er auch ^^

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlusConstants.au3>
    #include <StructureConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <array.au3>
    #include <GDIConstants.au3>
    #include <AssembleIt.au3>

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

    Opt("GuiOnEventMode", 1)

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

    ;Global $aDrag[5][2] = [[0, 0],[0, 0],[800, 50],[100, 530],[700, 450]]
    Global $aDrag[5][2] = [[0, 0],[35, 100],[100, 35],[750, 350],[110, 380]]

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

    Global $minx, $miny, $maxx, $maxy, $struct_float, $ptr_Hintergrund, $b, $b_buffer, $struct_buffer, $h
    Global $b_buffer = 800, $h_buffer = 540, $struct_koord

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

    $hGui = GUICreate("DrawImage_4Points Test", 800, 580)
    GUISetOnEvent(-3, "_Exit")
    GUICtrlCreateButton("render with higher precision", 200, 550, 200, 20)
    GUICtrlSetOnEvent(-1, "_Render")
    GUICtrlCreateLabel("precision:", 410, 550, 80, 20, 0x0002)
    $cSlider = GUICtrlCreateSlider(500, 545, 100, 25)
    GUICtrlSetData(-1, 25)
    GUICtrlSetOnEvent(-1, "_Slider")
    $cLabel = GUICtrlCreateLabel("0.25", 610, 550, 50, 20)

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

    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($b_buffer, $h_buffer, $hGraphics)
    $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)

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

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState()

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

    $hBrush = _GDIPlus_BrushCreateSolid(0x8800FF00)
    $hPen = _GDIPlus_PenCreate(0xFFFF0000)

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

    $sFile = FileOpenDialog("open image", "", "(*.jpg;*.bmp;*.png;*.tif;*.gif)")
    ;$sfile = "mona-lisa.jpg"
    $hImage = _GDIPlus_ImageLoadFromFile($sFile)
    Global $iwidth, $iheight
    Local $ptr_Hintergrund
    Local $hDC_Hintergrund = getDCfromfile($sFile, $ptr_Hintergrund) ;GDI+ lädt auch jpg

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

    Global $struct = DllStructCreate("dword[" & $iwidth * $iheight & "]", $ptr_Hintergrund)
    ;global $himagefile="mona-lisa.jpg"

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

    _ReDraw(0.02)

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

    $iIndex = 0
    While 1
    $aInfo = GUIGetCursorInfo($hGui)

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

    If Not $aInfo[2] Then $iIndex = 0
    Switch $iIndex
    Case 0
    If $aInfo[2] Then
    For $I = 1 To 4
    If $aInfo[0] > $aDrag[$I][0] - 5 And $aInfo[0] < $aDrag[$I][0] + 5 And $aInfo[1] > $aDrag[$I][1] - 5 And $aInfo[1] < $aDrag[$I][1] + 5 Then
    $iIndex = $I
    Sleep(100)
    ExitLoop
    EndIf
    Next
    EndIf
    Case Else
    $aDrag[$iIndex][0] = $aInfo[0]
    $aDrag[$iIndex][1] = $aInfo[1]
    _ReDraw(0.02)
    EndSwitch

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

    Sleep(20)
    WEnd

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

    Func _projective_mapping($hbitmap_1, $hImage, $1x, $1y, $2x, $2y, $3x, $3y, $4x, $4y) ;eck-koordinaten projektion, obere linke und untere rechte Ecke Orginal

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

    $b = _GDIPlus_ImageGetWidth($hImage)
    $h = _GDIPlus_ImageGetHeight($hImage)

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

    $u = 0 ;koordinaten oben rechts im $image
    $v = 0

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

    $BitmapData = _GDIPlus_BitmapLockBits($hbitmap_1, 0, 0, $b_buffer, $h_buffer, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

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

    If @error Then MsgBox(0, "", "Error locking region " & @error)
    Global $ptr_buffer = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap.
    Global $struct_buffer = DllStructCreate("dword [" & $b_buffer * $h_buffer & "]", $ptr_buffer)

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

    Dim $bl[8] = [$u, $b, $b, $u, $v, $v, $h, $h] ;lösungen der 8 Gleichungen (Eck-Koordinaten Orginalbild)
    Dim $a[8][8] = [ _ ;8 gleichungen in Matrix
    [$1x, $1y, 1, 0, 0, 0, -$1x * $u, -$1y * $u], _ ;Eckpunkte Transformiertes Rechteck
    [$2x, $2y, 1, 0, 0, 0, -$2x * $b, -$2y * $b], _
    [$3x, $3y, 1, 0, 0, 0, -$3x * $b, -$3y * $b], _ ;Eckpunkte Transformiertes Rechteck
    [$4x, $4y, 1, 0, 0, 0, -$4x * $u, -$4y * $u], _
    [0, 0, 0, $1x, $1y, 1, -$1x * $v, -$1y * $v], _ ;Eckpunkte Transformiertes Rechteck
    [0, 0, 0, $2x, $2y, 1, -$2x * $v, -$2y * $v], _
    [0, 0, 0, $3x, $3y, 1, -$3x * $h, -$3y * $h], _ ;Eckpunkte Transformiertes Rechteck
    [0, 0, 0, $4x, $4y, 1, -$4x * $h, -$4y * $h]]

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

    $s = _solve_linear_quad($a, $bl) ;8 lineare Gleichungen lösen
    ; _arraydisplay($s)
    $struct_float = DllStructCreate("float [8]") ;die 8 variablen in struct
    For $I = 1 To 8
    DllStructSetData($struct_float, 1, $s[$I - 1], $I)
    Next
    ;geraden 4-1 und 3-2 y=mx+b
    $m1 = ($4y - $1y) / ($4x - $1x)
    $b1 = $1y - $m1 * $1x

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

    $m2 = ($3y - $2y) / ($3x - $2x)
    $b2 = $2y - $m2 * $2x
    ;geraden 1-2 und 3-4 y=mx+b
    $m3 = ($2y - $1y) / ($2x - $1x)
    $b3 = $1y - $m3 * $1x

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

    $m4 = ($3y - $4y) / ($3x - $4x)
    $b4 = $3y - $m4 * $3x

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

    $struct_koord = DllStructCreate("uint[8]"); struct für die x- und y-koordinaten

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

    ;kleinstes und grösstes x und y finden, um nicht die gesamte bitmap durchzurechnen, sondern
    ;nur den Teil, der von dem quadrilateral belegt ist
    Global $minx = 1e9, $miny = 1e9, $maxx = 0, $maxy = 0
    For $I = 1 To 4
    DllStructSetData($struct_koord, 1, Eval($I & "x"), $I * 2 - 1);struct füllen
    DllStructSetData($struct_koord, 1, Eval($I & "y"), $I * 2);1x,1y,2x,2y,3x...

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

    If Eval($I & "x") < $minx Then $minx = Eval($I & "x");minimum und maximum finden
    If Eval($I & "x") > $maxx Then $maxx = Eval($I & "x")
    If Eval($I & "y") > $maxy Then $maxy = Eval($I & "y")
    If Eval($I & "y") < $miny Then $miny = Eval($I & "y")
    Next

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

    $ret = _AssembleIt("float", "_quadrilateral")
    ; MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$ret' & @lf & @lf & 'Return:' & @lf & $ret) ;### Debug MSGBOX

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

    ;folgende Zeilen in AutoItcode sind genau so in Assembler überführt
    ;~ For $py = $miny To $maxy Step 5
    ;~ For $px = $minx To $maxx Step 5
    ;~ ;ist y<mx+b , dann
    ;~ If $4x > $1x And $m1 * $px + $b1 < $py Then ContinueLoop ;grösser = unter der linie
    ;~ If $4x < $4x And $m1 * $px + $b1 > $py Then ContinueLoop ;grösser = unter der linie
    ;~ If $3x > $2x And $m2 * $px + $b2 > $py Then ContinueLoop ;grösser = unter der linie
    ;~ If $3x < $2x And $m2 * $px + $b2 < $py Then ContinueLoop ;grösser = unter der linie
    ;~ $X = int(($s[0] * $px + $s[1] * $py + $s[2]) / ($s[6] * $px + $s[7] * $py + 1))
    ;~ $Y = int(($s[3] * $px + $s[4] * $py + $s[5]) / ($s[6] * $px + $s[7] * $py + 1))
    ;~ If $X < 0 Or $Y < 0 Then ContinueLoop
    ;~ If $X * $Y > $b * $h Then ContinueLoop
    ;~ $col = DllStructGetData($struct, 1, $Y * $b + $X) ;farbe aus bild holen
    ;~ DllStructSetData($struct_buffer, 1, $col, ($py -1) * $b_buffer + $px)
    ;~ Next
    ;~ Next
    ;~ $t = TimerInit()
    $a = _GDIPlus_BitmapUnlockBits($hbitmap_1, $BitmapData)

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

    EndFunc ;==>_projective_mapping

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

    Func _quadrilateral()
    _("use32")
    _("org " & FasmGetBasePtr($Fasm))
    _("jmp _los")
    _("align 4")
    ; _("_speicher:")
    _("_px dd 0")
    _("_py dd 0")
    _("_x dd 0")
    _("_y dd 0")
    _("_b_buffer dd 0")
    _("_m1 dd 0.0") ;y=m*x+b geradengleichung
    _("_m2 dd 0.0") ;m=(x2-x1)/(y2-y1)
    _("_b1 dd 0.0") ;b=y-m*x
    _("_b2 dd 0.0")

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

    _("_los:")

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

    _("finit") ;coproinit
    ;geradengleichung wird gebraucht, um festzustellen, ob das aktuelle
    ;pixel innerhalb der zu zeichnenden fläche liegt
    ;$m1 = ($4y - $1y) / ($4x - $1x)
    _("mov ecx," & DllStructGetPtr($struct_koord));koordinaten
    _("fild dword[ecx+4*7]") ;st0=4y
    _("fisub dword[ecx+4*1]") ;st0=(4y-1y)
    _("fild dword[ecx+4*6]") ;st0=4x st1=(4y-1y)
    _("fisub dword[ecx+4*0]") ;st0=(4x-1x)
    _("fdivp") ;st0=m1
    _("fst dword[_m1]") ;st0=m1

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

    ;$b1 = $1y - $m1 * $1x
    _("fimul dword[ecx+4*0]") ;st0=m1*1x
    _("fisubr dword[ecx+4*1]") ;st0=1y-m1*1x = b1
    _("fstp dword[_b1]") ;b1 speichern, fpstack clean

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

    ;$m2 = ($3y - $2y) / ($3x - $2x)
    _("fild dword[ecx+4*5]") ;st0=3y
    _("fisub dword[ecx+4*3]") ;st0=(3y-2y)
    _("fild dword[ecx+4*4]") ;st0=3x st1=(3y-2y)
    _("fisub dword[ecx+4*2]") ;st0=(3x-2x)
    _("fdivp") ;st0=m2
    _("fst dword[_m2]") ;st0=m2
    ;$b2 = $2y - $m2 * $2x
    _("fimul dword[ecx+4*2]") ;st0=m2*2x
    _("fisubr dword[ecx+4*3]") ;st0=2y-m2*2x = b2
    _("fstp dword[_b2]") ;b2 speichern, fpstack clean
    _("")

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

    ;variablen in speicher schreiben
    _("mov eax," & $b_buffer)
    _("mov dword[_b_buffer],eax")
    ;register mit den laufvariablen laden
    _("mov edx," & $miny - 1) ;for ymin to ymax
    _("mov esi," & $ptr_Hintergrund) ;pointer auf orginal bitmap
    _("mov edi," & DllStructGetPtr($struct_buffer));pointer auf den backbuffer
    _("mov ebx," & DllStructGetPtr($struct_float));die 8 variablen

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

    _(".start:") ;hier gehts los

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

    _(".y_loop:") ;for py=ymin to ymax
    _("add edx,1") ;py
    _("cmp edx," & $maxy)
    _("jae .ende")
    _("mov ecx," & $minx - 1)

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

    _(".x_loop:") ;for px=xmin to xmax
    _("add ecx,1") ;px
    _("cmp ecx," & $maxx) ;ist maxx erreicht?
    _("jae .y_loop") ;ja, dann next py

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

    _("mov dword[_py],edx")
    _("mov dword[_px],ecx") ;abspeichern 17
    _("")
    _("jmp .is_pixel_inside_quadrilateral") ;prüfen, ob pixel in der fläche ist
    _(".pixelinside:")
    _("")
    _("")
    _("")
    _("fild dword[_py]") ;st0=py
    _("fild dword[_px]") ;st0=px st1=py

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

    ;x=int($s[0] * $px + $s[1] * $py + $s[2]) / ($s[6] * $px + $s[7] * $py + 1) bissl floatingpoint
    _("fld dword[ebx+4*0]") ;st0=s[0] st1=px st2=py
    _("fmul st0,st1") ;st0=s[0]*px
    _("fld dword[ebx+4*1]") ;st0=s[1] st1=s[0]*px st2=px st3=py
    _("fmul st0,st3") ;st0=s[1]*py st1=s[0]*px st2=px st3=py
    _("faddp") ;st0=s[1]*py+s[0]*px st1=px st2=py
    _("fadd dword[ebx+4*2]") ;st0=s[1]*py+s[0]*px+s[2] st1=px st2=py
    _("fld dword[ebx+4*6]") ;st0=$s[6] st1=s[1]*py+s[0]*px+s[2] st2=px st3=py
    _("fmul st0,st2") ;st0=$s[6]*px st1=s[1]*py+s[0]*px+s[2] st2=px st3=py
    _("fld dword[ebx+4*7]") ;st0=s[7] st1=$s[6]*px st2=s[1]*py+s[0]*px+s[2] st3=px st4=py
    _("fmul st0,st4") ;st0=s[7]* py st1=$s[6]*px st2=s[1]*py+s[0]*px+s[2] st3=px st4=py
    _("faddp ") ;st0=s[7]*py+$s[6]*px st1=s[1]*py+s[0]*px+s[2] st1=px st2=py
    _("fld1")
    _("faddp ") ;st0=s[7]*py+$s[6]*px+1 st1=s[1]*py+s[0]*px+s[2] st2=px st3=py
    _("fdivp") ;st0=x st1=px st2=py
    _("fistp dword[_x]") ;abspeichern als integer st0=px st1=py
    _("")
    ;$Y = Int(($s[3] * $px + $s[4] * $py + $s[5]) / ($s[6] * $px + $s[7] * $py + 1))
    _("fld dword[ebx+4*3]") ;st0=s[3] st1=px st2=py
    _("fmul st0,st1") ;st0=s[3]*px
    _("fld dword[ebx+4*4]") ;st0=s[4] st1=s[3]*px st2=px st3=py
    _("fmul st0,st3") ;st0=s[4]*py st1=s[3]*px st2=px st3=py
    _("faddp") ;st0=s[4]*py+s[3]*px st1=px st2=py
    _("fadd dword[ebx+4*5]") ;st0=s[4]*py+s[3]*px+s[5] st1=px st2=py
    _("fld dword[ebx+4*6]") ;st0=$s[6] st1=s[4]*py+s[3]*px+s[5] st2=px st3=py
    _("fmul st0,st2") ;st0=$s[6]*px st1=s[4]*py+s[3]*px+s[5] st2=px st3=py
    _("fld dword[ebx+4*7]") ;st0=s[7] st1=$s[6]*px st2=st1=s[4]*py+s[3]*px+s[5] st3=px st4=py
    _("fmul st0,st4") ;st0=s[7]* py st1=$s[6]*px st2=st1=s[4]*py+s[3]*px+s[5] st3=px st4=py
    _("faddp ") ;st0=s[7]*py+$s[6]*px st1=st1=s[4]*py+s[3]*px+s[5] st1=px st2=py
    _("fld1")
    _("faddp ") ;st0=s[7]*py+$s[6]*px+1 st1=st1=s[4]*py+s[3]*px+s[5] st2=px st3=py
    _("fdivp") ;st0=y st1=px st2=py
    _("fistp dword[_y]") ;abspeichern als integer st0=px st1=py 50
    _("FUCOMPP") ;pop, pop => stack clean!

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

    ;$col = DllStructGetData($struct, 1, $Y * $b + $X) ;farbe aus bild holen
    _("mov eax," & $b)
    _("push edx") ;sichern
    _("mul dword[_y]") ;eax=$b*y
    _("add eax,dword[_x]") ;eax=$b*y+x
    _("pop edx") ;

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

    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz .x_loop") ;wenn negativ, jump

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

    _("cmp eax," & $b * $h - $b) ;addresse grösser als bitmap?
    _("ja .x_loop")

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

    _("shl eax,2") ;4 byte = 1 pixel! daher anzahl der byte vervierfachen
    _("mov eax,dword[esi+eax*1]") ;pixelfarbe holen aus ursprungsbitmap
    _("push eax") ;pixelfarbe sichern

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

    ;DllStructSetData($struct_buffer, 1, $col, ($py - 1) * $b_buffer + $px)
    _("mov eax,dword[_py]")
    _("sub eax,1") ;eax=py-1
    _("push edx") ;sichern
    _("mul dword[_b_buffer]")
    _("pop edx") ;sichern
    _("add eax,dword[_px]") ;eax=($py - 1) * $b_buffer + $px
    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz .popeax")
    ;_("ret")
    ;~ _("cmp eax,"&$maxy*$maxx-$maxy)
    ;~ ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $b*$h = ' & $b*$h & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;~ _("ja .popeax")

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

    _("mov edi," & DllStructGetPtr($struct_buffer));pointer auf den backbuffer
    _("shl eax,2") ;4 byte = 1 pixel! daher anzahl der byte vervierfachen
    _("add edi,eax") ;edi=adresse pixel im buffer
    _("pop eax") ;farbe holen
    _("mov [edi],eax") ;pixel in buffer schreiben
    _("jmp .x_loop") ;next x
    _("")
    _(".ende:")
    _("ret")

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

    _("")
    _(".popeax:")
    _("pop eax")
    _("jmp .x_loop")

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

    _(".is_pixel_inside_quadrilateral:")
    ;prüfen ob pixel in der fläche liegt
    _("push eax")
    _("push ecx")
    _("mov ecx," & DllStructGetPtr($struct_koord));koordinaten
    ;~If $4x>$1x and $m1 * $px + $b1 < $py Then ContinueLoop ;ist punkt ausserhalb der fläche, dann nächstes px
    _("mov eax,dword[ecx+4*6]") ;eax=4x
    _("cmp eax,dword[ecx+4*0]") ;ist $4x>$1x
    _("jb @f") ;wenn kleiner, ein label weiter
    _("fld dword[_m1]") ;$m1 * $px + $b1
    _("fimul dword[_px]")
    _("fadd dword[_b1]")
    _("fistp dword[_y]") ;y=$m1 * $px + $b1
    _("mov eax,dword[_y]")
    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz .weiter") ;wenn negativ, dann nächstes px
    _("cmp eax,dword[_py]") ;ist y<py?
    _("jb .weiter") ;wenn py grösser, dann nächstes px
    _("@@:")
    ;If $4x<$1x and $m1 * $px + $b1 > $py Then ContinueLoop ;ist punkt ausserhalb der fläche, dann nächstes px
    _("mov eax,dword[ecx+4*6]") ;eax=4x
    _("cmp eax,dword[ecx+4*0]") ;ist $4x<$1x
    _("ja @f") ;wenn grösser, ein label weiter
    _("fld dword[_m1]") ;$m1 * $px + $b1
    _("fimul dword[_px]")
    _("fadd dword[_b1]")
    _("fistp dword[_y]") ;y=$m1 * $px + $b1
    _("mov eax,dword[_y]")
    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz @f") ;wenn negativ, dann nächstes px
    _("cmp eax,dword[_py]") ;ist py<y?
    _("ja .weiter") ;wenn py kleiner, dann nächstes px
    _("@@:")
    ;If $3x>$2x and $m2 * $px + $b2 > $py Then ContinueLoop ;ist punkt ausserhalb der fläche, dann nächstes px
    _("mov eax,dword[ecx+4*4]") ;eax=3x
    _("cmp eax,dword[ecx+4*2]") ;ist $3x>$2x
    _("jb @f") ;wenn kleiner, ein label weiter
    _("fld dword[_m2]") ;$m2* $px + $b2
    _("fimul dword[_px]")
    _("fadd dword[_b2]")
    _("fistp dword[_y]") ;
    _("mov eax,dword[_y]")
    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz @f") ;wenn negativ, dann
    _("cmp eax,dword[_py]") ;ist y<py?
    _("ja .weiter") ;wenn py kleiner, dann nächstes px
    _("@@:")
    ;If $3x<$2x and $m2 * $px + $b2 < $py Then ContinueLoop ;ist punkt ausserhalb der fläche, dann nächstes px
    _("mov eax,dword[ecx+4*4]") ;eax=3x
    _("cmp eax,dword[ecx+4*2]") ;if $3x<$2x
    _("ja @f") ;wenn kleiner, ein label weiter
    _("fld dword[_m2]") ;$m2 * $px + $b2
    _("fimul dword[_px]")
    _("fadd dword[_b2]")
    _("fistp dword[_y]") ;
    _("mov eax,dword[_y]")
    _("test eax, 10000000000000000000000000000000b") ;zahl positiv?
    _("jnz .weiter") ;wenn negativ, dann nächstes px
    _("cmp eax,dword[_py]") ;ist py>y?
    _("jb .weiter") ;wenn py grösser, dann nächstes px

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

    _("@@:")
    _("pop ecx")
    _("pop eax")
    _("jmp .pixelinside")

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

    _(".weiter:")
    _("pop ecx")
    _("pop eax")
    _("jmp .x_loop")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    _("")
    EndFunc ;==>_quadrilateral

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

    ;GDI+ wird nur verwendet, um andere Dateien als das BMP-Format zu laden
    Func getDCfromfile($bmpfile, ByRef $ptr) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($bmpfile)
    Local $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    $iwidth = _GDIPlus_ImageGetWidth($hBitmap)
    $iheight = _GDIPlus_ImageGetHeight($hBitmap)

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

    Local $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -$iheight)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32)
    Local $hdc = _WinAPI_GetDC(0)
    Local $hcdc = _WinAPI_CreateCompatibleDC($hdc)
    Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'ptr', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 1, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    ; select object
    _WinAPI_SelectObject($hcdc, $adib[0])
    ; copy the content of the bitmap into the buffer ...
    _WinAPI_GetDIBits($hdc, $hbmp, 0, $iheight, $adib[4], DllStructGetPtr($tBMI), 1)
    ; create the a dllstruct with the pointer $aDIB[4]
    Local $stride = 3 * $iwidth + Mod($iwidth, 4) ;number of bytes in one line (filled with some bytes, because it must be a multiple of four!)
    $tbits = DllStructCreate('byte[' & $stride * $iheight & ']', $adib[4])
    $ptr = DllStructGetPtr($tbits)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($adib[0])
    Return $hcdc ;MemoryDC of bitmap
    EndFunc ;==>getDCfromfile

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

    Func _solve_linear_quad($a, $b) ;matrix,lösung Gaußsches Eliminationsverfahren, löst x gleichungen mit x unbekannten
    ;by Andy
    Dim $Y[UBound($b)] ;ergebnisse
    $n = UBound($a) - 1 ;anzahl der zeilen/spalten
    ;falls erforderlich, zeilen und spalten tauschen
    If $a[0][0] = 0 Then ;wenn erster koeffizient = 0, dann kann das system nicht starten => spalten tauschen ggf zeilen tauschen
    For $k = 0 To $n ;jede zeile
    For $j = 0 To $n ;alle spalten in dieser Zeile testen
    If $a[$k][$j] <> 0 Then
    For $m = 0 To $n ;treffer, die erste spalte mit der j. tauschen
    $t = $a[$m][$j] ;sichern
    $a[$m][$j] = $a[$m][0] ;mit erster spalte tauschen
    $a[$m][0] = $t
    Next
    For $j = 0 To $n ;zeilen tauschen
    $t = $a[0][$j] ;sichern
    $a[0][$j] = $a[$k][$j] ;mit erster spalte tauschen
    $a[$k][$j] = $t
    Next
    $t = $b[0] ;ergebnisse auch tauschen
    $b[0] = $b[$k]
    $b[$k] = $t
    ExitLoop 2
    EndIf
    Next
    Next
    EndIf

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

    If $a[0][0] = 0 Then Return SetError(1, 0, 1)

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

    ;endlich rechnen :)
    For $I = 0 To $n ;alle zeilen
    ;erstes element auf 1 bringen indem man gesamte zeile durch erstes Element teilt
    For $k = $I To $n
    $t = $a[$k][$I] ;erstes element merken
    If $t <> 0 Then ;nur, wenn das erste element ungleich null ist...
    For $j = $I To $n
    $a[$k][$j] /= $t ;alle zeilenmitglieder durch erstes element teilen
    Next
    ;b durch i teilen
    $b[$k] /= $t ;ergebnis natürlich auch
    EndIf
    Next
    ;zeile i von allen weiteren zeilen subtrahieren, erstes element wird zu 0
    For $k = $I + 1 To $n
    If $a[$k][$I] <> 0 Then ;wenn null, dann überspringen
    For $j = $I To $n
    $a[$k][$j] -= $a[$I][$j] ;die i.zeile von der aktuellen zeile subtrahieren
    Next
    $b[$k] -= $b[$I] ;ergebnisse natürlich auch
    EndIf
    Next
    Next
    ;_ArrayDisplay($a)
    ;alle parameter bestimmen durch rückwärtseinsetzen

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

    $Y[$n] = $b[$n] ;letzter ist bereits bekannt
    For $I = $n - 1 To 0 Step -1
    For $j = $n To $I + 1 Step -1
    $b[$I] -= $a[$I][$j] * $Y[$j]
    Next
    $Y[$I] = $b[$I]
    Next
    Return $Y
    EndFunc ;==>_solve_linear_quad
    Exit

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

    Func _ReDraw($fPrecision)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
    _projective_mapping($hBmpBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1])
    ;_GDIPlus_GraphicsDrawImage_4Points($hGfxBuffer, $hImage, $aDrag[1][0], $aDrag[1][1], $aDrag[2][0], $aDrag[2][1], $aDrag[3][0], $aDrag[3][1], $aDrag[4][0], $aDrag[4][1], $fPrecision)
    For $I = 1 To 4
    _GDIPlus_GraphicsFillRect($hGfxBuffer, $aDrag[$I][0] - 5, $aDrag[$I][1] - 5, 10, 10, $hBrush)
    _GDIPlus_GraphicsDrawRect($hGfxBuffer, $aDrag[$I][0] - 5, $aDrag[$I][1] - 5, 10, 10, $hPen)
    Next
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)

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

    EndFunc ;==>_ReDraw

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

    Func _Slider()
    GUICtrlSetData($cLabel, GUICtrlRead($cSlider) / 100)
    EndFunc ;==>_Slider

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

    Func _Render()
    Local $fPrecision = GUICtrlRead($cSlider) / 100
    SplashTextOn("Rendering with precision " & $fPrecision, "please wait", 250, 50)
    _ReDraw($fPrecision)
    SplashOff()
    EndFunc ;==>_Render

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

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    Func _Exit()
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]
  • &[fertig] Pi Berechnung von campweb auf 1000101 Dezimalstellen in C++

    • Andy
    • 27. November 2010 um 13:15

    Pinguin
    wg BBP, der "passende" Link mit Beispiel für den Nutzen ist das hier.
    Gerade im unteren Teil ist auch eine feine kurze (superschnelle) Variante gezeigt, um MODULO sehr großer Zahlen per Binärrechnung in einer Handvoll Rechenschritten zu machen, was die Sache extrem beschleunigt.(bin mir nicht sicher, aber eukalyptus hat das m.E. sogar in der BigInt.udf so gemacht)
    Der Witz ist nämlich an der BBP-Methode, dass die Berechnung der n-ten Dezimalstelle gewissermassen als "Abfall" noch einige weitere Dezimalstellen liefert. Und die weiteren Dezimalstellen sind dann mit einer kleinen Veränderung an der Rechenmatrix zu erhalten, OHNE den kompletten Algorithmus nochmal durchzulaufen!

    Zitat von campweb

    Wenn ich die ganzen Dezi´s aber haben will!!!
    Können wir dieses Thema jetzt mal abhacken? Ja. Gute Nacht noch.

    naja, Ignoranz gepaart mit extrem schmaler geistiger Bandbreite führt genau dazu:

    Zitat von campweb

    Endlich 100104 Stellen in 4 Stunden af meinem Pentium-Dual Core mit Hilfe von Delphi.

    Ich hab die 100104 Stellen selbst auf einem 1,2Ghz-PIII in nicht mal 10 Sec. erhalten! Incl. schreiben in eine Datei...mit Hilfe von Opera 10.63. Hat in etwa genausoviel mit AutoIt zu tun wie Delphi. Ist aber wesetlich schneller im Ergebnis! :rofl:

  • &[fertig] Pi Berechnung von campweb auf 1000101 Dezimalstellen in C++

    • Andy
    • 26. November 2010 um 23:53
    Zitat

    =====GESCHLOSSEN=====

    Ich hab mir jetzt eine Berechnung in C++ geschrieben, die auf 1000101 Dezimalstellen berechnet!
    Wird wohl so 15 Stunden dauern!
    Wer sich für das Programm interessiert, PN an mich.

    Die Bailey - Borwein - Plouffe - Formel berechnet die nte Dezimalziffer (und auch noch weitere folgende) von Pi. Seit dieser Formel müssen dazu die vorausgehenden Stellen nicht mehr ermittelt werden, was das Verfahren letztendlich zur ultimativen Berechnung von Pi per Computer erhebt!

  • Happy Birthday Raupi & SlowlyDead !!

    • Andy
    • 26. November 2010 um 17:49

    Glücklichen Herzwunsch den beiden Geburtstags"kindern"! :thumbup:
    Wenigstens eins davon gehört jetzt zu den "alten Säcken"! Willkommen im Club!

  • GDI+ Bitmap "trapezoid" zeichnen / DrawImage_4Points

    • Andy
    • 25. November 2010 um 09:50
    Zitat

    dass ich wieder momentan voll ausgelastet und keine große Hilfe in ASM bin...

    hehe, ausgelastet bin ich zzt. voll, ich knabbere mich Viertelstundenweise durch^^
    Du wirst dich wundern, der eigentliche ASM-code ist supersimpel!

    [autoit]

    for u=xmin to xmax
    for v=ymin to ymax
    x=f(u,v) ; siehe formeln
    y=f(u,v)
    col=f(x,y)
    setpixel(u,v,col)
    next
    next

    [/autoit]

    den kompletten Rest lasse ich in Autoit, die Lösung der 8 Gleichungen mit 8 Unbekannten und die Transformation bzw. gesamte Berechnung der Umgebung ist in 2-3 Millisekunden gemacht, dafür schreibe ich keinen ASM-Code!
    Die o.g. Schleife dauert per dllstructsetdata() in AutoIt 2-3 Sekunden! DA ist dann Potenzial, hehe 8o

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™