Rect Collision mit Rotation

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

FOODy

Betreff: Rect Collision mit Rotation

BeitragSa, März 17, 2007 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi.
Da ich nicht so ein Collisionschecker bin hab ich probleme mit einer Collisionsabfrage für gedrehte Rechtecke.

Ich habs mal so versucht (was aber nicht das wahre ist):
Code: [AUSKLAPPEN]
SuperStrict
Framework BRL.GLMax2D

Graphics 480,480,0,-1

Local x:Int
Local y:Int
Local w:Int=48
Local h:Int=32
Local angle:Float

Repeat
   Cls
      x=MouseX()
      y=MouseY()
      
      If KeyDown(KEY_LEFT) angle:-1
      If KeyDown(KEY_RIGHT) angle:+1
      
      SetColor 255,255,255
      SetRotation 45
      DrawRect 128,128,96,128
      
   
      If RectangleCollision(x,y,w,h,angle,128,128,96,128,45)
         SetColor 255,0,0
      Else
         SetColor 0,255,255
      EndIf
      
      SetRotation angle
      DrawRect x,y,w,h
      
   Flip
Until AppTerminate() Or KeyDown(KEY_ESCAPE)



Function RectangleCollision:Byte(x1:Int,y1:Int,w1:Int,h1:Int,a1:Float,x2:Int,y2:Int,w2:Int=1,h2:Int=1,a2:Float=0)
   Local lx1:Int[4],ly1:Int[4]
   Local lx2:Int[4],ly2:Int[4]
   lx1[0]=x1
   ly1[0]=y1
   
   lx1[1]=x1+Cos(a1+90)*h1
   ly1[1]=y1+Sin(a1+90)*h1
   
   lx1[2]=lx1[1]+Cos(a1)*w1
   ly1[2]=ly1[1]+Sin(a1)*w1
   
   lx1[3]=lx1[0]+Cos(a1)*w1
   ly1[3]=ly1[0]+Sin(a1)*w1
   
   lx2[0]=x2
   ly2[0]=y2
   
   lx2[1]=x2+Cos(a2+90)*h2
   ly2[1]=y2+Sin(a2+90)*h2
   
   lx2[2]=lx2[1]+Cos(a2)*w2
   ly2[2]=ly2[1]+Sin(a2)*w2
   
   lx2[3]=lx2[0]+Cos(a2)*w2
   ly2[3]=ly2[0]+Sin(a2)*w2
   
   For Local i:Int=0 Until 4
      For Local n:Int=0 Until 4
         If CollisionLine(lx1[i],ly1[i],lx1[(i+1) Mod 4],ly1[(i+1) Mod 4],lx2[n],ly2[n],lx2[(n+1) Mod 4],ly2[(n+1) Mod 4]) Return True
      Next
   Next
EndFunction

Function CollisionLine:Byte(ax:Float, ay:Float, bx:Float, by:Float, cx:Float, cy:Float, dx:Float, dy:Float)
   Local rn:Float = (ay-cy)*(dx-cx) - (ax-cx)*(dy-cy)
   Local rd:Float = (bx-ax)*(dy-cy) - (by-ay)*(dx-cx)
   Local intersection:Int,intersection_ab:Float,intersection_cd:Float
   Local intersection_x:Float,intersection_y:Float
   Local sn:Float
   If rd = 0
      intersection = 0
   Else
      sn = (ay-cy)*(bx-ax) - (ax-cx)*(by-ay)
      intersection_ab = rn/ rd
      intersection_cd = sn/ rd
      intersection_x = ax+intersection_ab*(bx-ax)
      intersection_y = ay+intersection_ab*(by-ay)
      intersection = 1
   EndIf
   If(intersection=0 Or intersection_ab<0.0 Or intersection_ab>1.0 Or intersection_cd<0.0 Or intersection_cd>1.0)
      Return False
   Else
      Return True
   EndIf
End Function

(Bevor jemand fragt: Ja die CollisionLine funktion ist NICHT von mir xD)

Hier werden aber nur die Eckpunkte berechnet und dann wird geguckt ob sich die Seiten schneiden von den Rechtecken.

Weiß jemand wie man das "richtig" macht?
Bitte helft mir Sad


Gruß,
FOODy
BlitzMax + MaxGUI, 64-bit Arch Linux: Intel Core² E8500 | 8 GB Ram | GeForce GTX 460 · 1024 MB
 

krux

BeitragDi, März 27, 2007 20:22
Antworten mit Zitat
Benutzer-Profile anzeigen
also erstens ich weis garnichts, hab micht damit och nicht beschäftigt, aber ich glaube helfen zu können:

Ich würd versuchen zu untersuchen, ob die eckpunkte des einen innerhalb des anderen rechtecks liegen, dazu reicht es aus zu prüfen, ob sich die diagonalen des einen rechtecks mit den kannten des anderen schneiden, aber die beste laufzeitobtimierung schafft man dadurch, indem man eine abfrage einbaut, die Prüft, ob eine kollision überhaupt in frage kommt. Das ist der fall, wenn der abstand in irgendeineeine koordinatenrichtung zum anderen Objekt höher ist als der Durchmesser beider objekte zusammen geteilt durch zwei. und den Durchmesser muss man ja nur einmal ausrechnen.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group