| Autor |
Beitrag |
Fussel9
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Mo 14.02.11 18:35
hallo, habe zwei rechtecke die sich schneiden.
jetzt muss ich herausfinden an welcher seite...
Ich habe von dem einen Rechteck zwei Punkte von der geraden auf der es sich bewegt und von dem anderen Rechteck habe ich ja Top|left und top|(Left+width)
jetz will ich bestimmen ob die beiden geraden sich schneiden, nur wie mache ich das im Quelltext?
und wie stelle ich die geradengleichungen auf, bzw. brauche ich die überhaupt?
normaler weise würde man ja jetzt zwei geradengleichungen erstellen und die dann gleichsetzen...
das wäre ja ziehmlich aufwendig... hat delphi da schon funktionen..?
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Mo 14.02.11 18:43
Du könntest ev. mittels IntersectRect auf eine Schnittfläche bei den beiden Rechtecken prüfen.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
Fussel9 
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Mo 14.02.11 18:48
Das mach ich schon, aber ich muss wissen ob das zweite rechteck von links/rechts oder von oben/unten
berührt wird.
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Mo 14.02.11 19:49
Hallo,
aus dem Ergebnis-Rect kannst Du es ermitteln:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var aR, bR, ergR: TRect; begin aRect := Rect(100,100,200,200); bRect := Rect(10,10,120,120); IntersectRect(ergRect,aRect,bRect); |
Ist ergRect.Left gleich aRect.Left, dann Berührung von links
...
...
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
Fussel9 
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Mo 14.02.11 20:26
wie soll das funktionieren?
Siehe angehängte Grafik.
Ich habe jetzt einen mathematischen Weg, nur als Quelltext funktioniert der nicht und ich weiß nicht wieso...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function TFormMain.LineCollision(x1: Integer; y1: Integer; x2: Integer; y2: Integer; x3: Integer; y3: Integer; x4: Integer; y4: Integer) : Boolean; var m1,m2,b1,b2,resultX: Real; begin result:=FALSE; m1:=(y2-y1)/(x2-x1); m2:=(y4-y3)/(x4-x3); b1:=y1-m1*x1; b2:=y3-m2*x3; resultX:=(b1-b2)/(m2-m1); ShowMessage(FloatToStr(resultX)); if not(resultX=0) then begin result:=TRUE; end; end; |
für jede gerade: m=(y2-y1)/(x2-x1) b=y1-m*x1
und dann für den Schnittpunkt: x=(b1-b2)/(m2-m1)
will nur einfach nicht funktionieren... bei resultX:=(b1-b2)/(m2-m1); fliegt der compiler raus mit der Meldung:
'Ungültige Gleitkommaoperation!'
Einloggen, um Attachments anzusehen!
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Mo 14.02.11 20:36
Hallo,
in dem Fall der Grafik ist:
ergRect.Right = aRect.Right
und
ergRect.Bottom = aRect.Bottom
=> von rechts/unten
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
Fussel9 
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Mo 14.02.11 20:39
Und genau das ist das problem, ich muss genau zwischen unten oder oben und rechts oder links unterscheiden.
Bei Rechts/Links muss die XKoordinate invertiert werden,
Bei Oben/Unten die YKoordinate...
Daher auch die function oben
PS: nach dem ich die function mit realen werten benutze tritt der selbe fehler jetzt schon hier auf: m1:=(y2-y1)/(x2-x1); (in der funtion)
|
|
Fussel9 
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Mo 14.02.11 21:38
(!)
Das ganze funktioniert einiger maßen, aber nicht immer unbedingt richtig und es kommt zu divisionen durch null...
Ich gebe hier mal den Quelltext aus...
Kann mir jemand helfen?
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183:
| procedure TFormMain.MoveBall(pCollisionObject: array of TPanel); var tempObject,CollisionRect,BallAlt: TRect; I,: Integer; begin BallAlt.Top:=Ball.Top; BallAlt.Bottom:=Ball.Bottom; BallAlt.Left:=Ball.Left; BallAlt.Right:=Ball.Right; oldXCor:=XCor; oldYCor:=YCor; sball.left:=sball.left+XCor; Ball.Left:=SBall.Left; Ball.Right:=SBall.Left+SBall.Width; if sball.left < (PLinks.Left+PLinks.Width) then begin sball.left := (PLinks.Left+PLinks.Width); Xcor := -Xcor; end; if sball.left > PRechts.Left - sball.width then begin sball.left := (PRechts.Left - sball.width); XCor := -XCor; end; sball.top := sball.top+YCor; Ball.Top:=SBall.Top; Ball.Bottom:=SBall.Top+SBall.Height; if sball.top < (POben.Top+POben.Height) then begin sball.Top := (POben.Top+POben.Height); YCor := -YCor; end; if sball.top > (self.height - sball.height) then begin sball.top := (self.height - sball.height); YCor := -YCor; end; if IntersectRect(Collision,Ball,Stick) then begin sball.top := (PStick.top - sball.height); YCor:= -YCor; XCor:= XCor-1; end; for I := 0 to High(pCollisionObject) - 1 do begin tempObject.Left:=pCollisionObject[I].Left; tempObject.Right:=pCollisionObject[I].Left+pCollisionObject[I].Width; tempObject.Top:=pCollisionObject[I].Top; tempObject.Bottom:=pCollisionObject[I].Top+pCollisionObject[I].Height; if IntersectRect(CollisionRect,tempObject,Ball) then begin TMover.Enabled:=False; case Richtung of 0: begin if LineCollision(BallAlt.Left,BallAlt.Top,Ball.Left,Ball.Top, pCollisionObject[I].Left,pCollisionObject[I].Top, pCollisionObject[I].Left+pCollisionObject[I].Width, pCollisionObject[I].Top)=TRUE then begin SBall.Top:=(pCollisionObject[I].Top-SBall.Height); YCor:= -YCor; end else begin SBall.Left:=(pCollisionObject[I].Left-SBall.Width); XCor:= -XCor; end; end; 1: begin if LineCollision(BallAlt.Left,BallAlt.Top,Ball.Left,Ball.Top, pCollisionObject[I].Left, pCollisionObject[I].Top+pCollisionObject[I].Height, pCollisionObject[I].Left+pCollisionObject[I].Width, pCollisionObject[I].Top+pCollisionObject[I].Height) =TRUE then begin SBall.Top:=(pCollisionObject[I].Top+SBall.Height); YCor:= -YCor; end else begin SBall.Left:=(pCollisionObject[I].Left-SBall.Width); XCor:= -XCor; end; end; 2: begin if LineCollision(BallAlt.Left,BallAlt.Top,Ball.Left,Ball.Top, pCollisionObject[I].Left, pCollisionObject[I].Top+pCollisionObject[I].Height, pCollisionObject[I].Left+pCollisionObject[I].Width, pCollisionObject[I].Top+pCollisionObject[I].Height) =TRUE then begin SBall.Top:=(pCollisionObject[I].Top+SBall.Height); YCor:= -YCor; end else begin SBall.Left:=(pCollisionObject[I].Left+SBall.Width); XCor:= -XCor; end; end; 3: begin if LineCollision(BallAlt.Left,BallAlt.Top,Ball.Left,Ball.Top, pCollisionObject[I].Left,pCollisionObject[I].Top, pCollisionObject[I].Left+pCollisionObject[I].Width, pCollisionObject[I].Top)=TRUE then begin SBall.Top:=(pCollisionObject[I].Top-SBall.Height); YCor:= -YCor; end else begin SBall.Left:=(pCollisionObject[I].Left+SBall.Width); XCor:= -XCor; end; end; end; TMover.Enabled:=TRUE; end; end; if Sball.Top > PStick.Top then begin SBall.Visible:=False; TMover.Enabled:=False; MessageDLG('Game Over!',mtWarning,[mbOk],0); SpawnBall; end; if ((BallAlt.Left-Ball.Left)<0) then begin if ((BallAlt.Top-Ball.Top)<0) then begin Richtung:=3; end else begin if ((BallAlt.Top-Ball.Top)>0) then begin Richtung:=2; end; end; end else begin if ((BallAlt.Left-Ball.Left)>0) then begin if ((BallAlt.Top-Ball.Top)<0) then begin Richtung:=0; end else begin if ((BallAlt.Top-Ball.Top)>0) then begin Richtung:=1; end; end; end; end; end; |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| function TFormMain.LineCollision(x1: Integer; y1: Integer; x2: Integer; y2: Integer; x3: Integer; y3: Integer; x4: Integer; y4: Integer) : Boolean; var m1,m2,b1,b2,resultX: Real; begin result:=FALSE; m1:=(y2-y1)/(x2-x1); m2:=(y4-y3)/(x4-x3); b1:=y1-m1*x1; b2:=y3-m2*x3; resultX:=(b1-b2)/(m2-m1); if not(resultX=0) then begin result:=TRUE; end; end; |
Danke schon mal für jeden Tip der ratlose Fussel 
|
|
Fiete
      
Beiträge: 618
Erhaltene Danke: 368
W7
Delphi 6 pro
|
Verfasst: Di 15.02.11 13:11
Moin Fussel9,
schau mal hier nach:
mathenexus.zum.de/ht..._SchneideGeraden.htm
Gruß
Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
Fussel9 
      
Beiträge: 23
Win 7
Delphi
|
Verfasst: Di 15.02.11 20:30
Oh, ok jetz hab ich also noch eine Abfrage nach m1<>m2 hinzugefügt...
jetzt fliegt das Programm nicht mehr wegen Divisionen durch 0 raus, das ist gut;
aber das Programm berechnet irgendwie die collisionen und so noch nit richtig, irgendwo muss noch ein fehler in der moveBall procedure bestehen...
Ich finde ihn aber einfach nicht zur anschauung im anhang mal die .pas und die .exe
Ich hoffe ihr könnt mir nochmal weiter helfen
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<<Edit>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
---> Nach einigen Überlegungen und Beobachtungen des Programes ist mir der Fehler aufgefallen:
---> Bei der procedure LineCollision liegt der Fehler: die procedure funktioniert, das Problem ist, das die function immer True ausgeben wird, außer es handelt sich um Parallelen, was schon daher nicht sein kann da ich den Wert 0 für Xcor/Ycor abfange und neu auswürfeln lasse!...
Mit anderen Worten: da ich Geraden berechne und nicht Strecken werden diese immer einen Schnittpunkt haben!
--Ich hab die function LineCollision jetzt so erweitert das sie prüft ob der Schnittpunkt auf der Kante des Steins liegt mit dem der Ball kollidiert..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Es funktioniert aber immer noch nicht... jemand eine Idee wieso *verzweiflungs smiley*
Einloggen, um Attachments anzusehen!
|
|
Fiete
      
Beiträge: 618
Erhaltene Danke: 368
W7
Delphi 6 pro
|
Verfasst: Mi 16.02.11 18:07
Moin Fussel9,
versuchs mal hiermit (Objekte als Rechtecke oder Kreise):
www.delphi-forum.de/...sabfrage_103385.html
Gruß
Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
|