AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Berührung 2er bewegter Kreise
Thema durchsuchen
Ansicht
Themen-Optionen

Berührung 2er bewegter Kreise

Ein Thema von mr____zero · begonnen am 25. Mai 2009 · letzter Beitrag vom 26. Mai 2009
Antwort Antwort
mr____zero

Registriert seit: 22. Mär 2009
13 Beiträge
 
#1

Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 15:23
ersteinmal hallo bin hier schonwas länger angemeldet brauchte aber bisher noch nicht wirklich hilfe
jetzt schon^^

mein problem ist das wir für die schule ein prog schreiben sollen indem sich auf einem canvas 2 kreise bewegen die gleiche oder verschiedene geschwindigkeiten haben
treffen diese auf die wände sollen sie reflektiert werden was auch klappt aller dings sollen sie auch reflecktiert werden wenn sie sich gegenseitig berühren und da liegt mein problem

hier einmal den quelltext

Code:
verschx := StrToInt(edit1.text);
    verschy := StrToInt(edit2.text);
    verschx1 := StrToInt(edit3.text);
    verschy1 := StrToInt(edit4.text);

    image1.Canvas.Pen.Color := clwhite;
    image1.Canvas.Brush.Color := clwhite;
    image1.Canvas.Rectangle(x,y,x+50,y+50);
    image1.Canvas.Rectangle(x1,y1,x1+50,y1+50);

    x := x+verschx;
    y := y+verschy;
    x1 := x1+verschx1;
    y1 := y1+verschy1;
    image1.Canvas.Pen.Color := clred;
    image1.Canvas.Brush.Color := clred;

    {if (((x1 <= x+50) and (x1 >= x)) and ((y1 <= y+50) and (y1 >= y)))
    then begin
             edit1.Text := IntToStr(StrToInt(Edit1.Text)*(-1));
             edit3.Text := IntToStr(StrToInt(Edit3.Text)*(-1));
             edit2.Text := IntToStr(StrToInt(Edit2.Text)*(-1));
             edit4.Text := IntToStr(StrToInt(Edit4.Text)*(-1));
         end;}
    if (x1+25-x+25+y1+25-y+25) > 0
    then if (Round(sqrt(x1+25-x+25+y1+25-y+25))) <= 50
         then begin
               edit1.Text := IntToStr(StrToInt(Edit1.Text)*(-1));
               edit3.Text := IntToStr(StrToInt(Edit3.Text)*(-1));
               edit2.Text := IntToStr(StrToInt(Edit2.Text)*(-1));
               edit4.Text := IntToStr(StrToInt(Edit4.Text)*(-1));
              end ;



    if x <= 0
    then edit1.Text := IntToStr(StrToInt(Edit1.Text)*(-1));

    if x >= image1.Width-50-StrToInt(Edit1.Text)
    then edit1.Text := IntToStr(StrToInt(Edit1.Text)*(-1));

    if y <= 0
    then edit2.Text := IntToStr(StrToInt(Edit2.Text)*(-1));

    if y >= image1.Height-50-StrToInt(Edit2.Text)
    then edit2.Text := IntToStr(StrToInt(Edit2.Text)*(-1));

    image1.Canvas.Ellipse(x,y,x+50,y+50);

    if x1 <= 0
    then edit3.Text := IntToStr(StrToInt(Edit3.Text)*(-1));

    if x1 >= image1.Width-50-StrToInt(Edit3.Text)
    then edit3.Text := IntToStr(StrToInt(Edit3.Text)*(-1));

    if y1 <= 0
    then edit4.Text := IntToStr(StrToInt(Edit4.Text)*(-1));

    if y1 >= image1.Height-50-StrToInt(Edit4.Text)
    then edit4.Text := IntToStr(StrToInt(Edit4.Text)*(-1));

    image1.Canvas.Brush.Color := clblue;
    image1.Canvas.Pen.Color := clblue;
    image1.Canvas.Ellipse(x1,y1,x1+50,y1+50);
hoffe das ihr mir helfen könnt
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 15:39
Also mal theoretisch...

Beide Kreismittelpunkte berechnen (Koordinaten umgebendes Quadrat hast Du)
Entfernung der Kreismittelpunkte berechnen (Wie Diagonale eines Rechteckes)
Wenn Entfernung <= Radius1 + Radius2 dann berühren sich die Kreise

Sollte aus den Kreisen echte Ellipsen werde, wird es mit dem Radius haarig
  Mit Zitat antworten Zitat
mr____zero

Registriert seit: 22. Mär 2009
13 Beiträge
 
#3

Re: Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 15:44
nein sollen kreise bleiben
und von der theorie her ist mir auch klar wie das geht nur leider funzt das net habe bei beiden kreisen den radius 25 gewählt
nun rechne ich via phytagoras aus wie weit die voneinander entfernt sind und lasse die dann ihre richtung wechseln nur wenn man das ganze startet kommt da irgendwie müll raus

Code:
if round(sqrt(sqr(x1+25-x+25)+sqr(y1+25-y+25))) <= 50
         then begin
               edit1.Text := IntToStr(StrToInt(Edit1.Text)*(-1));
               edit3.Text := IntToStr(StrToInt(Edit3.Text)*(-1));
               edit2.Text := IntToStr(StrToInt(Edit2.Text)*(-1));
               edit4.Text := IntToStr(StrToInt(Edit4.Text)*(-1));
              end ;
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#4

Re: Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 15:45
Hast du schon mal was von Variablen gehört? Ein Edit ist nicht dazu da, Variablen zu speichern... Wenn du die aktuellen Werte anzeigen willst, wären Labels das richtige.
Zahlen wie "25" gehören auf keinen Fall (!) in den Code, in 2h weisst du nicht mehr, was die bedeuten, wenn du einen größeren Kreis benutzen willst, liegst du damit recht schnell auf der Nase.

Das mit der Kollision ist eigentlich ziemlich einfach. Du kannst die beiden Geraden, auf denen sich die Mittelpunkte bewegen, in Parameterform angeben:
g_1 : (x,y)+r*(vx,vy)
g_2 : (x',y')+s*(vx',vy')

Die beiden Kreise kollidieren, wenn der Abstand der geraden der Summe der Radien entspricht. In Abhängigkeit von der Position hast du einen Abstand von
d_x = (x+r*vx-x'-r*vx)
d_y = (y+r*vy-y'-s*vy')

d(r,s)=sqrt(d_x*d_x+d_y*d_y)

Dann löst du den Ausdruck d(r,s)=R_1+R_2 und hast zwei Mögliche Lösungen, wobei du die frühere Lösung wählst.

Wenn du das hast, kannst du dir sorgen um das Abprallen machen, da wirds schon ein bischen schwieriger, weil noch Rotationsmatrizen ins Spiel kommen (und für Fortgeschrittene auch noch unterschiedliche Massen).

@satty: Das mit Ellipsen wird SEHR unschön. Die Kollisionsberechnung dort für auf ein Polynom dritten Grades, dessen Lösung (ohne Approximative Verfahren) recht schwierig wird.

@Post 3: Hast du verstanden, was dein Code macht? Du tust so, als ob die Kugeln von senkrechten Wänden abprallen und nicht voneinander...
btw: Du hast schon die Variable verschx. Warum machst du diesen Murks mit den Casts in das Edit rein und wieder raus?
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
mr____zero

Registriert seit: 22. Mär 2009
13 Beiträge
 
#5

Re: Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 15:53
Zitat von Nikolas:
Hast du schon mal was von Variablen gehört? Ein Edit ist nicht dazu da, Variablen zu speichern... Wenn du die aktuellen Werte anzeigen willst, wären Labels das richtige.
Zahlen wie "25" gehören auf keinen Fall (!) in den Code, in 2h weisst du nicht mehr, was die bedeuten, wenn du einen größeren Kreis benutzen willst, liegst du damit recht schnell auf der Nase.

Das mit der Kollision ist eigentlich ziemlich einfach. Du kannst die beiden Geraden, auf denen sich die Mittelpunkte bewegen, in Parameterform angeben:
g_1 : (x,y)+r*(vx,vy)
g_2 : (x',y')+s*(vx',vy')

Die beiden Kreise kollidieren, wenn der Abstand der geraden der Summe der Radien entspricht. In Abhängigkeit von der Position hast du einen Abstand von
d_x = (x+r*vx-x'-r*vx)
d_y = (y+r*vy-y'-s*vy')

d(r,s)=sqrt(d_x*d_x+d_y*d_y)

Dann löst du den Ausdruck d(r,s)=R_1+R_2 und hast zwei Mögliche Lösungen, wobei du die frühere Lösung wählst.

Wenn du das hast, kannst du dir sorgen um das Abprallen machen, da wirds schon ein bischen schwieriger, weil noch Rotationsmatrizen ins Spiel kommen (und für Fortgeschrittene auch noch unterschiedliche Massen).

@satty: Das mit Ellipsen wird SEHR unschön. Die Kollisionsberechnung dort für auf ein Polynom dritten Grades, dessen Lösung (ohne Approximative Verfahren) recht schwierig wird.

@Post 3: Hast du verstanden, was dein Code macht? Du tust so, als ob die Kugeln von senkrechten Wänden abprallen und nicht voneinander...
btw: Du hast schon die Variable verschx. Warum machst du diesen Murks mit den Casts in das Edit rein und wieder raus?
g_2 : (x',y')+s*(vx',vy')
hier müsstest du mir noch einmal erklären was du mit s meinst
ansonsten danke ich dir für deine hilfe werde versuchen alles umzusetzen
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

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

Re: Berührung 2er bewegter Kreise

  Alt 25. Mai 2009, 22:07
Zitat von mr____zero:
g_2 : (x',y')+s*(vx',vy')
hier müsstest du mir noch einmal erklären was du mit s meinst
ansonsten danke ich dir für deine hilfe werde versuchen alles umzusetzen
Das ist ein Schreibweise für eine Gerade.

s ist eine Laufvariable (z.B. die Zeit) und x',y' ist die Anfangsposition. Zum Zeuitpubkt s=0 ist die Position also gleich der Anfangsposition. Danach bewegt sich das Objekt - du zählst s hoch und bekommst die aktuielle Position raus.
  Mit Zitat antworten Zitat
mr_emre_d
(Gast)

n/a Beiträge
 
#7

Re: Berührung 2er bewegter Kreise

  Alt 26. Mai 2009, 00:03
Delphi-Quellcode:
function CircleIntersect( Circle1Center, Circle2Center: TPoint;
  Circle1Radius, Circle2Radius: Cardinal ): Boolean;
begin
  Circle1Center := Point( Circle2Center.X - Circle1Center.X, Circle2Center.Y - Circle1Center.Y );
  Result := SQRT( Circle1Center.X*Circle1Center.X + Circle1Center.Y*Circle1Center.Y ) <= (Circle1Radius div 2 + Circle2Radius div 2);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  M1 := Point( $80, $80 );
  M1R := $80;
  M2 := Point( $100, $80 );
  M2R := $80;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  if CircleIntersect( M1, M2, M1R, M2R ) then
    Canvas.Pen.Color := clRed
  else
    Canvas.Pen.Color := clLime;
  Canvas.Ellipse( M1.X - M1R div 2, M1.Y - M1R div 2, M1.X + M1R div 2, M1.Y + M1R div 2 );
  Canvas.Ellipse( M2.X - M2R div 2, M2.Y - M2R div 2, M2.X + M2R div 2, M2.Y + M2R div 2 );
end;
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#8

Re: Berührung 2er bewegter Kreise

  Alt 26. Mai 2009, 15:59
Das ist aber ziemlich schlechter Stil.

Warum benutzt du in der Intersect-Funktion denn keine lokale Variable für den Abstand in x und y und überschreibst lieber einen der Parameter, wodurch die fiese Seiteneffekte auslöst und die Benennung der Variablen nichts mehr mit ihrem Inhalt zu tun hat.
Was machst du bei schnellen Kreisen? (Also etwa solche, die während eines Zeitschritts durcheinander durchlaufen?)
Die Lösung funktioniert zwar bei einfachen Beispielen, bei einer richtigen Anwendung bringt es dir aber gar nichts mehr...
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
Draos

Registriert seit: 12. Aug 2008
42 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Berührung 2er bewegter Kreise

  Alt 26. Mai 2009, 18:47
Wie wärs mit Vektorrechnung? Hier mal eine Function die ich aufgrund eines Kollisionstest mal schrieb.
Vector ist eine Klasse die die Vektoroperationen beinhaltet.
Delphi-Quellcode:
TSphere=record
  m :TVector;//Stützvektor, Kreismittelpunkt
  a :TVector;//Geschwindigkeitsvektor
  r :Single;//Kreisradius
end;
//..
function collision(k1,k2:TSphere):Single;
var a,b :TVector;
    s,r,t:Single;
begin
 with Vector do begin
  a:=Sub(k1.m,k2.m);
  b:=Sub(k1.a,k2.a);
  r:=k1.r+k2.r;
  t:=Skalar(b,b);
  if t<>0 then begin
   s:=sqr(Skalar(a,b)/t)-Skalar(a,a)/t+r*r/t;
   if s>=0 then
    s:=-Skalar(a,b)/t-sqrt(s)
   else s:=0;
  end else s:=0;
  result:=s;
 end;
end;
Der Rückgabewert der Funktion beinhaltet die Zeiteinheiten bis die Kreise kollidieren. Wenn sie nicht kollidieren s=0.
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz