Autor Beitrag
Fussel9
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mo 14.02.11 19:49 
Hallo,

aus dem Ergebnis-Rect kannst Du es ermitteln:

ausblenden 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);//=> ergRect(100,100,120,120)

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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...

ausblenden 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=0then
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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?
ausblenden volle Höhe 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:
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
//-----------------------------save old Parameters----------------------------//
BallAlt.Top:=Ball.Top;
BallAlt.Bottom:=Ball.Bottom;
BallAlt.Left:=Ball.Left;
BallAlt.Right:=Ball.Right;
oldXCor:=XCor;
oldYCor:=YCor;
//----------------------------------------------------------------------------//
//--------------------Move Ball Check for Wall Collision(x)-------------------//
  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;
//----------------------------------------------------------------------------//
//--------------------Move Ball Check for Wall Collision(y)-------------------//
  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;
//----------------------------------------------------------------------------//
//-----------------------------Collision Ball Stick---------------------------//
    if IntersectRect(Collision,Ball,Stick) then
      begin
        sball.top := (PStick.top - sball.height);
        YCor:= -YCor;
        XCor:= XCor-1;
      end;
//----------------------------------------------------------------------------//
//------------------------Collision Ball Brick--------------------------------//
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
          0begin
               //Ball läuft nach Unten Rechts
             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;
          1begin
               //Ball läuft nach Oben Rechts
             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;
          2begin
              //Ball läuft nach Oben Links
             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;
          3begin
              //Ball läuft nach Unten Links
             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;
//----------------------------------------------------------------------------//
//-------------------------Ball doesn't hit Stick-----------------------------//
    if Sball.Top > PStick.Top then
      begin
        SBall.Visible:=False;
        TMover.Enabled:=False;
        MessageDLG('Game Over!',mtWarning,[mbOk],0);
        SpawnBall;
      end;
//----------------------------------------------------------------------------//
//------------------------Save (?)new(?) Direction----------------------------//
if ((BallAlt.Left-Ball.Left)<0then
  begin
    //links
    if ((BallAlt.Top-Ball.Top)<0then
      begin
        //schräg unten links
        Richtung:=3;
      end
    else
      begin
        if ((BallAlt.Top-Ball.Top)>0then
          begin
            //schräg oben links
            Richtung:=2;
          end;
      end;
  end
else
  begin
    if ((BallAlt.Left-Ball.Left)>0then
      begin
        //rechts
        if ((BallAlt.Top-Ball.Top)<0then
          begin
            //schräg unten rechts
            Richtung:=0;
          end
        else
          begin
            if ((BallAlt.Top-Ball.Top)>0then
              begin
                //schräg oben rechts
                Richtung:=1;
              end;
          end;
      end;
  end;
//----------------------------------------------------------------------------//
end;

ausblenden 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
//ShowMessage('x1:'+IntToStr(x1)+'y1:'+IntToStr(y1)+'x2:'+IntToStr(x2)+'y2:'+
//            IntToStr(y2)+'x3:'+IntToStr(x3)+'y3:'+IntToStr(y3)+'x4:'+
//            IntToStr(x4)+'y4:'+IntToStr(y4));
result:=FALSE;
  m1:=(y2-y1)/(x2-x1);
//ShowMessage(FloatToStr(m1));
  m2:=(y4-y3)/(x4-x3);
//ShowMessage(FloatToStr(m2));
  b1:=y1-m1*x1;
//ShowMessage(FloatToStr(b1));
  b2:=y3-m2*x3;
//ShowMessage(FloatToStr(b2));
  resultX:=(b1-b2)/(m2-m1);
//ShowMessage(FloatToStr(resultX));
if not(resultX=0then
  begin
    result:=TRUE;
  end;
end;



Danke schon mal für jeden Tip der ratlose Fussel :shock:
Fiete
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 618
Erhaltene Danke: 368

W7
Delphi 6 pro
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 23

Win 7
Delphi
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 618
Erhaltene Danke: 368

W7
Delphi 6 pro
BeitragVerfasst: 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)