| Autor |
Beitrag |
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Mo 19.02.07 11:37
HI,
es gab vor ein paar wochen schonma so'n Thema. das hat mich auf die Idee gebracht n Billjardspiel zu programmieren. Nun ist das eintige woran es hängt die berechnung wie sich die beiden Kugeln voneinander abstoßen. Ich hab schon edliche Skizzen gemacht und irgedwie versucht mit Winkelfkt. die Flugbahn zu berechnen aber ich komm einfach nicht dahinter. Kann mir da jemand helfen?! Die rein physikalische Formel würde reichen umsetzung in Delphi müsste ich selber hin bekommen.
MfG & Thx Bergmann.
|
|
rockminstrel
      
Beiträge: 38
Win XP Prof.
Delphi 5 Prof., Delphi 2005 pers., Turbo Delphi 2006 Exp.
|
Verfasst: Mo 19.02.07 11:44
Also eigentlich müsste es so sein: (Billardbeispiel) die rote Kugel bewegt sich geradlinig in die Richtung, die Berührungspunkt mir der weißen ugel und Zentrum bilden. Deswegen testen die Spieler oft, wo man die rote Kugel treffen muss um sie direkt ins Loch zu stoßen.
Was ich dir nicht sagen kann ist wohin die weiße Kugel geht nachdem Sie die rote berührt hat.
|
|
Dragonclaw
      
Beiträge: 196
Windows Vista
Delphi 7 Prof.
|
Verfasst: Mo 19.02.07 11:48
Hallo,
das ganze nennt sich dezentraler elastischer Stoß.
Es gab mal einen Beitrag hier im Forum wo jemand genau dieses Problem gelöst hatte. Ich würde hier gerne delfiphan quoten, aber der Beitrag scheint down zu sein. Hier mal der Link: www.delphi-forum.de/...=tkugel+class+tshape
Allerdings habe ich mir damals den Code geladen und hab den auch noch wieder gefunden. Hier ist der Code:
| Zitat: | 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: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197:
| unit Unit1;
interface
uses SysUtils, Forms, StdCtrls, ExtCtrls, Classes, Controls;
const dt = 20; SubIterations = 20; KugelCount = 10;
type TKugel = class;
TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private public Kugeln: array[0..KugelCount-1] of TKugel; end;
Borders = (boLeft, boTop, boBottom, boRight); BordersSet = set of Borders; TKugel = class(TShape) private FX, FY: Extended; FR: Extended; FM: Extended; FVx, FVy: Extended; procedure setR(const Value: Extended); public property X: Extended read FX write FX; property Y: Extended read FY write FY; property R: Extended read FR write setR; property M: Extended read FM write FM; property Vx: Extended read FVx write FVx; property Vy: Extended read FVy write FVy; procedure Move; procedure Apply; function CollidesWith(const Kugel2: TKugel): Boolean; function WallCollisions: BordersSet; constructor Create(AOwner: TComponent); override; end;
var Form1: TForm1;
implementation
{$R *.dfm}
function TKugel.CollidesWith(const Kugel2: TKugel): Boolean; begin Result := sqr(FX-Kugel2.FX)+sqr(FY-Kugel2.FY) < sqr(FR+Kugel2.FR); end;
constructor TKugel.Create(AOwner: TComponent); begin inherited; Shape := stCircle; end;
procedure TKugel.Move; begin X := X + (dt/1000)/SubIterations*FVx; Y := Y + (dt/1000)/SubIterations*FVy; end;
function TKugel.WallCollisions: BordersSet; const Border = 10; begin Result := []; if X-Border < R then Result := Result + [boLeft]; if Y-Border < R then Result := Result + [boTop]; if X+Border >= Parent.ClientWidth-R then Result := Result + [boRight]; if Y+Border >= Parent.ClientHeight-R then Result := Result + [boBottom]; end;
procedure TKugel.setR(const Value: Extended); begin FR := Value; Width := Round(FR*2); Height := Round(FR*2); end;
procedure TKugel.Apply; begin Left := round(X-FR); Top := round(Y-FR); end;
procedure TForm1.FormCreate(Sender: TObject); const Border = 10; var I: Integer; begin with Timer1 do begin Interval := dt; OnTimer := Timer1Timer; end;
for I := 0 to Length(Kugeln)-1 do begin Kugeln[I] := TKugel.Create(Form1); with Kugeln[I] do begin Parent := self; R := 20+Random(8); X := Random(self.ClientWidth-2*Round(R+Border))+Round(R+Border); Y := Random(self.ClientHeight-2*Round(R+Border))+Round(R+Border); Vx := Random(400); Vy := Random(400); M := 4/3*R*R*R*pi; Brush.Color := Random(256*256*256); end; end; end;
procedure TForm1.Timer1Timer(Sender: TObject); var DX, DY, M11, M21, M12, M22, L, Vp1, Vp2, Vs1, Vs2, MTot, Vp1_, Vp2_: Extended; I, J, K: Integer; B: BordersSet; begin for K := 0 to SubIterations-1 do begin for I := 0 to Length(Kugeln)-1 do Kugeln[I].Move;
for I := 0 to Length(Kugeln)-1 do for J := I+1 to Length(Kugeln)-1 do if Kugeln[I].CollidesWith(Kugeln[J]) then begin DX := Kugeln[j].X-Kugeln[i].X; DY := Kugeln[j].Y-Kugeln[i].Y; L := sqrt(sqr(DX)+sqr(DY)); M11 := DX/L; M12 := -DY/L; M21 := DY/L; M22 := DX/L;
Vp1 := Kugeln[i].Vx*M11+Kugeln[i].Vy*-M12; Vs1 := Kugeln[i].Vx*-M21+Kugeln[i].Vy*M22; Vp2 := Kugeln[j].Vx*M11+Kugeln[j].Vy*-M12; Vs2 := Kugeln[j].Vx*-M21+Kugeln[j].Vy*M22;
if Vp1-Vp2<0 then Continue; MTot := Kugeln[i].M+Kugeln[j].M; Vp1_ := (Kugeln[i].M-Kugeln[j].M)/MTot*Vp1+2*Kugeln[j].M/MTot*Vp2; Vp2_ := (Kugeln[j].M-Kugeln[i].M)/MTot*Vp2+2*Kugeln[i].M/MTot*Vp1;
Kugeln[i].Vx := Vp1_*M11+Vs1*M12; Kugeln[i].Vy := Vp1_*M21+Vs1*M22; Kugeln[j].Vx := Vp2_*M11+Vs2*M12; Kugeln[j].Vy := Vp2_*M21+Vs2*M22; end;
for I := 0 to Length(Kugeln)-1 do with Kugeln[I] do begin B := WallCollisions; if ((boLeft in B) and (Vx < 0)) or ((boRight in B) and (Vx > 0)) then Vx := -Vx; if ((boTop in B) and (Vy < 0)) or ((boBottom in B) and (Vy > 0)) then Vy := -Vy; end; end; for I := 0 to Length(Kugeln)-1 do Kugeln[I].Apply; end;
end. |
|
|
|
Corpsman
      
Beiträge: 228
KUbuntu 10.4
Lazarus
|
Verfasst: Mo 19.02.07 11:49
Das wurde echt schon zig mal gefragt.
Schau dir einfach mal das
Sample
an.
_________________ --
Just Try it.
|
|
Bergmann89 
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Di 20.02.07 08:19
OK, das hab ich gesucht...
Werd mich da jetzt erstma Durcharbeiten, DANKE.
Gibts da auch noch ne genaue Erklärung dazu, denn die Variablen sind
nicht grad aussagefähig, mit manchen Befehlen weiß ich nicht viel
anzufangen und erläuterungen sind auch nicht sehr viele drin.
Ich will ja nicht meckern, aber wenn ich das bloß abscreib hab ich auch
nix davon...
|
|
reptile
      
Beiträge: 40
|
Verfasst: Mo 02.04.07 18:33
ich habe mir das beispiel mal angesehen und muss bergmann89 recht geben: es wäre schön wenn das ganze besser auskommentiert wäre, nicht jeder kommt so hinter die variablenbezeichnungen.
ich verstehe zwar das vorgehen grob und es funktioniert auch wenn ich es einbaue, aber kann mir jemand die variablen:
M11, M21, M12, M22, Vp1, Vp2, Vs1, Vs2, Vp1_, Vp2_
erklären ?
ich vermute die M-s sind die neuen koordinatenachsen ? aber was ist Vp und Vs?
tut mir leid da kugel-kollision bestimmt schon tausendmal durchgekaut wurde, aber es ist für anfänger kein leichtes thema ^^
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Di 03.04.07 00:12
Der FAQ-Beitrag berechnet den elastischen Stoss für Kugeln verschiedener Grössen und Massen. Bei Billardkugeln gibt es einfachere Formeln, da die Massen und Kugelradien für alle Kugeln gleich sind. Die Kugeln gehen dann z.B. immer im rechten Winkel zueinander auseinander.
|
|
|