IPB
ЛогинПароль:

 
 Ответить  Открыть новую тему 
> Реализация соударения шаров.., Дайте формулы, пожалуйста..
philip-s
сообщение 14.08.2007 16:43
Сообщение #1





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Филиппс

Репутация: -  0  +


Задача такова, чтобы реализовать нецентральное соударение двух шаров (на плоскости) разных масс и скоростей и рисовать все это на канве (в Дельфи). Я так понимаю, что нужно делать в таймере: вычислять новые координаты, перебирать каждый шар (это если их много), не соприкасается ли он с другим. Когда это произошло, нужно перещитывать скорости и направления шаров. Вот это как раз таки и интересует. По каким формулам можно посчитать углы и скорости?? Перепробывал кучу формул, найденных в книгах и интернете. Не работает даже центральный удар. Может что-нибудь неправильно в самой идее реализации..

Заранее благодарен.

Сообщение отредактировано: philip-s - 14.08.2007 17:51
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.08.2007 17:04
Сообщение #2


Гость






Вот это тоже пробовал?

+ Поищи по форуму, выкладывались реализации (да и формулы тоже) того, что тебе нужно...
 К началу страницы 
+ Ответить 
philip-s
сообщение 14.08.2007 17:45
Сообщение #3





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Филиппс

Репутация: -  0  +


Цитата
Вот это тоже пробовал?


Бильярд является частным случаем (т.к массы шаров одинаковые), что мне не совсем подходит.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.08.2007 17:50
Сообщение #4


Гость






А ты б хотя бы этот, частный, случай реализовал - прежде чем за общее браться... Пока ни строчки твоего кода (даже неправильного работающего) никто не видел...

Сообщение отредактировано: volvo - 14.08.2007 17:54
 К началу страницы 
+ Ответить 
philip-s
сообщение 14.08.2007 21:02
Сообщение #5





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Филиппс

Репутация: -  0  +


Вот код обработчика события таймера. Там почти все закомментировано, т.к содержит несколько вариантов обсчета скоростей. Однако все неправильно считают. Я начал подозревать, что дело не в формулах, а в самой идее реализации.

Прикрепленный файл  procedureCode.txt ( 9.13 килобайт ) Кол-во скачиваний: 622

Подскажите что-нить.. wacko.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.08.2007 22:14
Сообщение #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
сообщение 15.08.2007 0:02
Сообщение #7





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Филиппс

Репутация: -  0  +


В моем случае строчки "x:=x + Vx;" и "y:=y + Vy;" в конструкциях if нужны для отскока от стенки не теряя "шага" (эксперементально доказано smile.gif, т.к при действии силы шары будут, отскакивая от стенки, постоянно снижаться). А чтобы текущий объект двигался есть следущие строчки в конце конструкции обработчика в первом for после второго for:

// Изменяет скорость при действии внешней силы:
Vx:=Vx + Fx / Mass;
Vy:=Vy + Fy / Mass;
// Изменяет координату:
x:=x + Vx * ddt;
y:=y + Vy * ddt;

Кста, ваш вариант просчета скоростей тоже у мя не работает правильно.. sad.gif Я вот думаю, может общие формулы не подходят для всех случаев и нада рассматривать более частные, например при определенных углах будут разные формулы..
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 15.08.2007 0:36
Сообщение #8


Гость






А я твой вариант не менял, я просто отформатировал его так, чтобы видно было, что к чему относится. Уж очень странно выглядят формулы, ощущение - что со скобками напутано. А вникать в логику происходящего в программе просто нет времени, да и поздно уже.
 К началу страницы 
+ Ответить 
Чужак
сообщение 2.09.2007 15:01
Сообщение #9


меркантильный
***

Группа: Пользователи
Сообщений: 161
Пол: Мужской

Репутация: -  6  +


Цитата(philip-s @ 14.08.2007 22:02) *

Вот код обработчика события таймера. Там почти все закомментировано, т.к содержит несколько вариантов обсчета скоростей. Однако все неправильно считают. Я начал подозревать, что дело не в формулах, а в самой идее реализации.
Подскажите что-нить.. wacko.gif

Подозреваю, что ты прав.
Мне кажется, что формула при каждом пересчете дает дискретное значение,
а это задача реального времени. Значение координаты шара постоянно меняется,
и программа постоянно должна его мониторить.Когда я как ты, пытался считать по формулам,
программа у меня вылетала-не знала, какое зачение подставлять-предыдущее или последующее.
Тут надо понимать логику действий.
Попробуй вот такой код. Он "типа корявый", но логика соударений в нем реализована.

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. 



--------------------
Смысл откроется тебе. Красками играя
Жизнь предстанет как поток без конца и края.


В этом мире порой разбиваютсямечты
Но чтобы он стал другой Вдруг в него приходишь ТЫ...

После странствий и скитаний настают другие времена.
Старая волна уходит и приходит новая волна.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 17.07.2025 20:51
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"