AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Kollision mit Reflektion - Ich raffs net...

Kollision mit Reflektion - Ich raffs net...

Ein Thema von Fussel9 · begonnen am 9. Feb 2011 · letzter Beitrag vom 13. Feb 2011
Thema geschlossen
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#1

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 10. Feb 2011, 22:16
Du würdest dir mit Vektoren wesentlich einfacher tun.
Zitat:
ich speicher übrigens nicht die xy sondern den winkel für den ball hilft mir das irgendwie weiter?
ich glaub das kann ich so gar nicht machen oder?
Genau dafür sind die nämlich praktisch - anstatt des Winkels speicherst du ein deltaX und ein deltaY. Und jedesmal, wenn sich der Ball bewegen soll, veränderst du seine X Postition um deltaX udn seine Y Position um deltaY.

Die Prozedur sieht dann so aus:
Delphi-Quellcode:
procedure TFormMain.MoveByAngle(pWinkel: Integer);
begin
    SBall.Top := SBall.Top + deltaX;
    SBall.Left := SBall.Left + deltaY;
end;
Und über diese deltas steuerst du dann die Bewegungsrichtung.

P.S.: In diesem Zusammenhang ist ein "Vektor" auch nur etwas, um 2 Zahlen "zusammenzufassen". die kannst also deltaX und deltaY als einen Vektor interpretieren. Oder CBall.Left und SBall.Top als einen Vektor.
Zitat:
venn VNeu darstellt wo sich der Ball jetzt befinden wird und VAlt wo der Ball vorher war, woher nehme ich dann den Normalenvektor der Fläche (ich denke mal das soll z.B. der Schläger oder der Brick sein)
Und worauf basiert die Formel? 2* den alten Vektor*Normalenvektor und dann nochmal * den Normalenvektor ...
Und das v aus meinem Beitrag ist dann genau dieser Vektor deltaX/deltaY. Das v ist also nicht die Position, sondern die Geschwindigkeit des Balls!
Die Formel basiert auf Einfallswinkel=Ausfallswinkel. Habe ich vorhin selbst hergeleitet, aber ist sicher noch woanders zu finden.[1] [2] Den Normalenvektor der Fläche musst du wissen - wenn der Ball z.B. oben an den Rand gestoßen ist, dann ist der Normalenvektor (0|1) (Y Achse zeigt ja nach unten, daher +1)
Ach, und: Die Produkte sind Skalarprodukte, die musst du schon genau so rechnen. Assoziativgesetz gilt nicht, also die Klammern sind wichtig!

ich hoffe das hat mehr geholfen als verwirrt

Geändert von jfheins (10. Feb 2011 um 22:22 Uhr)
 
Benutzerbild von Fussel9
Fussel9

Registriert seit: 25. Mai 2009
322 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 11. Feb 2011, 16:07
Zitat:
ich hoffe das hat mehr geholfen als verwirrt
Nope ^^

Ich versteh jetz nicht, woher ich zur laufzeit den Normalenvektor her nehmen soll.. hier ist meine Move methode ohne winkelberechnung... so wie ich sie in nem anderen threat gefunden hatte nur weiter ausgebaut.

Delphi-Quellcode:
procedure TFormMain.MoveBall(pCollisionObject: array of TPanel);
var tempObject,CollisionRect: TRect;
    I: Integer;
begin
  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;
      end;
    if Sball.Top > PStick.Top then
      begin
        SBall.Visible:=False;
        TMover.Enabled:=False;
        MessageDLG('Game Over!',mtWarning,[mbOk],0);
        SpawnBall;
      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,Ball,tempObject) then
          begin
            YCor:= -YCor;
            XCor:= -XCor;
            pCollisionObject[I].Visible:=False;
            pCollisionObject[I].Left:=0-PCollisionObject[I].Width;
            pCollisionObject[I].Top:=0-PCollisionObject[I].Height;
          end;
      end;
end;
hier der Methodenaufruf:
Delphi-Quellcode:
procedure TFormMain.TMoverTimer(Sender: TObject);
begin
  MoveBall([Panel2,Panel3,Panel4,Panel5,Panel6,Panel7,Panel8,Panel9,Panel10,
           Panel11,Panel12,Panel13,Panel14,Panel15,Panel16,Panel17,Panel18,
           Panel19,Panel20,Panel21,Panel22,Panel23,Panel24,Panel25,Panel26,
           Panel27,Panel28,Panel29,Panel30,Panel31,Panel32,Panel33,Panel34,
           Panel35,Panel36,Panel37,Panel38,Panel39,Panel40,Panel41,Panel42,
           Panel43,Panel44,Panel45,Panel46,Panel47,Panel48,Panel49,Panel50,
           Panel51,Panel52,Panel53,Panel54,Panel55,Panel56,Panel57]);
end;
und im anhang mal die pas

Wenn mein Ball jetzt auf einen Stein trifft, woher nehme ich dann den Normalenvektor? Der Normalenvektor beschreibt doch eine im rechten winkel zur fläche stehende gerade, oder?


ich geb es einfach mal auf die formel nachzuvollziehen und sehe sie als gegeben...

Wenn mir jetzt jemand sagen kann woher ich den dusseligen Normalenvektor nehmen soll dann könnte ichs ja programmieren...

Zitat:
Den Normalenvektor der Fläche musst du wissen - wenn der Ball z.B. oben an den Rand gestoßen ist, dann ist der Normalenvektor (0|1) (Y Achse zeigt ja nach unten, daher +1)
... das hat mir irgendwie nicht weitergeholfen...
Angehängte Dateien
Dateityp: pas UMain.pas (5,9 KB, 2x aufgerufen)
 
Notxor

Registriert seit: 28. Okt 2009
41 Beiträge
 
Delphi XE2 Professional
 
#3

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 11. Feb 2011, 16:39
ein Normalvektor ist jeder Vektor, der auf die Gerade/Fläche/(Raum) normal steht. 2 Vektoren stehen aufeinander Normal, wenn ihr Skalarprodukt 0 ergibt. Im 2-dimensionalen kann man dies sehr einfach berechnen(wurde aber schon in diesem Thread irgendwo gesagt...)

v = (x,y)

1.Normalvektor auf v = (y,-x)
2.Normalvektor auf v = (-y,x)

es gibt aber unendlich viele davon, da du n1,n2 mit einem beliebigen Skalar multiplizieren kannst (außer 0), ohne dass sich die Richtung ändert.
 
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 11. Feb 2011, 16:51
Das wird ihm auch nicht weiterhelfen ^^

Das mit den Vektoren hatte ich nur ins Spiel gebracht, weil jemand meinte:
Zitat:
Daraus kannst du dann über den Tangens den Winkel ermitteln...´
Wenn dein Ball nur an horizontalen und Vertikalen Flächen reflektiert ist es sogar noch einfacher...
...dann musst du nur das Vorzeichen einer der Teilgeschwindigkeiten umkehren.
Um zu zeigen: Man kann auf den Tangens verzichten, auch wenn die Geraden schräg im Raum liegen. Die Formel und den Normalenvektor kannst du daher wieder vergessen - du hast ja anscheinend nur vertikale/horizontale Flächen

Zu dem Problem: Du hast ja bereits so eine Art Kollisionserkennung drin. Das Problem ist nur: IntersectRect liefert dir zwar zurück, ob es eine Kollision gab, aber nicht wo. Das musst du selbst herausfinden!

Unter der Annahme dass der übrige Code funktioniert (sieht etwas umständlich aber sonst okay aus...) musst du also in der Schleife feststellen a) ob der Ball kollidiert und b) Wenn ja, wo er kollidiert.
Du musst halt manuell nacheinander die Ober & Unterseite und die linke und die rechte Seite abchecken. Bei Ober/Unterseite die Y Komponente invertieren, Bei links/rechts eben die X-Komponente invertieren.
 
Benutzerbild von Fussel9
Fussel9

Registriert seit: 25. Mai 2009
322 Beiträge
 
Turbo Delphi für Win32
 
#5

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 11. Feb 2011, 19:42
...solangsam gehn mir die Ideen aus... jetz funktionierts nix mehr ^^

Delphi-Quellcode:
procedure TFormMain.MoveBall(pCollisionObject: array of TPanel);
var tempObject,CollisionRect: TRect;
    I,J,a,b,c,d: Integer;
begin
  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;
for J := 0 to SBall.Width - 1 do
  begin
    tempObject.Left:=pCollisionObject[J].Left;
    tempObject.Right:=pCollisionObject[J].Left+pCollisionObject[J].Width;
    tempObject.Top:=pCollisionObject[J].Top;
    tempObject.Bottom:=pCollisionObject[J].Top+pCollisionObject[J].Height;
    if InterSectRect(CollisionRect,Ball,tempObject) then
      begin
        if not (pCollisionObject[J]=nil) then
          begin
            if (sball.Left < (pCollisionObject[J].Left+pCollisionObject[J].Width)) then
              begin
                XCor := -XCor;
                pCollisionObject[J]:=nil;
              end;
            if ((sball.Left+sball.Width)>pCollisionObject[J].Left) then
              begin
                XCor:= -XCor;
                pCollisionObject[J]:=nil;
              end;
          end;
      end;
  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;
    if Sball.Top > PStick.Top then
      begin
        SBall.Visible:=False;
        TMover.Enabled:=False;
        MessageDLG('Game Over!',mtWarning,[mbOk],0);
        SpawnBall;
      end;
for I := 0 to SBall.Height - 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,Ball,tempObject) then
      begin
        if not (pCollisionObject[I]=nil) then
          begin
            if (sball.Top < (pCollisionObject[I].Top+pCollisionObject[I].Height)) then
              begin
                YCor := -YCor;
                pCollisionObject[I]:=nil;
              end;
            if ((sball.Top+sball.Height)>pCollisionObject[I].Top) then
              begin
                YCor:= -YCor;
                pCollisionObject[I]:=nil;
              end;
          end;
      end;
    end;
end;
 
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#6

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 11. Feb 2011, 22:32
...solangsam gehn mir die Ideen aus... jetz funktionierts nix mehr ^^
Und, soll das eine Frage sein? Was soll man damit anfangen?

Einfach hingeklatschte Mammutquelltexte.....

Ich muß mal ein wenig deutlicher werden: Du scheinst mathematisch und/oder physikalisch mit der Aufgabe(nstellung) überfordert zu sein. Doch derlei Defizite auszubügeln, dürfte dieses (Programmier-!)Forum nicht der geeignete Ort sein (auch wenn es nicht meine Aufgabe ist, darüber zu wachen und zu befinden). Ich staune über die Geduld der anderen Schreiberlinge und der Moderatoren.
 
Benutzerbild von Fussel9
Fussel9

Registriert seit: 25. Mai 2009
322 Beiträge
 
Turbo Delphi für Win32
 
#7

AW: Kollision mit Reflektion - Ich raffs net...

  Alt 12. Feb 2011, 01:41
...solangsam gehn mir die Ideen aus... jetz funktionierts nix mehr ^^
Und, soll das eine Frage sein? Was soll man damit anfangen?

Einfach hingeklatschte Mammutquelltexte.....

Ich muß mal ein wenig deutlicher werden: Du scheinst mathematisch und/oder physikalisch mit der Aufgabe(nstellung) überfordert zu sein. Doch derlei Defizite auszubügeln, dürfte dieses (Programmier-!)Forum nicht der geeignete Ort sein (auch wenn es nicht meine Aufgabe ist, darüber zu wachen und zu befinden). Ich staune über die Geduld der anderen Schreiberlinge und der Moderatoren.
Niemand zwingt dich hier zu antworten und wenn die anderen freundlicher weise versuchen mir zu helfen und mir darlegen wo meine fehler liegen, dann ist das ihre eigene entscheidung gewesen mir zu helfen.

Und da es hier um Programmierung geht denke ich das dies schon der ort ist so etwas zu lernen/sich so etwas erklären zu lassem.
 
Thema geschlossen

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:02 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