Schnittfunktion LineRectOverlap

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Mike Nike

Betreff: Schnittfunktion LineRectOverlap

BeitragMo, Feb 02, 2004 18:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Tobi bat mich im Blitzchat (mIRC), ihm bei einem Kollisionsproblem zu helfen. Ich habe den Code nicht optimiert (weder in Übersicht, noch Geschwindigkeit oder in Kürzung...) und unausreichend dokumentiert ^^ - dazu hatte ich jetzt keine Lust mehr...

Habe 5 Beispiele eingefügt.
Um ein Beispiel auszuwählen, einfach in der Zeile
Beispiel=5
den Wert ändern. Viel Erfolg.

Edit:
Sorry, falls es, und da bin ich mir fast sicher, schon solche mathematischen Codeschnipsel hierfür gab, aber ich hatte keine Lust zu suchen und außerdem erfinde ich alles immer wieder gerne neu (also progge es selbst), bevor ich es mir irgendwo abgucke.
By the way: man hätte aus dem Line auch ganz einfach ein Image createn können, auf Maskcolor achten und dann den Befehl ImageRectCollide einsetzen können. Langsamer (glaube ich), aber man hätte den Mathekram umgehen können. Aber jedem das seine...

Code: [AUSKLAPPEN]

;Schnittfunktionen by Mike Nike (16:20 bis 17:20 2.2.2004)
;Dauer der Berechnung: 15 lange Minuten auf Papier *schäm*, hatte lang nicht mehr sowas gemacht.
;Umsetzung: 20 Minuten
;Testen: 10 Minuten
;Debugging: 5 Minuten ->Bugreport: 1x vertippt beim height schreiben (dacht ichs mir doch)
;Rest: Trödelei^^
;Habe an Zeichen nicht gespart, damit man es lesen kann...

Beispiel=6

Select Beispiel
   Case 1
      LineX1=50:LineY1=50
      LineX2=100:LineY2=150
      RectX=75:RectY=25
      RectWidth=100:RectHeight=100
   Case 2
      LineX1=100:LineY1=100
      LineX2=100:LineY2=150
      RectX=75:RectY=25
      RectWidth=100:RectHeight=100
   Case 3
      LineX1=50:LineY1=100
      LineX2=100:LineY2=100
      RectX=75:RectY=25
      RectWidth=100:RectHeight=100
   Case 4
      LineX1=50:LineY1=100
      LineX2=100:LineY2=150
      RectX=75:RectY=25
      RectWidth=100:RectHeight=100
   Case 5
      LineX1=50:LineY1=100
      LineX2=100:LineY2=150
      RectX=85:RectY=15
      RectWidth=100:RectHeight=100
   Case 6
      LineX1=50:LineY1=100
      LineX2=200:LineY2=0
      RectX=85:RectY=15
      RectWidth=100:RectHeight=100
End Select

Line LineX1,LineY1,LineX2,LineY2
Rect RectX,RectY,RectWidth,RectHeight,0

If LineRectOverlap(LineX1,LineY1,LineX2,LineY2,RectX,RectY,RectWidth,RectHeight) Then
   Text 0,0,"Kollision=TRUE"
Else
   DebugLog LineX1+" "+LineY1+" "+LineX2+" "+LineY2+" "+RectX+" "+RectY+" "+RectWidth+" "+RectHeight
   Text 0,0,"Kollision=FALSE"
End If

;Prüfung, ob eine Linie ein Rechteck überlappt
Function LineRectOverlap(x1,y1,x2,y2,x,y,width,height)

   If x1=x2 Then
      ;m ist nicht definiert
      If RectsOverlap(x1,y1,1,y2-y1,x,y,width,height) Then
         DebugLog "Case x1=x2: TRUE"
         Return True
      Else
         DebugLog "Case x1=x2: FALSE"
         Return False
      End If
   Else
         DebugLog "RectsOverlap: TRUE"
         ;Trick: die mathematische Geradengleichung der Line-Strecke wird ermittelt
         ;y=m*x+b;oder y=m*x+c...ist ja egal...
         m#=(y2-y1)/Float(x2-x1)
         b#=y1-m#*x1;oder b=y2-m*x2 oder b=y1-(....)*x1 <-m Berechnungsformel einsetzten
         Ya#=m#*x+b#
         Yb#=m#*(x+width)+b#
         ;hier hätte ich mich beinahe für eine PointRectOverlap-Version entschieden...
         ;aber ich blieb bei meinem ersten Gedanken:
         If ValueInSkala(Ya#,y,y+width) Or ValueInSkala(Yb#,y,y+width) Then
            DebugLog "X-Values in: TRUE"
            Return True
         Else
            DebugLog "X-Values in: FALSE"
            Return False
         End If
   End If

End Function

;Prüft, ob eine Koordinate in einem Rechteck ist
Function PointRectOverlap(x1,y1,x,y,width,height)

   ;Es ginge zwar auch eine Rectsoverlapprüfung, aber so hab ichs lieber...
   If x1>=y And x1<=x+width And y1>=y And y1<=y+height Then
      Return True
   Else
      Return False
   End If
   
End Function

;Prüft ob ein Wert zwischen zwei Werten liegt
Function ValueInSkala(V,V_Start,V_End)

   If V>=V_Start And V<=V_End Then
      Return True
   Else
      Return False
   End If

End Function


Edit2:

Wie man glaube ich erkennen kann, habe ich das Prog nicht ausreichend getestet und Ausnahmefälle habe ich wohl auch nicht ausreichend implementiert bzw. im Code beachtet.

Edit 3:

Habe den Code wurde berichtigt.
Es gibt trotzdem noch Ausnahmen, die bei normalem Rect-Zeichnen auch vorkommen könnten, glaube ich.
..where the only limit is your imagination.
  • Zuletzt bearbeitet von Mike Nike am Di, Feb 03, 2004 0:51, insgesamt 2-mal bearbeitet
 

CodeMaster

BeitragMo, Feb 02, 2004 19:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Funktioniert noch nicht korrekt:
Code: [AUSKLAPPEN]
;Schnittfunktionen by Mike Nike (16:20 bis 17:20 2.2.2004)
;Dauer der Berechnung: 15 lange Minuten auf Papier *schäm*, hatte lang nicht mehr sowas gemacht.
;Umsetzung: 20 Minuten
;Testen: 10 Minuten
;Debugging: 5 Minuten ->Bugreport: 1x vertippt beim height schreiben (dacht ichs mir doch)
;Rest: Trödelei^^
;Habe an Zeichen nicht gespart, damit man es lesen kann...

Beispiel=6

Select Beispiel
Case 1
LineX1=50:LineY1=50
LineX2=100:LineY2=150
RectX=75:RectY=25
RectWidth=100:RectHeight=100
Case 2
LineX1=100:LineY1=100
LineX2=100:LineY2=150
RectX=75:RectY=25
RectWidth=100:RectHeight=100
Case 3
LineX1=50:LineY1=100
LineX2=100:LineY2=100
RectX=75:RectY=25
RectWidth=100:RectHeight=100
Case 4
LineX1=50:LineY1=100
LineX2=100:LineY2=150
RectX=75:RectY=25
RectWidth=100:RectHeight=100
Case 5
LineX1=50:LineY1=100
LineX2=100:LineY2=150
RectX=85:RectY=15
RectWidth=100:RectHeight=100
Case 6
LineX1=50:LineY1=100
LineX2 = 200
LineY2 = 0
RectX=85:RectY=15
RectWidth=100:RectHeight=100
End Select


 Line LineX1,LineY1,LineX2,LineY2
 Rect RectX,RectY,RectWidth,RectHeight,0
 If LineRectOverlap(LineX1,LineY1,LineX2,LineY2,RectX,RectY,RectWidth,RectHeight) Then
 Text 0,0,"Kollision=TRUE"
 Else
 ; DebugLog LineX1+" "+LineY1+" "+LineX2+" "+LineY2+" "+RectX+" "+RectY+" "+RectWidth+" "+RectHeight
 Text 0,0,"Kollision=FALSE"
 End If


;Prüfung, ob eine Linie ein Rechteck überlappt
Function LineRectOverlap(x1,y1,x2,y2,x,y,width,height)

If x1=x2 Then
;m ist nicht definiert
If RectsOverlap(x1,y1,1,y2-y1,x,y,width,height) Then
Return True
Else
Return False
End If
Else
;LineToRect -> Prüfung, ob Line überhaupt Chancen hat, das Rechteck zu treffen...
;anders ginge auch: Prüfung, ob x1 oder x2 im Bereich von x und x+width liegt, aber
;das wird ja dadurch getan...
If RectsOverlap(x1,y1,x2-x1,y2-y1,x,y,width,height) Then
;Trick: die mathematische Geradengleichung der Line-Strecke wird ermittelt
;y=m*x+b;oder y=m*x+c...ist ja egal...
m=(y2-y1)/Float(x2-x1)
b=y1-m*x1;oder b=y2-m*x2 oder b=y1-(....)*x1 <-m Berechnungsformel einsetzten
Ya=m*x+b
Yb=m*(x+width)
;hier hätte ich mich beinahe für eine PointRectOverlap-Version entschieden...
;aber ich blieb bei meinem ersten Gedanken:
If ValueInSkala(Ya,y,y+width) Or ValueInSkala(Yb,y,y+width) Then
Return True
Else
Return False
End If
Else
Return False
End If
End If

End Function

;Prüft, ob eine Koordinate in einem Rechteck ist
Function PointRectOverlap(x1,y1,x,y,width,height)

;Es ginge zwar auch eine Rectsoverlapprüfung, aber so hab ichs lieber...
If x1>=y And x1<=x+width And y1>=y And y1<=y+height Then
Return True
Else
Return False
End If

End Function

;Prüft ob ein Wert zwischen zwei Werten liegt
Function ValueInSkala(V,V_Start,V_End)

If V>=V_Start And V<=V_End Then
Return True
Else
Return False
End If

End Function
Dabei habe ich folgende Werte ausprobiert:Code: [AUSKLAPPEN]
LineX1=50:LineY1=100
LineX2 = 200
LineY2 = 0
RectX=85:RectY=15
RectWidth=100:RectHeight=100
Dies ist ein Text, der an jeden Beitrag von dir angehängt werden kann. Es besteht eine Limit von 500 Buchstaben.

Zuletzt bearbeitet von CodeMaster am Mo Apr 01, Parse error: syntax error, unexpected ';' in htdocs\viewtopic.php on line 102

Mike Nike

BeitragMo, Feb 02, 2004 23:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube ich tüftle gerade nochmal was daran herum.
Ich schätze, dass zum Beispiel "m" Floatwerte geINTed hat.

Edit:

Ok, habe den Code upgedated -> siehe Post 1 in diesem Thread und Edit 3.
..where the only limit is your imagination.

Markus2

BeitragDi, Feb 03, 2004 0:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Es ginge zwar auch eine Rectsoverlapprüfung, aber so hab ichs lieber...
If x1>=y And x1<=x+width And y1>=y And y1<=y+height Then
Return True
Else
Return False
End If

= so ? ... 3 änderungen Smile

Es ginge zwar auch eine Rectsoverlapprüfung, aber so hab ichs lieber...
If x1>=x And x1<x+width And y1>=y And y1<y+height Then
Return True
Else
Return False
End If

Mike Nike

BeitragDi, Feb 03, 2004 15:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiss nicht genau, was du damit andeuten willst, aber du musst wissen, genau das war die Ursache für meinen fehlerhaften Code.
Also, ich hatte genau diese RectsOverlapprüfung schon eingebaut.
Du siehst sie noch in codemasters Reply, der meinen ersten Code kopierte und Beispiel 6 dranhing.
Ich aber habe gestern meinen 1.Post etwas verbessert und die RectsOverlap-Prüfung rausgenommen.

Eine alleinige RectsOverlapprüfung bringt nämlich nichts.
Es reicht die mathematische "Angelegenheit"...
Schau dir mal "Codemasters" Code an und teste die Beispiele durch und dann meinen neuen Code in Post 1. Musst aber nicht...
Fakt ist nämlich, dass die Line das Rect zwar mit RectsOverlap überlappen könnte, aber die Line selbst ist so schräg angelegt, dass sie das Rect eigentlich gar nicht berührt, sondern nur knapp verfehlt.
..where the only limit is your imagination.
 

blitzatius

BeitragSo, Jan 08, 2006 21:08
Antworten mit Zitat
Benutzer-Profile anzeigen
https://www.blitzforum.de/view...highlight=

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group