Ich komm einfach nicht weiter
Ich will überprüfen ob eine Linie von der ich Anfangs - und Endpunkt habe , ein Rechteck schneidet (Quadrat).
Linie schneidet Rechteck ?
-
- [ gelöst ]
-
nof@ker2 -
4. August 2010 um 21:40 -
Geschlossen -
Erledigt
-
-
Hey, vorhin hatte ich mal Zeit.
Spoiler anzeigen
[autoit]#include <GuiConstantsEx.au3>
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
#include <GDIPlus.au3>
#include <array.au3>$hGUI = GUICreate("GDI+", 400, 300, 100)
[/autoit] [autoit][/autoit] [autoit]
GUISetState()_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI);#################### EXAMPLE 1
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsDrawLine($hGraphic, 10, 75, 100, 80)
_GDIPlus_GraphicsDrawRect($hGraphic, 30, 20, 50, 50)$Koords1 = _GetPixelOfLineRectIntercept(10, 75, 100, 80, 30, 20, 50, 50)
[/autoit] [autoit][/autoit] [autoit]If $Koords1[0][0] = True Then
[/autoit] [autoit][/autoit] [autoit]
$hBrushRed = _GDIPlus_BrushCreateSolid(0xFFFF0000)
_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords1[1][0] - 2, $Koords1[1][1] - 2, 4, 4)
_GDIPlus_GraphicsFillPie($hGraphic, $Koords1[1][0] - 2, $Koords1[1][1] - 2, 4, 4, 0, 360, $hBrushRed)_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords1[2][0] - 2, $Koords1[2][1] - 2, 4, 4)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsFillPie($hGraphic, $Koords1[2][0] - 2, $Koords1[2][1] - 2, 4, 4, 0, 360, $hBrushRed)
EndIf
_ArrayDisplay($Koords1)
;####################;#################### EXAMPLE 2
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsDrawLine($hGraphic, 260, 100, 300, 50)
_GDIPlus_GraphicsDrawRect($hGraphic, 250, 20, 30, 70)$Koords2 = _GetPixelOfLineRectIntercept(260, 100, 300, 50, 250, 20, 30, 70)
[/autoit] [autoit][/autoit] [autoit]If $Koords2[0][0] = True Then
[/autoit] [autoit][/autoit] [autoit]
$hBrushRed = _GDIPlus_BrushCreateSolid(0xFFFF0000)
_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords2[1][0] - 2, $Koords2[1][1] - 2, 4, 4)
_GDIPlus_GraphicsFillPie($hGraphic, $Koords2[1][0] - 2, $Koords2[1][1] - 2, 4, 4, 0, 360, $hBrushRed)_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords2[2][0] - 2, $Koords2[2][1] - 2, 4, 4)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsFillPie($hGraphic, $Koords2[2][0] - 2, $Koords2[2][1] - 2, 4, 4, 0, 360, $hBrushRed)
EndIf
_ArrayDisplay($Koords2)
;####################;#################### EXAMPLE 3
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsDrawLine($hGraphic, 210, 180, 270, 260)
_GDIPlus_GraphicsDrawRect($hGraphic, 150, 190, 150, 50)$Koords3 = _GetPixelOfLineRectIntercept(210, 180, 270, 260, 150, 190, 150, 50)
[/autoit] [autoit][/autoit] [autoit]If $Koords3[0][0] = True Then
[/autoit] [autoit][/autoit] [autoit]
$hBrushRed = _GDIPlus_BrushCreateSolid(0xFFFF0000)
_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords3[1][0] - 2, $Koords3[1][1] - 2, 4, 4)
_GDIPlus_GraphicsFillPie($hGraphic, $Koords3[1][0] - 2, $Koords3[1][1] - 2, 4, 4, 0, 360, $hBrushRed)_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords3[2][0] - 2, $Koords3[2][1] - 2, 4, 4)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsFillPie($hGraphic, $Koords3[2][0] - 2, $Koords3[2][1] - 2, 4, 4, 0, 360, $hBrushRed)
EndIf
_ArrayDisplay($Koords3)_GDIPlus_GraphicsDrawLine($hGraphic, 120, 210, 320, 220)
[/autoit] [autoit][/autoit] [autoit]$Koords4 = _GetPixelOfLineRectIntercept(120, 210, 320, 220, 150, 190, 150, 50)
[/autoit] [autoit][/autoit] [autoit]If $Koords4[0][0] = True Then
[/autoit] [autoit][/autoit] [autoit]
$hBrushRed = _GDIPlus_BrushCreateSolid(0xFFFF0000)
_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords4[1][0] - 2, $Koords4[1][1] - 2, 4, 4)
_GDIPlus_GraphicsFillPie($hGraphic, $Koords4[1][0] - 2, $Koords4[1][1] - 2, 4, 4, 0, 360, $hBrushRed)_GDIPlus_GraphicsDrawEllipse($hGraphic, $Koords4[2][0] - 2, $Koords4[2][1] - 2, 4, 4)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsFillPie($hGraphic, $Koords4[2][0] - 2, $Koords4[2][1] - 2, 4, 4, 0, 360, $hBrushRed)
EndIf
_ArrayDisplay($Koords4)
;####################Do
[/autoit] [autoit][/autoit] [autoit]
Until GUIGetMsg() = $GUI_EVENT_CLOSE_GDIPlus_GraphicsDispose($hGraphic)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_Shutdown()Func _GetPixelOfLineRectIntercept($iLineX1, $iLineY1, $iLineX2, $iLineY2, $iRectX, $IRectY, $IRectW, $iRectH)
[/autoit] [autoit][/autoit] [autoit]
Local $iVals[16] = [$iRectX, $iRectX + $IRectW, $IRectY, 0, $IRectY, $IRectY + $iRectH, $iRectX, 1, $iRectX, $iRectX + $IRectW, $IRectY + $iRectH, 0, $IRectY, $IRectY + $iRectH, $iRectX + $IRectW, 1]
Dim $aArray[2], $aFoundArray[3][2]
If $iLineX1 >= $iLineX2 And $iLineY1 >= $iLineY2 Then ; RECHTS UNTEN
$xAbstand = $iLineX1 - $iLineX2
$yAbstand = $iLineY1 - $iLineY2
If $yAbstand > $xAbstand Then
For $j = 1 To $yAbstand Step +1
ReDim $aArray[$yAbstand + 1]
$aArray[$j] = ($iLineY1) - $j & ";" & Round(($iLineX1) - $j * ($xAbstand / $yAbstand))
Next
Else
For $j = 1 To $xAbstand Step +1
ReDim $aArray[$xAbstand + 1]
$aArray[$j] = ($iLineX1) - $j & ";" & Round(($iLineY1) - $j * ($yAbstand / $xAbstand))
Next
EndIf
ElseIf $iLineX1 < $iLineX2 And $iLineY1 > $iLineY2 Then ; LINKS UNTEN
$xAbstand = $iLineX2 - $iLineX1
$yAbstand = $iLineY1 - $iLineY2
If $yAbstand > $xAbstand Then
For $j = 1 To $yAbstand Step +1
ReDim $aArray[$yAbstand + 1]
$aArray[$j] = Round(($iLineX1) + $j * ($xAbstand / $yAbstand)) & ";" & ($iLineY1) - $j
Next
Else
For $j = 1 To $xAbstand Step +1
ReDim $aArray[$xAbstand + 1]
$aArray[$j] = ($iLineX1) + $j & ";" & Round(($iLineY1) - $j * ($yAbstand / $xAbstand))
Next
EndIf
ElseIf $iLineX1 > $iLineX2 And $iLineY1 < $iLineY2 Then ; RECHTS OBEN
$xAbstand = $iLineX1 - $iLineX2
$yAbstand = $iLineY2 - $iLineY1
If $yAbstand > $xAbstand Then
For $j = 1 To $yAbstand Step +1
ReDim $aArray[$yAbstand + 1]
$aArray[$j] = Round(($iLineX1) - $j * ($xAbstand / $yAbstand)) & ";" & ($iLineY1) + $j
Next
Else
For $j = 1 To $xAbstand Step +1
ReDim $aArray[$xAbstand + 1]
$aArray[$j] = ($iLineX1) - $j & ";" & Round(($iLineY1) + $j * ($yAbstand / $xAbstand))
Next
EndIf
ElseIf $iLineX1 <= $iLineX2 And $iLineY1 <= $iLineY2 Then ; LINKS OBEN
$xAbstand = $iLineX2 - $iLineX1
$yAbstand = $iLineY2 - $iLineY1
If $yAbstand > $xAbstand Then
For $j = 1 To $yAbstand Step +1
ReDim $aArray[$yAbstand + 1]
$aArray[$j] = Round(($iLineX1) + $j * ($xAbstand / $yAbstand)) & ";" & ($iLineY1) + $j
Next
Else
For $j = 1 To $xAbstand Step +1
ReDim $aArray[$xAbstand + 1]
$aArray[$j] = ($iLineX1) + $j & ";" & Round(($iLineY1) + $j * ($yAbstand / $xAbstand))
Next
EndIf
EndIf
$aFoundArray[0][0] = False
For $k = 0 To 15 Step +4
Local $Val
$Val = _CalcRect($iVals[$k], $iVals[$k + 1], $iVals[$k + 2], $iVals[$k + 3], $aArray)
If $aFoundArray[1][0] = '' And $Val <> '' Then
$aFoundArray[1][0] = $Val[0]
$aFoundArray[1][1] = $Val[1]
ElseIf $aFoundArray[2][0] = '' And $Val <> '' Then
$aFoundArray[2][0] = $Val[0]
$aFoundArray[2][1] = $Val[1]
EndIf
Next
If $aFoundArray[1][0] <> "" And $aFoundArray[2][0] <> "" Then $aFoundArray[0][0] = True
Return $aFoundArray
EndFunc ;==>_GetPixelOfLineRectInterceptFunc _CalcRect($iVar1, $iVar2, $iVar3, $iMode, $aArray)
[/autoit]
Local $aCalcArray[2]
For $i = $iVar1 To $iVar2
For $j = 1 To UBound($aArray) - 1
If $iMode = 0 Then
If $aArray[$j] = $i & ";" & $iVar3 Then
Local $aCalcArray[2] = [$i, $iVar3]
Return $aCalcArray
EndIf
ElseIf $iMode = 1 Then
If $aArray[$j] = $iVar3 & ";" & $i Then
Local $aCalcArray[2] = [$iVar3, $i]
Return $aCalcArray
EndIf
EndIf
Next
Next
Return ''
EndFunc ;==>_CalcRect -
- Offizieller Beitrag
Versuche es mit der folgenden Funktion. Verwende RECT-Strukturen für das Quadrat und die Gerade (Höhe 1).
[autoit];===============================================================================
[/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 -
Da gibts schon ne Func dazu :E? Auch recht^^ Meine ist eh langsam.
-
BugFix : Könntest du mir schnell noch sagen wie ich die RECT Struktur für die Gerade erstelle ? (Quadrat hab ich hinbekommen ;))
-
Die Funktion schneidet 2 Rechtecke, nicht Rechteck und Linie. Da braucht man etwas Mathe
-
- Offizieller Beitrag
Da die Linie Höhe 1 hat ergibt das also ein RECT mit Höhe 1. Somit kann die Schnittfunktion genutzt werden.
Für die Gerade:
Spoiler anzeigen
[autoit]; Bsp-Daten:
[/autoit] [autoit][/autoit] [autoit]Local $lineX = 50
[/autoit] [autoit][/autoit] [autoit]
Local $lineLen = 120
Local $lineY = 20
Local $lineRECT = DllStructCreate("int Left;int Top;int Right;int Bottom")_WinAPI_SetRect($lineRECT, $lineX, $lineY, $lineX + $lineLen, $lineY +1)
[/autoit] [autoit][/autoit] [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 -
Was ist mit schiefen Linien? Die senkrechten und waagrechten sind ja einfach
-
- Offizieller Beitrag
Was ist mit schiefen Linien? Die senkrechten und waagrechten sind ja einfach
Alter Spielverderber :D, aber ich hab immer irgendwie an Gerade gedacht.
Gibt aber 'ne Variante: In einer Schleife jeden Punkt der Linie mit _WinAPI_PtInRect abprüfen. -
Das sollte funktionieren, ich habs nicht getestet.
Benötigt werden:
oberer linker Punkt der Linie,
unterer rechter Punkt der Linie
oberer linker Punkt des Rechtecks,
unterer rechter Punkt des Rechtecks.Spoiler anzeigen
[autoit]Func _IntersectLineRect($iLineX1, $iLineY1, $iLineX2, $iLineY2, $iRectX1, $iRectY1, $iRectX2, $iRectY2)
[/autoit] [autoit][/autoit] [autoit]
; Author: ProgAndy; Geradengleichung aus 2 Punkten y = mx + c:
Local $tmp
If $iLineX1 > $iLineX2 Then
$tmp = $iLineX1
$iLineX1 = $iLineX2
$iLineX2 = $tmp
EndIf
If $iLineY1 > $iLineY2 Then
$tmp = $iLineX1
$iLineY1 = $iLineY2
$iLineY2 = $tmp
EndIf
If $iRectX1 > $iRectX2 Then
$tmp = $iRectX1
$iRectX1 = $iRectX2
$iRectX2 = $tmp
EndIf
If $iRectY1 > $iRectY2 Then
$tmp = $iRectX1
$iRectY1 = $iRectY2
$iRectY2 = $tmp
EndIf; Geradengleichung aus 2 Punkten y = mx + c:
[/autoit] [autoit][/autoit] [autoit]
Local $tmp = ($iLineX2 - $iLineX1), $m = 0
If Not ($tmp = 0) Then $m = ($iLineY2 - $iLineY1)/$tmp ; Wenn nicht senkrecht, Steigung berechnen
If $m = 0 Then ; Gerade waagrecht oder senkrecht
If $iLineY1 >= $iRectY1 And $iLineY1 <= $iRectY2 And $iLineX1 <= $iRectX2 And $iLineX2 >= $iRectX1 Then
Return True
EndIf
Return False
EndIfLocal $c = $iLineY1 - ($m*$iLineX1), $x
[/autoit] [autoit][/autoit] [autoit]; schnitt mit waagrechten
[/autoit] [autoit][/autoit] [autoit]
; x-Wert für $iRectY1
$x = ($iRectY1 -$c)/$m
If $x >= $iRectX1 And $x <= $iRectX2 Then Return True
; x-Wert für $iRectY2
$x = ($iRectY2 -$c)/$m
If $x >= $iRectX1 And $x <= $iRectX2 Then Return True; schnitt mit Snkerechten
[/autoit] [autoit][/autoit] [autoit]
; y-Wert für $iRectX1
$x = $m * $iRectX1 + $c
If $x >= $iRectY1 And $x <= $iRectY2 Then Return True
; y-Wert für $iRectX2
$x = $m * $iRectX2 + $c
If $x >= $iRectY1 And $x <= $iRectY2 Then Return TrueReturn False
[/autoit]
EndFuncPS: Die Schnittpunkte werden nicht berechnet.
-
Danke Prog@ndy , deine Funktion löst das Problem perfekt
-
Ich habe dann doch nochmal ein kleines Problem
Ist es auch noch möglich die Schnittpunkte herauszufinden ? -
Klar Eine Frage hätte ich noch. Suchst du Schnittpunkte auf der ganzen Geraden durch die zwei Punkte oder nur in dem Segment wischen den zwei Punkten?
PS: Die bisherige Funktion berechnet nicht korrekt. Bei schiefen Segmenten wird auch ein Schnitt erkannt, wenn sich die Gerade durch die beiden Punkte schneidet. Das ist wohl nicht so gewollt, oder?
-
Ich suche die Schnittpunkte nur in dem Segment zwischen den beiden Punkten
PS: Nein das ist nicht so gewollt.
-
Also verwende sie besser nicht. Hab inzwischen noch mehr Bugs gefunden ... War wohl zu spät.
Edit: Also warte lieber nicht auf die Funktion, das ist echt einiges zum Rechnen, lauter Sonderfälle, wenn man die Koordinaten bestimmen will. (oder denke ich nur zu kompliziert?)
-
Zitat
(oder denke ich nur zu kompliziert?)
Diese Frage habe ich mir auch schon gestellt. Eigentlich hört sich das ganze ja nicht schwer an , aber die Umsetzung ist mehr als kompliziert. -
Den Schnitt grundsätzlich hab ich schon zusammen, nur gibt es noch Probleme mit dem berechnen der
SchnitpunkteSchnittsegmente.
Wenn nur die Punkte auf den Rechteckkanten gesucht sind, wird es einfacher, das hätte ich jetzt innerhalb von 5 Minuten fertig.Edit: Das ist mein aktueller Stand, bitte teste mal mit möglichst vielen unterschiedlichen Kombinationen, die dir einfallen. Ich hoffe, dass ich alles berücksichtigt habe.
Spoiler anzeigen
[autoit]Func _IntersectLineSegmentRect($iLineX1, $iLineY1, $iLineX2, $iLineY2, $iRectX1, $iRectY1, $iRectX2, $iRectY2)
[/autoit] [autoit][/autoit] [autoit]
; Author: ProgAndy
Local $tmp, $aResult[2][2]
;==================================================================================================
; Vorbereitung: Punkt sortieren, falls nicht richtig angegeben
;--------------------------------------------------------------------------------------------------
If $iLineX1 > $iLineX2 Then
$tmp = $iLineX1
$iLineX1 = $iLineX2
$iLineX2 = $tmp
$tmp = $iLineY1
$iLineY1 = $iLineY2
$iLineY2 = $tmp
EndIf
If $iRectX1 > $iRectX2 Then
$tmp = $iRectX1
$iRectX1 = $iRectX2
$iRectX2 = $tmp
EndIf
If $iRectY1 > $iRectY2 Then
$tmp = $iRectY1
$iRectY1 = $iRectY2
$iRectY2 = $tmp
EndIf;==================================================================================================
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
; Fall 1: Segment komplett im Rechteck
;--------------------------------------------------------------------------------------------------
If $iLineY1 >= $iRectY1 And $iLineY1 <= $iRectY2 And $iLineX1 <= $iRectX2 And $iLineX1 >= $iRectX1 And _
$iLineY2 >= $iRectY1 And $iLineY2 <= $iRectY2 And $iLineX2 <= $iRectX2 And $iLineX2 >= $iRectX1 Then ; beide Punkte im Kasten
Local $aResult[2][2] = [ [$iLineX1, $iLineY1], [$iLineX2, $iLineY2]]
Return $aResult
EndIf;==================================================================================================
[/autoit] [autoit][/autoit] [autoit]
; Fall 2: Segment senkrecht oder waagrecht
;--------------------------------------------------------------------------------------------------
; Geradengleichung aus 2 Punkten y = mx + c:
Local $dst = ($iLineX2 - $iLineX1), $m = 0
If Not ($dst = 0) Then $m = ($iLineY2 - $iLineY1)/$dst ; Wenn nicht senkrecht, Steigung berechnen
If $m = 0 Then ; Gerade waagrecht oder senkrecht
If $iLineY1 > $iLineY2 Then ; jetzt kann man tauschen, das interessiert bei senkrechten oder waagrechten Linien nicht.
$tmp = $iLineY1
$iLineY1 = $iLineY2
$iLineY2 = $tmp
EndIf
If $iLineY2 >= $iRectY1 And $iLineY1 <= $iRectY2 And $iLineX1 <= $iRectX2 And $iLineX2 >= $iRectX1 Then
If $dst = 0 Then ; senkrechte Linie
Dim $aResult[2][2] = [ [$iLineX1, $iRectY1], [$iLineX1, $iRectY2] ]
If $iLineY1 > $iRectY1 Then $aResult[0][1] = $iLineY1 ; Die Fälle abdecken, in denen die Linie nicht durch das ganze Rechteck geht
If $iLineY2 < $iRectY2 Then $aResult[1][1] = $iLineY2
Else ; waagrechte Linie
Dim $aResult[2][2] = [ [$iRectX1, $iLineY1], [$iRectX2, $iLineY1] ]
If $iLineX1 > $iRectX1 Then $aResult[0][1] = $iLineX1 ; Die Fälle abdecken, in denen die Linie nicht durch das ganze Rechteck geht
If $iLineX2 < $iRectX2 Then $aResult[1][1] = $iLineX2
EndIf
Return $aResult
;~ Return True
EndIf
Return False
EndIf;==================================================================================================
[/autoit] [autoit][/autoit] [autoit]
; Fall 3: Segment schief
;--------------------------------------------------------------------------------------------------
Local $c = $iLineY1 - ($m*$iLineX1), $x1, $x2, $y1, $y2, $ok=0
; schnitt mit waagrechten
; x-Wert für $iRectY1
$x1 = ($iRectY1 -$c)/$m
If $x1 >= $iRectX1 And $x1 < $iRectX2 And $x1 >= $iLineX1 And $x1 <= $iLineX2 Then
$aResult[$ok][0] = Round($x1, 15)
$aResult[$ok][1] = $iRectY1
$ok += 1
EndIf
; x-Wert für $iRectY2
$x2 = ($iRectY2 -$c)/$m
If $x2 >= $iRectX1 And $x2 < $iRectX2 And $x2 >= $iLineX1 And $x2 <= $iLineX2 Then
$aResult[$ok][0] = Round($x2, 15)
$aResult[$ok][1] = $iRectY2
$ok += 1
If $ok = 2 Then Return $aResult
EndIf; schnitt mit Senkrechten
[/autoit] [autoit][/autoit] [autoit]
; y-Wert für $iRectX1
$y1 = $m * $iRectX1 + $c
If $y1 > $iRectY1 And $y1 < $iRectY2 And (($y1 >= $iLineY1 And $y1 <= $iLineY2) Or ($y1 <= $iLineY1 And $y1 >= $iLineY2)) Then
$aResult[$ok][0] = $iRectX1
$aResult[$ok][1] = Round($y1, 15)
$ok += 1
If $ok = 2 Then Return $aResult
EndIf
; y-Wert für $iRectX2
$y2 = $m * $iRectX2 + $c
If $y2 >= $iRectY1 And $y2 <= $iRectY2 And (($y2 >= $iLineY1 And $y2 <= $iLineY2) Or ($y2 <= $iLineY1 And $y2 >= $iLineY2)) Then
$aResult[$ok][0] = $iRectX2
$aResult[$ok][1] = Round($y2, 15)
$ok += 1
If $ok = 2 Then Return $aResult
EndIf;==================================================================================================
[/autoit] [autoit][/autoit] [autoit]
; Fall 4: Nur ein Schnittpunkt mit Rechteckkanten
;--------------------------------------------------------------------------------------------------
If $ok = 1 Then ; Die Linie hört im Rechteck auf oder berührt nur
; Punkt 1 der Linie testen:If $iLineY1 >= $iRectY1 And $iLineY1 <= $iRectY2 And $iLineX1 <= $iRectX2 And $iLineX1 >= $iRectX1 Then ; Punkt 1 ist im Kasten
[/autoit] [autoit][/autoit] [autoit]
; Wenn der Punkt schon gefunden wurde, testen, ob der 2. Punkt auch drin liegt, sollte eigentlich schon per Fall 1 gelöst sein
If $aResult[0][0] = $iLineX1 And $aResult[0][1] = $iLineY1 And $iLineY2 >= $iRectY1 And $iLineY2 <= $iRectY2 And $iLineX2 <= $iRectX2 And $iLineX2 >= $iRectX1 Then ; Punkt ist im Kasten
$aResult[1][0] = $iLineX2
$aResult[1][1] = $iLineY2
Else ; Wenn der 2. Punkt nicht im REchteck liegt, dann ist das ein Berührpunkt, also doppelte Rückgabe
$aResult[1][0] = $iLineX1
$aResult[1][1] = $iLineY1
EndIf
ElseIf $iLineY2 >= $iRectY1 And $iLineY2 <= $iRectY2 And $iLineX2 <= $iRectX2 And $iLineX2 >= $iRectX1 Then ; Punkt 2 ist im Kasten
$aResult[1][0] = $iLineX2
$aResult[1][1] = $iLineY2
EndIfIf $aResult[0][0] > $aResult[1][0] Then ; X-Wert des 1. Punkts ist größer als vom zweiten. Also vertauschen
[/autoit] [autoit][/autoit] [autoit]
$tmp = $aResult[1][0]
$aResult[1][0] = $aResult[0][0]
$aResult[0][0] = $tmp$tmp = $aResult[1][1]
[/autoit] [autoit][/autoit] [autoit]
$aResult[1][1] = $aResult[0][1]
$aResult[0][1] = $tmp
EndIf
Return $aResultEndIf
[/autoit] [autoit][/autoit] [autoit]; kein Schnitt
[/autoit]
Return False
EndFunc
Edit: Funktion besser kommentiert und noch ein paar Sachen geändert.