Prüfen ob sich 2 Grafiken überlagern

  • Hallo,
    ich möchte gerne prüfen, ob sich 2 Grafiken überlagern:

    [autoit]


    $pos = ControlGetPos($Form1,"",$Pic1) ;Grafik A
    $x = $pos[0] ;Entfernung von Links
    $y = $pos[1] ;Entfernung von Oben
    $w = $pos[2] ;Breite
    $h = $pos[3] ;Höhe
    $w1 = $w*(1-($k-1)) ;Breite schmälern
    $w2 = $h*(1-($k-1)) ;Höhe schmälern
    $w3 = $w*$k ;verbreitern
    $w4 = $h*$k ;vergrößern
    $pos2 = ControlGetPos($Form1,"",$Pic5) ;Grafik B
    $x2 = $pos[0] ;Entfernung von Links
    $y2 = $pos[1] ;Entfernung von Oben
    $ww = $pos[2] ;Breite
    $hh = $pos[3] ;Höhe

    [/autoit]

    Wie muss ich das jetzt ansetzen?
    ich muss prüfen ob sich 4 Werte überlappen, aber ich weiß einfach nicht wie ichs anstellen soll :(
    Hoffentlich kann mir jemand helfen
    LG
    Captain09

    Einmal editiert, zuletzt von Captain09 (18. Mai 2014 um 19:39)

    • Offizieller Beitrag

    Wenn es zwei rechteckige Grafiken sind, kannst du die Koordinaten in Rectangle packen und vergleichen.

    Spoiler anzeigen
    [autoit]

    ;===============================================================================
    ; Function Name: _WinAPI_IntersectRect(ByRef $Src1Rect, ByRef $Src2Rect)
    ; Description: Ermittelt Schnittmengen zweier RECT-Strukturen
    ; Parameter(s): $Src1Rect, $Src2Rect RECT-Strukturen aus denen Schnittmengen festgestellt werden sollen
    ; Return Value(s): Erfolg RECT-Struktur der Schnittmenge
    ; Fehler 0 set @error 1-keine Struktur(en) übergeben
    ; 2-Dll-Fehler (s. @extended)
    ; 3-keine Schnittmenge
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _WinAPI_IntersectRect(ByRef $Src1Rect, ByRef $Src2Rect)
    If (Not IsDllStruct($Src1Rect)) Or (Not IsDllStruct($Src2Rect)) Then Return SetError(1,0,0)
    Local $DestRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
    Local $ret = DllCall("user32", "int", "IntersectRect", "ptr", DllStructGetPtr($DestRect), "ptr", DllStructGetPtr($Src1Rect), "ptr", DllStructGetPtr($Src2Rect))
    If @error > 0 Then Return SetError(2,@error,0)
    If $ret[0] > 0 Then
    Return $DestRect
    Else
    Return SetError(3,0,0)
    EndIf
    EndFunc ;==>_WinAPI_IntersectRect

    [/autoit]
  • Mit dem Rectangle komme ich überhaupt nicht zurecht,
    ich habs jetzt mal als eindimensionale Überlappung versucht, aber es funktioniert nicht,
    habe ich irgendwo einen Denkfehler?

    [autoit]


    $pos = ControlGetPos($Form1,"",$Pic1) ;Grafik a
    $x = $pos[0] ;Entfernung von Links
    $y = $pos[1] ;Entfernung von Oben
    $w = $pos[2] ;Breite
    $h = $pos[3] ;Höhe
    $w1 = $w*(1-($k-1)) ;Breite schmälern
    $w2 = $h*(1-($k-1)) ;Höhe schmälern
    $w3 = $w*$k ;verbreitern
    $w4 = $h*$k ;vergrößern
    $pos2 = ControlGetPos($Form1,"",$Pic5) ;Grafik B
    $x2 = $pos[0] ;Entfernung von Links
    $y2 = $pos[1] ;Entfernung von Oben
    $ww = $pos[2] ;Breite
    $hh = $pos[3] ;Höhe
    If (($x < $x2) And (($x + $w) > $x2)) Or (($x2 < $x) And (($x2 + $ww) > $x)) Then
    MsgBox(0,"Treffer","Die beiden Grafiken überlagern sich",1)
    Exit
    EndIf

    [/autoit]
    • Offizieller Beitrag

    Bsp.:

    Spoiler anzeigen
    [autoit]

    #include <WinApi.au3>

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

    Global $tRect1 = DllStructCreate("int Left;int Top;int Right;int Bottom")
    Global $tRect2 = DllStructCreate("int Left;int Top;int Right;int Bottom")

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

    ; Grafik 1
    $left1 = 10
    $top1 = 10
    $right1 = 90 ; left + width
    $bottom1 = 60 ; top + heighth

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

    ; Grafik 2
    $left2 = 85
    $top2 = 55
    $right2 = 135 ; left + width
    $bottom2 = 105 ; top + heighth

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

    _WinAPI_SetRect($tRect1, $left1, $top1, $right1, $bottom1)
    _WinAPI_SetRect($tRect2, $left2, $top2, $right2, $bottom2)

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

    $ret = _WinAPI_IntersectRect($tRect1, $tRect2)
    If Not @error Then
    ConsoleWrite('Schnittmenge:' & @LF & _WinAPI_GetRectValue($ret) & @LF)
    Else
    ConsoleWrite('Keine Schnittmenge' & @LF)
    EndIf

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

    ;===============================================================================
    ; Function Name: _WinAPI_SetRect(ByRef $tRECT, $X1, $Y1, $X2, $Y2)
    ; Description: Befüllt eine RECT-Struktur in einem Aufruf mit Werten
    ; Parameter(s): $tRECT RECT-Struktur
    ; $X1, $Y1, $X2, $Y2 Werte des Rectangle
    ; Return Value(s): Erfolg <> 0
    ; Fehler 0 set @error 1-keine Struktur übergeben
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _WinAPI_SetRect(ByRef $tRECT, $X1, $Y1, $X2, $Y2)
    If Not IsDllStruct($tRECT) Then Return SetError(1,0,0)
    Local $ret = DllCall("user32", 'long', 'SetRect', 'ptr', DllStructGetPtr($tRECT), 'long', $X1, 'long', $Y1, 'long', $X2, 'long', $Y2)
    If @error > 0 Then Return SetError(1,@error,0)
    Return $ret[0]
    EndFunc ;==>_WinAPI_SetRect

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

    ;===============================================================================
    ; Function Name: _WinAPI_GetRectValue(ByRef $tRECT, $bArray=False)
    ; Description: Gibt die Werte einer RECT-Struktur als String(Standard) od. Array zurück
    ; Parameter(s): $tRECT RECT-Struktur, die gelesen werden soll
    ; $fArray Rückgabetyp: False(Standard)=String, True=Array
    ; Return Value(s): Erfolg Werte der RECT-Struktur
    ; Fehler 0 set @error 1-keine Struktur übergeben
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _WinAPI_GetRectValue(ByRef $tRECT, $fArray=False)
    If Not IsDllStruct($tRECT) Then Return SetError(1,0,0)
    Local $sOut = _
    DllStructGetData($tRECT, 1) & ',' & _
    DllStructGetData($tRECT, 2) & ',' & _
    DllStructGetData($tRECT, 3) & ',' & _
    DllStructGetData($tRECT, 4)
    If $fArray Then Return StringSplit($sOut, ',', 2)
    Return $sOut
    EndFunc ;==>_WinAPI_GetRectValue

    [/autoit]


    _WinAPI_IntersectRect() ist inzwischen Bestandteil der WinAPI, brauchst du also nicht extra die Funktion.

  • Funktionen für einige Kollisionsabfragen habe ich mal gesammelt und auf Tempo hin optimiert. (Damals gab es den ternären operator noch nicht, daher kann man sicherlich noch etwas Geschwindigkeit rausholen).
    Klick mich !
    Um zwei rechtecke zu überprüfen gibts das hier:
    Klick Mich !
    (ganz runter scrollen. Der letzte Codeabschnitt ist eine effiziente Kollisionsfunktion)
    Hier die AutoIt Funktion für 2 Rechtecke:

    [autoit]

    Func _Kollision_Viereck_Viereck($x1, $y1, $b1, $h1, $x2, $y2, $b2, $h2) ;Selbsterklärend
    Return ($x1 + $b1 > $x2 And $y1 + $h1 > $y2 And $x1 < $x2 + $b2 And $y1 < $y2 + $h2)
    EndFunc ;==>_Kollision_Viereck_Viereck

    [/autoit]