Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Überprüfung, ob sich Rechtecke schneiden (https://www.delphipraxis.net/94879-ueberpruefung-ob-sich-rechtecke-schneiden.html)

Nikolas 27. Jun 2007 15:35


Überprüfung, ob sich Rechtecke schneiden
 
Hallo

Ich bin gerade auf der Suche nach einer schnellen Lösung für folgendes Problem:

Ich habe ein ruhendes Rechteck, dessen Kanten parallel zu den Achsen liegen. Ein anderes Rechteck liegt irgendwie gedreht im Raum. Die Frage ist jetzt, ob sie sich beühren.

Eine Möglichkeit wäre natürlich alle Kanten des einen mit allen Kanten des anderen zu schneiden und auf schnittpunkt im richtigen Bereich zu testen. Nur ist das etwas aufwändig. Später soll das ganze in einem Spiel laufen, von da her Suche ich besonders nach einer perfomanten Lösung. Weiss da jemand etwas schnelleres?

Nikolas

Robert Marquardt 27. Jun 2007 15:47

Re: Überprüfung, ob sich Rechtecke schneiden
 
Game mit OpenGL bzw. DirectX? Wenn ja dann sollte es da passende Funktionen geben. Vierecke sind zwei aneinanderliegende Dreiecke. Dafuer gibt es bestimmt Schnitttestfunktionen.

Nikolas 27. Jun 2007 15:51

Re: Überprüfung, ob sich Rechtecke schneiden
 
Nein, Game mit C++ :)

Alles reine Handarbeit :mrgreen:

DGL-luke 27. Jun 2007 16:05

Re: Überprüfung, ob sich Rechtecke schneiden
 
Hallo,

projiziere die Rechtecke zuerst auf eine 2-dimensionale ebene (z.B. indem du sie "von oben" ansiehst, du kannst dann einfach die z-koords untern tisch fallen lassen).

Benutze dann MSDN-Library durchsuchenIntersectRect. Wenn du damit keine Kollision erkennst, gibts auch keine. Wenn doch, musst du das ganze nochmal 3-dimensional prüfen, bzw. prüfen, ob es in einer der anderen ebenen (yz und xz) auch kollisionen gibt (bei einem rechteck mit höhe = 1 bzw. 0 kannst du dann davon ausgehen, dass eine kollision genau dann stattfindet, wenn du in allen drei ebenen eine erkennst, glaube ich... :gruebel: )

shmia 27. Jun 2007 16:57

Re: Überprüfung, ob sich Rechtecke schneiden
 
Zitat:

Zitat von DGL-luke
Benutze dann MSDN-Library durchsuchenIntersectRect.

Hier werden aber Rechtecke erwartet, die rechtwinklig zum Koordinatensystem liegen. Zumindest ein Rechteck tut dies nicht.

@Nikolas oder Admin: bitte Thema ändern nach: Überprüfung, ob Quader sich schneiden.

DGL-luke 27. Jun 2007 17:06

Re: Überprüfung, ob sich Rechtecke schneiden
 
...trotzdem funktioniert mein ansatz. und ich denke, Nikolas spricht von Rechtecken.

shmia 27. Jun 2007 17:11

Re: Überprüfung, ob sich Rechtecke schneiden
 
Zitat:

Zitat von DGL-luke
und ich denke, Nikolas spricht von Rechtecken.

> Ein anderes Rechteck liegt irgendwie gedreht im Raum
"Gedreht im Raum" deutet für mich auf 3 Dimensionen hin. Er soll sich halt erklären, ob es 2 oder 3 Dimensionen sind.

OregonGhost 27. Jun 2007 17:27

Re: Überprüfung, ob sich Rechtecke schneiden
 
Zitat:

Später soll das ganze in einem Spiel laufen, von da her Suche ich besonders nach einer perfomanten Lösung.
Wenn es um Performance geht, kannst du auch einfach 99% aller Fälle abfangen, indem du zunächst prüfst, ob sich die Bounding Boxes (die parallel zu den Achsen ausgerichtet sind) überschneiden, und nur in dem Fall eine genaue Prüfung vornimmst (alternativ auch Bounding Circles, das könnte bei gedrehten Rechtecken sogar besser sein). Denk daran, dass es bei dem Gedanken der Performance-Optimierung nicht unbedingt immer darum geht, einen zeitaufwändigen Vorgang etwas schneller zu machen, sondern häufiger, ihn von vornherein zu vermeiden.

DGL-luke 27. Jun 2007 17:38

Re: Überprüfung, ob sich Rechtecke schneiden
 
auch ein rechteck kann im raum liegen, auch "gedreht"...

Nikolas 28. Jun 2007 08:51

Re: Überprüfung, ob sich Rechtecke schneiden
 
Es geht um den 2-Dimensionalen Raum, in dem sich mein Spiel bewegt. Entschuldigt bitte die Ungenauigkeit. (Wobei: Wer hat schon mal in einem Spiel Rechtecke in einem 3D-Raum gesehen, die geschnitten werden müssen? Klingt etwas nach Autoscooter mit fliegenden Teppichen :) )

Das mit dem Boundingcircle hört sich gut an. Als Vorprüfung werde ich das einführen. Eine schnelle Lösung dahinter wär aber auch gut

jfheins 28. Jun 2007 10:38

Re: Überprüfung, ob sich Rechtecke schneiden
 
Du kannst das Problem vereinfachen: Prüfe für jeden der 8 Punkte, ob er sich im jeweils anderen Rechteck befindet. Falls das bei einem der Fall ist, schneiden sie sich. Falls das bei allen nicht der fall ist, schneiden sie sich nicht. (gibt es nicht sogar ein PtInRect Funktion?)
Ob das die performateste Lösung ist, weis ich jetzt nicht, aber nach den bounding circles dürften ja eh nicht mehr soviele berechnungen gemacht werden ;)

DGL-luke 28. Jun 2007 10:43

Re: Überprüfung, ob sich Rechtecke schneiden
 
oh, damit stellt sich das Problem natürlich ganz anders dar. Mit in der HInsicht gedrehten Sachen hatte ich nicht gerechnet.

Nikolas 28. Jun 2007 12:05

Re: Überprüfung, ob sich Rechtecke schneiden
 
Zitat:

Du kannst das Problem vereinfachen: Prüfe für jeden der 8 Punkte, ob er sich im jeweils anderen Rechteck befindet. Falls das bei einem der Fall ist, schneiden sie sich. Falls das bei allen nicht der fall ist, schneiden sie sich nicht.
Leider auch nicht. Leg mal ein langes Lineal auf ein Blatt Papier, so dass keine Ecke des Papiers bedeckt ist.

Zitat:

Mit in der HInsicht gedrehten Sachen hatte ich nicht gerechnet.
Alles andere ist trivial, da hätte ich kein Problem..

Hawkeye219 28. Jun 2007 19:18

Re: Überprüfung, ob sich Rechtecke schneiden
 
Hallo Nikolas,

wenn du keine rein mathematische Lösung mehr findest, kannst du auch auf die Regionen-Befehle der WinAPI ausweichen:

Delphi-Quellcode:
function RectPolygonIntersect (const R: TRect; const P: array of TPoint): Boolean;
var
  RectRgn : HRGN;
  PolyRgn : HRGN;
begin
  RectRgn := CreateRectRgnIndirect(R);
  PolyRgn := CreatePolygonRgn(P[0], Length(P), WINDING);
  Result := (CombineRgn(RectRgn, RectRgn, PolyRgn, RGN_AND) <> NULLREGION);
  DeleteObject(PolyRgn);
  DeleteObject(RectRgn);
end;
Sollte sich diese Lösung als zu langsam erweisen, hilft vielleicht ein vorgeschalteter BoundingBox-Test, so wie es bereits in den vorigen Beiträgen vorgeschlagen wurde.

Gruß Hawkeye

Clobber the mob 29. Jun 2007 08:12

Re: Überprüfung, ob sich Rechtecke schneiden
 
Delphi-Quellcode:
procedure blub (...);
var
  Overlay: TRect;

begin
if IntersectRect (Overlay, Rect1.BoundsRect, Rect2.BoundsRect) then
  begin
   .
   .
   .
  end;
end;
Wär das ne Möglichkeit=?

Nikolas 29. Jun 2007 09:25

Re: Überprüfung, ob sich Rechtecke schneiden
 
Ich hab heute keinen Windowsrechner, von da her kann ich zu dem Intersect Rect nichts sagen. Könnte vielleicht jemand den Quellcode oder wenigstens den HilfeEintrag hier posten.
// Ich hab die Hilfe gefunden. Die Funktion erwartet Rechtecke, deren Achsen parallel zu den Koordinatenachsen sind. Deswegen hilft mir die Funktion überhaupt nicht.


Als kleine Fiesigkeit der Tutoren darf ich mein geliebtes Pascal nicht einsetzen, sondern muss C++ schreiben, so dass ich die Funktion umschreiben müsste.

Nikolas 1. Jul 2007 13:36

Re: Überprüfung, ob sich Rechtecke schneiden
 
Hier mal meine Lösung:

Mit dem Drehwinkel des zweiten Rechtecks kann ich die unterste Ecke bestimmen (oder auch die untersten Ecken im Fall von z.B. winkel=0)
Wenn dann z.B. die y-Komponente der Geschwindigkeit kleiner als Null ist, schneide ich die Halbgerade, die entsteht, wenn ich den Richtungsvektor an die unterste Ecke hänge, mit der oberen Kante meines stehenden Rechtecks.

Wenn aber die y-Komponente positiv ist, schneide ich die übernachste Ecke nach der untersten mit der unteren Seite des stehenden Rechtecks.

Egal wie zweite Rechteck gedreht ist, schneide ich maximal 4 halbgeraden. (z.B. dann wenn das Rechteck nicht gedreht ist und von oben links auf das stehende prallt. Dann kann die untere linke und rechts ecke mit der oberen kante zusammenstoßen, aber auch die rechte obere und untere mit der linken Seite des Rechtecks.

Insgesamt also nicht allzu viel Aufwand.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz