Via GDI+ Matrix normale Arrays transformieren

  • Hi

    In der GDIp.au3 gibt es die Funktion _GDIPlus_MatrixTransformPoints
    damit kann man z.B. Koordinaten, die sich in einem normalen Array befinden mit einer GDI+Matrix multiplizieren
    Kann manchmal ganz nützlich sein

    Hier ein kurzes Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

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

    HotKeySet("{ESC}", "_Exit")

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

    Global Const $PI = ATan(1) * 4
    Global Const $DegToRad = $PI / 180

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

    Global $aPoints[10][2]
    $aPoints[0][0] = 9
    For $i = 1 To 9
    $aPoints[$i][0] = Cos($i * 40 * $DegToRad) * 200 + 400
    $aPoints[$i][1] = Sin($i * 40 * $DegToRad) * 200 + 300
    Next

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

    Global $aGui[10]
    For $i = 1 To 9
    $aGui[$i] = GUICreate("", 100, 100, $aPoints[$i][0], $aPoints[$i][1])
    GUISetState()
    Next

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

    _GDIPlus_Startup()
    Global $hMatrixRotate = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrixRotate, 400, 300)
    _GDIPlus_MatrixRotate($hMatrixRotate, 1)
    _GDIPlus_MatrixTranslate($hMatrixRotate, -400, -300)

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

    Global $hMatrixScale = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrixScale, 400, 300)
    _GDIPlus_MatrixScale($hMatrixScale, 2, 1)
    _GDIPlus_MatrixTranslate($hMatrixScale, -400, -300)

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

    Global $aPointsNew

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

    While 1
    $aPoints = _GDIPlus_MatrixTransformPoints($hMatrixRotate, $aPoints)
    $aPointsNew = _GDIPlus_MatrixTransformPoints($hMatrixScale, $aPoints)
    For $i = 1 To $aPointsNew[0][0]
    WinMove($aGui[$i], "", $aPointsNew[$i][0], $aPointsNew[$i][1], 100, 100)
    Next
    Sleep(10)
    WEnd

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

    Func _Exit()
    _GDIPlus_MatrixDispose($hMatrixRotate)
    _GDIPlus_MatrixDispose($hMatrixScale)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_MatrixTransformPoints
    ; Description ...: Multiplies each point in an array by a matrix
    ; Syntax.........: _GDIPlus_MatrixTransformPoints($hMatrix, $aPoints)
    ; Parameters ....: $hMatrix - Pointer to a Matrix object
    ; $aPoints - Array of points to be transformed:
    ; |[0][0] - Number of points
    ; |[1][0] - Point 1 X coordinate
    ; |[1][1] - Point 1 Y coordinate
    ; |[2][0] - Point 2 X coordinate
    ; |[2][1] - Point 2 Y coordinate
    ; |[n][0] - Point n X coordinate
    ; |[n][1] - Point n Y coordinate
    ; Return values .: Success - Array containing the transformed points:
    ; |[0][0] - Number of points
    ; |[1][0] - Transformed point 1 X coordinate
    ; |[1][1] - Transformed point 1 Y coordinate
    ; |[2][0] - Transformed point 2 X coordinate
    ; |[2][1] - Transformed point 2 Y coordinate
    ; |[n][0] - Transformed point n X coordinate
    ; |[n][1] - Transformed point n Y coordinate
    ; Failure - -1 and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: Each point in the array is treated as a row matrix. The multiplication is performed with the row matrix on the
    ; +left and the matrix on the right
    ; Related .......: _GDIPlus_MatrixTransformPointsI
    ; Link ..........; @@MsdnLink@@ GdipTransformMatrixPoints
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_MatrixTransformPoints($hMatrix, $aPoints)
    Local $iI, $iCount, $tPoints, $pPoints, $aResult

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

    $iCount = $aPoints[0][0]
    $tPoints = DllStructCreate("float[" & $iCount * 2 & "]")
    $pPoints = DllStructGetPtr($tPoints)

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

    For $iI = 1 To $iCount
    DllStructSetData($tPoints, 1, $aPoints[$iI][0], ($iI - 1) * 2 + 1)
    DllStructSetData($tPoints, 1, $aPoints[$iI][1], ($iI - 1) * 2 + 2)
    Next

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

    $aResult = DllCall($ghGDIPDll, "uint", "GdipTransformMatrixPoints", "hwnd", $hMatrix, "ptr", $pPoints, "int", $iCount)
    If @error Then Return SetError(@error, @extended, -1)

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

    $GDIP_STATUS = $aResult[0]
    If $GDIP_STATUS Then Return -1

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

    For $iI = 1 To $iCount
    $aPoints[$iI][0] = DllStructGetData($tPoints, 1, ($iI - 1) * 2 + 1)
    $aPoints[$iI][1] = DllStructGetData($tPoints, 1, ($iI - 1) * 2 + 2)
    Next

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

    Return $aPoints
    EndFunc ;==>_GDIPlus_MatrixTransformPoints

    [/autoit]

    Bei großen Arrays sollte man gleich DllStructs statt Arrays verwenden, damit nicht jedesmal umgewandelt werden muß...

    E

  • Klasse Funktion! Kann man irgendwann bestimmt mal gut gebrauchen! :thumbup:

    GDIp.au3 hat ja zig Funktion, die bestimmt interessant sind, leider gibt es wenig Beispiele dazu! Klasse, was du alles aus der GDIp.au3 heraus holst!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Und dann hätte ich da noch ein etwas aufwändigeres Beispiel ^^

    Spoiler anzeigen
    [autoit]

    #include "GDIP.au3"
    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <String.au3>
    #include <WindowsConstants.au3>

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

    Opt("GUIOnEventMode", 1)

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

    Global $sText = "GDI+ Example by Eukalyptus....."
    $sText = _StringReverse($sText)

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

    Global $iW = 500
    Global $iH = 400

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

    Global Const $PI = ATan(1) * 4
    Global Const $DegToRad = $PI / 180

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

    _GDIPlus_Startup()
    Global $hGui = GUICreate("Test", $iW, $iH)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)

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

    Global $hBmpFade = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Global $hGfxFade = _GDIPlus_ImageGetGraphicsContext($hBmpFade)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxFade, 2)
    Global $fTransform = -0.01
    _GDIPlus_GraphicsTranslateTransform($hGfxFade, -($iW / 2 * $fTransform), -($iH / 2 * $fTransform))
    _GDIPlus_GraphicsScaleTransform($hGfxFade, 1 + $fTransform, 1 + $fTransform)
    _GDIPlus_GraphicsSetInterpolationMode($hGfxFade, 0)
    _GDIPlus_GraphicsClear($hGfxFade, 0xFF000000)
    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState()

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

    Global $hPath = _GDIPlus_PathCreate()
    Global $aSplit = StringSplit($sText, "")
    Global $fX, $fY, $fA = 360 / $aSplit[0]
    For $i = 1 To $aSplit[0]
    $fX = Cos($i * $fA * $DegToRad) * $iH / 6
    $fY = Sin($i * $fA * $DegToRad) * $iH / 6
    _GDIPlus_PathAddLine($hPath, $fX, $fY, $fX + 1, $fY)
    Next

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

    Global $hMatrixRotate = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixRotate($hMatrixRotate, 1)

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

    Global $hMatrixRotate2 = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrixRotate2, 1, 1)
    _GDIPlus_MatrixRotate($hMatrixRotate2, 0.6)
    _GDIPlus_MatrixTranslate($hMatrixRotate2, -1, -1)

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

    Global $tScale = DllStructCreate("float[4]")
    Global $pScale = DllStructGetPtr($tScale)
    DllStructSetData($tScale, 1, 1, 1)
    DllStructSetData($tScale, 1, 0, 2)
    DllStructSetData($tScale, 1, 0, 3)
    DllStructSetData($tScale, 1, 2, 4)

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

    Global $hMatrixRotate3 = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixRotate($hMatrixRotate3, 0.8)

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

    Global $tPulse = DllStructCreate("float[2]")
    Global $pPulse = DllStructGetPtr($tPulse)
    DllStructSetData($tPulse, 1, 1, 1)
    DllStructSetData($tPulse, 1, 0, 2)

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

    Global $hPen = _GDIPlus_PenCreate(0xFF00FF00)
    Global $hBrush = _GDIPlus_BrushCreateSolid(0x40000000)

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

    Global $hFormat = _GDIPlus_StringFormatCreate()
    Global $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    Global $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)

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

    While 1
    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpFade, 0, 0)
    _Draw()
    _GDIPlus_GraphicsDrawImage($hGfxFade, $hBmpBuffer, 0, 0)
    _GDIPlus_GraphicsFillRect($hGfxFade, 0, 0, $iW, $iH, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Sleep(10)
    WEnd

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

    Func _Draw()
    _GDIPlus_PathTransform($hPath, $hMatrixRotate)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipGetPointCount", "hwnd", $hPath, "int*", 0)
    Local $iCount = $aResult[2]
    Local $tPoints = DllStructCreate("float[" & $iCount * 2 & "]")
    Local $pPoints = DllStructGetPtr($tPoints)
    DllCall($ghGDIPDll, "uint", "GdipGetPathPoints", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount)

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

    DllCall($ghGDIPDll, "uint", "GdipTransformMatrixPoints", "hwnd", $hMatrixRotate2, "ptr", $pScale, "int", 2)
    Local $hMatrixScale = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixScale($hMatrixScale, 1 + DllStructGetData($tScale, 1, 1), 1 + DllStructGetData($tScale, 1, 4))
    DllCall($ghGDIPDll, "uint", "GdipTransformMatrixPoints", "hwnd", $hMatrixScale, "ptr", $pPoints, "int", $iCount)
    _GDIPlus_MatrixDispose($hMatrixScale)

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

    DllCall($ghGDIPDll, "uint", "GdipTransformMatrixPoints", "hwnd", $hMatrixRotate3, "ptr", $pPulse, "int", 1)
    Local $fSize = Abs(DllStructGetData($tPulse, 1, 1))
    $hMatrixScale = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixScale($hMatrixScale, $fSize, $fSize)
    DllCall($ghGDIPDll, "uint", "GdipTransformMatrixPoints", "hwnd", $hMatrixScale, "ptr", $pPoints, "int", $iCount)
    _GDIPlus_MatrixDispose($hMatrixScale)

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

    Local $hPathDraw = _GDIPlus_PathCreate()
    Local $fX, $fY
    $fSize *= $iH / $aSplit[0] * 4
    For $i = 1 To $aSplit[0]
    $fX = DllStructGetData($tPoints, 1, ($i - 1) * 4 + 1) + $iW / 2
    $fY = DllStructGetData($tPoints, 1, ($i - 1) * 4 + 2) + $iH / 2
    DllStructSetData($tLayout, 1, $fX)
    DllStructSetData($tLayout, 2, $fY)
    _GDIPlus_PathAddString($hPathDraw, $aSplit[$i], $tLayout, $hFamily, 0, $fSize, $hFormat)
    Next

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

    _GDIPlus_GraphicsDrawPath($hGfxBuffer, $hPathDraw, $hPen)
    _GDIPlus_PathDispose($hPathDraw)
    EndFunc ;==>_Draw

    [/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]

    Func _Exit()
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_MatrixDispose($hMatrixRotate)
    _GDIPlus_MatrixDispose($hMatrixRotate2)
    _GDIPlus_GraphicsDispose($hGfxFade)
    _GDIPlus_BitmapDispose($hBmpFade)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]