![]() |
![]() ![]() |
![]() |
philip-s |
![]() ![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Реальное имя: Филиппс Репутация: ![]() ![]() ![]() |
Задача такова, чтобы реализовать нецентральное соударение двух шаров (на плоскости) разных масс и скоростей и рисовать все это на канве (в Дельфи). Я так понимаю, что нужно делать в таймере: вычислять новые координаты, перебирать каждый шар (это если их много), не соприкасается ли он с другим. Когда это произошло, нужно перещитывать скорости и направления шаров. Вот это как раз таки и интересует. По каким формулам можно посчитать углы и скорости?? Перепробывал кучу формул, найденных в книгах и интернете. Не работает даже центральный удар. Может что-нибудь неправильно в самой идее реализации..
Заранее благодарен. Сообщение отредактировано: philip-s - 14.08.2007 17:51 |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Вот это тоже пробовал?
+ Поищи по форуму, выкладывались реализации (да и формулы тоже) того, что тебе нужно... |
philip-s |
![]()
Сообщение
#3
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Реальное имя: Филиппс Репутация: ![]() ![]() ![]() |
Цитата Вот это тоже пробовал? Бильярд является частным случаем (т.к массы шаров одинаковые), что мне не совсем подходит. |
volvo |
![]()
Сообщение
#4
|
Гость ![]() |
А ты б хотя бы этот, частный, случай реализовал - прежде чем за общее браться... Пока ни строчки твоего кода (даже неправильного работающего) никто не видел...
Сообщение отредактировано: volvo - 14.08.2007 17:54 |
philip-s |
![]()
Сообщение
#5
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Реальное имя: Филиппс Репутация: ![]() ![]() ![]() |
Вот код обработчика события таймера. Там почти все закомментировано, т.к содержит несколько вариантов обсчета скоростей. Однако все неправильно считают. Я начал подозревать, что дело не в формулах, а в самой идее реализации.
![]() Подскажите что-нить.. ![]() |
volvo |
![]()
Сообщение
#6
|
Гость ![]() |
Насколько я вижу, у тебя не будет обновляться положение шаров, поскольку изменение координат X и Y происходит только при касании границы, а откуда взяться этому касанию?
Вот так попробуй: procedure TForm1.Timer1Timer(Sender: TObject);
var
i, j, dx, dy: integer;
vxOld, vyOld: integer;
begin
for i := 1 to Amount do begin
with Balls[i] do begin
if (X <= R) or (X >= PaintBox1.Width - R) then Vx := -Vx;
x := x + Vx; // Изменение координаты - в любом случае, ВНЕ If-а
if (Y <= R) or (Y >= PaintBox1.Height - R) then Vy := -Vy;
y := y + Vy; // аналогично
end;
for j := 1 to Amount do begin
if i <> j then begin
dx := Balls[i].x + Balls[i].vx - Balls[j].x - Balls[j].vx;
dy := Balls[i].y + Balls[i].vy - Balls[j].y - Balls[j].vy;
if sqrt(dx*dx + dy*dy) <= Balls[i].R + Balls[j].R then begin
VxOld:=Balls[i].Vx;
VyOld:=Balls[i].Vy;
Balls[i].Vx:=Trunc(
(
(Balls[i].Mass-Balls[j].Mass)*VxOld + 2*Balls[j].Mass*Balls[j].Vx
) /
(Balls[i].Mass+Balls[j].Mass)
);
Balls[i].Vy:=Trunc(
(
(Balls[i].Mass-Balls[j].Mass)*VyOld + 2*Balls[j].Mass*Balls[j].Vy
) /
(Balls[i].Mass+Balls[j].Mass)
);
Balls[j].Vx:=Trunc(
(
(Balls[j].Mass-Balls[i].Mass) * Balls[j].Vx + 2*Balls[i].Mass*VxOld
) /
(Balls[i].Mass+Balls[j].Mass)
);
Balls[j].Vy := Trunc(
(
(Balls[j].Mass-Balls[i].Mass) * Balls[j].Vy + 2*Balls[i].Mass*VyOld
) /
(Balls[i].Mass+Balls[j].Mass)
);
end;
end;
end;
end;
UpdatePic;
//
end;
Обрати внимание на то, КАК у тебя вычисляются Vx и Vy. Ты уверен, что ты именно этого хочешь, либо напутал со скобками? |
philip-s |
![]()
Сообщение
#7
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Реальное имя: Филиппс Репутация: ![]() ![]() ![]() |
В моем случае строчки "x:=x + Vx;" и "y:=y + Vy;" в конструкциях if нужны для отскока от стенки не теряя "шага" (эксперементально доказано
![]() // Изменяет скорость при действии внешней силы:
Vx:=Vx + Fx / Mass;
Vy:=Vy + Fy / Mass;
// Изменяет координату:
x:=x + Vx * ddt;
y:=y + Vy * ddt;
Кста, ваш вариант просчета скоростей тоже у мя не работает правильно.. ![]() |
volvo |
![]()
Сообщение
#8
|
Гость ![]() |
А я твой вариант не менял, я просто отформатировал его так, чтобы видно было, что к чему относится. Уж очень странно выглядят формулы, ощущение - что со скобками напутано. А вникать в логику происходящего в программе просто нет времени, да и поздно уже.
|
Чужак |
![]()
Сообщение
#9
|
![]() меркантильный ![]() ![]() ![]() Группа: Пользователи Сообщений: 161 Пол: Мужской Репутация: ![]() ![]() ![]() |
Вот код обработчика события таймера. Там почти все закомментировано, т.к содержит несколько вариантов обсчета скоростей. Однако все неправильно считают. Я начал подозревать, что дело не в формулах, а в самой идее реализации. Подскажите что-нить.. ![]() Подозреваю, что ты прав. Мне кажется, что формула при каждом пересчете дает дискретное значение, а это задача реального времени. Значение координаты шара постоянно меняется, и программа постоянно должна его мониторить.Когда я как ты, пытался считать по формулам, программа у меня вылетала-не знала, какое зачение подставлять-предыдущее или последующее. Тут надо понимать логику действий. Попробуй вот такой код. Он "типа корявый", но логика соударений в нем реализована.
program Sharik2;
uses graph,crt;
var Gd, Gm, X, Y, R, n: Integer; Napr: string;
X1,Y1,R1,n1, Napr1: Integer;
begin
Gd := Detect; InitGraph(Gd, Gm, ' ');
X:=120; Y:=240; R:=20; Napr:='NP'; n:=1;
X1:=220; Y1:=230; R1:=15; Napr1:=6; n1:=1;
repeat
setcolor(15);
Line(20, 40,20, 440); Line(20,40,620,40);
Line(620,40,620,440); Line(620,440,20,440);
Circle(X,Y,R); Circle(X1,Y1,R1); {Line(X,Y,X1,Y1);--эта линия не обязательна}
delay(400);
setcolor(0);
Circle(X,Y,R); Circle(X1,Y1,R1); Line(X,Y,X1,Y1);
if Napr='VP' then begin
X:=X+n; Y:=Y-n;
end;
if Napr='NP' then begin
X:=X+n; Y:=Y+n;
end;
if Napr='NL' then begin
X:=X-n; Y:=Y+n;
end;
if Napr='VL' then begin
X:=X-n; Y:=Y-n;
end;
if Y=40 then begin
if Napr='VP' then Napr:='NP';
if Napr='VL' then Napr:='NL';
end;
if X=620 then begin
if Napr='VP' then Napr:='VL';
if Napr='NP' then Napr:='NL';
end;
if Y=440 then begin
if Napr='NP' then Napr:='VP';
if Napr='NL' then Napr:='VL';
end;
if X=20 then begin
if Napr='VL' then Napr:='VP';
if Napr='NL' then Napr:='NP';
end;
if Napr1=2 then begin
X1:=X1+n1; Y1:=Y1-n1;
end;
if Napr1=4 then begin
X1:=X1+n1; Y1:=Y1+n1;
end;
if Napr1=6 then begin
X1:=X1-n1; Y1:=Y1+n1;
end;
if Napr1=8 then begin
X1:=X1-n1; Y1:=Y1-n1;
end;
if Y1=40 then begin
if Napr1=2 then Napr1:=4;
if Napr1=8 then Napr1:=6;
end;
if X1=620 then begin
if Napr1=2 then Napr1:=8;
if Napr1=4 then Napr1:=6;
end;
if Y1=440 then begin
if Napr1=4 then Napr1:=2;
if Napr1=6 then Napr1:=8;
end;
if X1=20 then begin
if Napr1=8 then Napr1:=2;
if Napr1=6 then Napr1:=4;
end;
if (abs(X-X1)<(R1+R)/2) and (abs(Y-Y1)<(R1+R)/2) then
begin
if Napr='VP' then Napr:='NL';
if Napr='VL' then Napr:='NP';
if Napr='NP' then Napr:='VL';
if Napr='NL' then Napr:='VP';
if Napr1=2 then Napr1:=6;
if Napr1=4 then Napr1:=8;
if Napr1=6 then Napr1:=2;
if Napr1=8 then Napr1:=4;
end;
until keypressed;
CloseGraph
end.
-------------------- Смысл откроется тебе. Красками играя
Жизнь предстанет как поток без конца и края. В этом мире порой разбиваютсямечты Но чтобы он стал другой Вдруг в него приходишь ТЫ... После странствий и скитаний настают другие времена. Старая волна уходит и приходит новая волна. |
![]() ![]() |
![]() |
Текстовая версия | 17.07.2025 20:51 |