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

4 страниц V < 1 2 3 4 >  
 Ответить  Открыть новую тему 
> Моделирование движения шаров
сообщение
Сообщение #41


Профи
****

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

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


Мне бы хотелось, чтобы шарики, при столкновении друг с другом, изменяли угол движения... но добиться этого не удаётся:

{изменяем скорость и угол после столкновения}
procedure after_hit (spee1, speed2 : integer; x1, y1, x2, y2 : integer; angle1, angle2 : single);
var m1, m2 : real;
begin
m1 := value(r1);
m2 := value(r2);
speed1 := round((2*m2*speed2 + (m1-m2)*speed1)/(m1+m2));
speed2 := round((2*m1*speed1 + (m2-m1)*speed2)/(m1+m2));
x1 := round(x1 + speed1*cos(pi-angle1));
y1 := round(y1 + speed1*sin(-angle1));
x2 := round(x2 + speed2*cos(pi-angle2));
y2 := round(y2 + speed2*sin(-angle2));
end;

{проверка на столкновение}
function balls_hit (const r1,r2 : integer; x1,y1,x2,y2 : integer) : boolean;
var
dist : real;
t1, t2, t3, t4, t5: real;
begin
t1 := abs(x2-x1); t2 := sqr(t1);
t3 := abs(y2-y1); t4 := sqr(t3);
t5 := t2 + t4;
dist := sqrt(t5);

balls_hit := (dist < (r1 + r2));
end;

{если шары стлкнулись - изменяем скорость и угол }
procedure balls_hit_2;
begin
if balls_hit(r1,r2,x1,y1,x2,y2) then after_hit (speed1, speed2, x1, y1,x2, y2,angle1,angle2);
end;



но шарики только проводят друг через друга.....

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #42


Профи
****

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

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


Цитата(18192123 @ 22.04.2007 0:21) *


но шарики только проводят друг через друга.....

не пойму, в чём причина?

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #43


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 22.04.2007 0:42) *

не пойму, в чём причина?

Причин несколько.
1. ты снова забываешь сменить углы..
2. одна переменная у тебя называется spee1 (должно быть, видимо, speed1)
3. Ты пересчитываешь параметры, но обратно из процедуры они у тебя не передаются. Чтоб передавались, используй декларацию var.

Можно один вопрос? Зачем ты искусственно увеличиваешь код программы? Тебе кажется, так проще? или так от вас требуют препы? Например, функция balls_hit моогла бы выглядеть много короче..
function balls_hit (r1,r2,x1,y1,x2,y2 : integer) : boolean; 
begin
balls_hit := Sqrt(Sqr(x2-x1)+Sqr(y2-y1)) < r1+r2
end;

Разве так не проще? Все сразу видно..



--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #44


Профи
****

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

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


Цитата(Lapp @ 22.04.2007 11:20) *

Например, функция balls_hit моогла бы выглядеть много короче..
function balls_hit (r1,r2,x1,y1,x2,y2 : integer) : boolean; 
begin
balls_hit := Sqrt(Sqr(x2-x1)+Sqr(y2-y1)) < r1+r2
end;

Разве так не проще? Все сразу видно..

ф-я работала некорректно , компилятор выдавал ошибку 207, и чтобы понять причину этого выражение Sqrt(Sqr(x2-x1)+Sqr(y2-y1)) < r1+r2 было разбито на более простые (пост #27)

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #45


Профи
****

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

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


Цитата(Lapp @ 22.04.2007 11:20) *


3. Ты пересчитываешь параметры, но обратно из процедуры они у тебя не передаются. Чтоб передавались, используй декларацию var.


не совсем тебя поняла....какие параметры я ещё должна описать внутри ф-ции? (всё, что нужно я уже передаю из программы)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #46


Профи
****

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

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


Цитата(Lapp @ 22.04.2007 11:20) *

ты снова забываешь сменить углы..

а как их менять? ( по какой состовляющей? ведь другой шарик - это не граница!)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #47


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 22.04.2007 21:38) *

не совсем тебя поняла....какие параметры я ещё должна описать внутри ф-ции? (всё, что нужно я уже передаю из программы)

Вот смотри - ты вычисляешь переменные:
  x1 := round(x1 + speed1*cos(pi-angle1));
y1 := round(y1 + speed1*sin(-angle1));
x2 := round(x2 + speed2*cos(pi-angle2));
y2 := round(y2 + speed2*sin(-angle2));
end;

- после этого выходишь из процедуры.
Как ты думаешь, что случается с переменными x1,y1,x2,y2? Они просто уничтожаются.
Чтобы они передавались в вызывающую программу, ты должна в описании фрмальных параметров употребить декларацию var :

procedure after_hit (spee1, speed2 : integer; VAR x1, y1, x2, y2 : integer; angle1, angle2 : single);

То же самое касается других параметров, которые ты хочешь передать не только туда, но и обратно.
Это понятно? Прочти про это в учебнике, плз.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #48


Профи
****

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

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


Цитата(Lapp @ 23.04.2007 1:47) *



То же самое касается других параметров, которые ты хочешь передать не только туда, но и обратно.
Это понятно? Прочти про это в учебнике, плз.

Да, понятно. Извини, с этим я "стормозила" по полной программе.

Но у меня шарики всё равно проходят друг через друга...

procedure after_hit (var speed1, speed2 : integer; var x1, y1, x2, y2 : integer; var angle1, angle2 : single);
var m1, m2 : real;
begin
m1 := value(r1);
m2 := value(r2);
angle1 := -angle1;
angle2 := pi - angle2;
speed1 := round((2*m2*speed2 + (m1-m2)*speed1)/(m1+m2));
speed2 := round((2*m1*speed1 + (m2-m1)*speed2)/(m1+m2));
x1 := round(x1 + speed1*cos(angle1));
y1 := round(y1 + speed1*sin(angle1));
x2 := round(x2 + speed2*cos(angle2));
y2 := round(y2 + speed2*sin(angle2));
end;


wacko.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #49


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 23.04.2007 22:13) *

Но у меня шарики всё равно проходят друг через друга...

Значит, так.
1. Ты выбрала очень неудобное представление - через углы (модули скоростей и углы). Я рекомендовал тебе давно иметь просто Vx и Vy для каждого шара вместо модуля скорости и угла. Ты бы избежала очень многих проблем (это я все брюзжу про то, что то, что кажется на первый взгляд сложнее, на самом деле легче).

2. Тебе совсем не нужно вычислять координаты (x и y) в этой процедуре. Вычисляй только параметры скорости (в твоем представлении - модуль и угол). Только эти параметры используй в загаловке процедуры и описывай их как var.

3. Скорость персчитывай по ЗСИ по каждой компоненте вектора (Vx и Vy). Для этого сначала высчитай эти компоненты (как модуль скорости умножить на косинус и синус угла), потом для каждой реши уравнение ЗСИ и пересчитай. По этим новым компонентам рассчитай новый модуль скорости и угол. Эти значения нужно вернуть в вызывающую программу.

Вот так все будет работать..

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


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #50


Профи
****

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

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


Цитата(Lapp @ 24.04.2007 11:14) *


3. Скорость персчитывай по ЗСИ по каждой компоненте вектора (Vx и Vy). Для этого сначала высчитай эти компоненты (как модуль скорости умножить на косинус и синус угла), потом для каждой реши уравнение ЗСИ и пересчитай. По этим новым компонентам рассчитай новый модуль скорости и угол. Эти значения нужно вернуть в вызывающую программу.


вот что написала:

Vx1 := speed1*cos(angle1);
Vy1 := speed1*sin(angle1);
Vx2 := speed2*cos(angle2);
Vy2 := speed2*sin(angle2);




дальше не пойму...объясни, пожалуйста, подробнее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #51


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Дальше для каждой компоненты записываешь (на бумажке) ЗСИ и ЗСЭ:

m1*Vx1 + m2*Vx2 = m1*Vx1' + m2*Vx2
m1*Vx1^2 + m2*Vx2^2 = m1*Vx1'^2 + m2*Vx2'^2

(Для Vy аналогично).

Дальше решаешь эти две системы (тоже на бумажке). Находишь Vx1' и Vx2' (а также Vy1' и Vy2'). Заводишь в программу эти решения:

Vx1 := {выражение через Vx1 и Vx2 }
Vx2 := {выражение через Vx1 и Vx2 }
Vy1 := {выражение через Vy1 и Vy2 }
Vy2 := {выражение через Vy1 и Vy2 }

После этого находишь модули и углы:

V1 := Sqrt(Vx1*Vx1+Vy1*Vy1);
Angle1 := ArcTan(Vy1/Vx1);
if Abs(Vx1)<1e-5 then begin
Angle1:=Pi/2;
if Vy1<0 then Angle1:=-Angle1
end
else begin
Angle1:=ArcTan(Vy1/Vx1);
if Vx<0 then Angle1:=-Angle1
end;

- и плюс аналогично для второго шарика.
Сделай и выложи тут, я проверю.
Если все еще непонятно - говори.

Теперь ты видишь, сколько мороки с углами? Если бы не они, то все, что нужно было бы в этой процедуре - это те четыре строчки с решениями ЗСИ и ЗСЭ..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #52


Профи
****

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

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


Цитата(Lapp @ 24.04.2007 23:10) *

Находишь Vx1' и Vx2' (а также Vy1' и Vy2'). Заводишь в программу эти решения:

Vx1 := {выражение через Vx1 и Vx2 }
Vx2 := {выражение через Vx1 и Vx2 }
Vy1 := {выражение через Vy1 и Vy2 }
Vy2 := {выражение через Vy1 и Vy2 }


ты имел ввиду
Vx1' := {выражение через Vx1 и Vx2 }
Vx2' := {выражение через Vx1 и Vx2 }
Vy1' := {выражение через Vy1 и Vy2 }
Vy2' := {выражение через Vy1 и Vy2 }
?

Abs(Vx1)< 1e-5 - что такое 1е-5?

А морока с углами - не куда не денешься, как сказали, так и приходиться делать....( имею ввиду в универе)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #53


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 25.04.2007 0:10) *

ты имел ввиду
Vx1' :=
?
Нет, я имел в виду то, что написал. Пересчитываем значения через старые и кладем их в те же самые переменные. Логично? Это программирование уже, математика кончилась..
Цитата(18192123 @ 25.04.2007 0:10) *

Abs(Vx1)< 1e-5 - что такое 1е-5?
Это аналог сравнения с нулем. Математически формула теряет смысл при Vx1=0. Но реально в программе это может произойти и раньше, когда модуль этой величины становится слишком маленьким - и возникнет переполнение, сбой в программе. Для твоей программы вполне достаточно приблизительно сравнения с 0.0001 (то есть 1e-5). Я взял это наобум, но суть выдержана.
Цитата(18192123 @ 25.04.2007 0:10) *

А морока с углами - не куда не денешься, как сказали, так и приходиться делать....( имею ввиду в универе)
Ну, слава Богу - хоть какое-то объяснение есть.. smile.gif


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #54


Профи
****

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

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


Цитата(Lapp @ 24.04.2007 23:10) *

Дальше для каждой компоненты записываешь (на бумажке) ЗСИ и ЗСЭ:

m1*Vx1 + m2*Vx2 = m1*Vx1' + m2*Vx2
m1*Vx1^2 + m2*Vx2^2 = m1*Vx1'^2 + m2*Vx2'^2

(Для Vy аналогично).

Дальше решаешь эти две системы (тоже на бумажке). Находишь Vx1' и Vx2' (а также Vy1' и Vy2'). Заводишь в программу эти решения:


ох...что-то я залезла в дебри.....

Сообщение отредактировано: 18192123 -


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #55


Профи
****

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

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


перед тем, как шарики сталкиваются, программа вылетает и выдаёт ошибку 207....первое, о чём подумала- стек переполнился из длинных выражений для скоростей, разбила на более простые - не помогло...


procedure after_hit (var speed1, speed2 : integer; var angle1, angle2 : single);
var m1, m2 : real;
Vx1, Vy1, Vx2, Vy2 : real;
t1, t2, t3, t4, t5, t6, t7, t8, t9, t10 : real;
begin
m1 := value®;
m2 := value®;
Vx1 := speed1*cos(angle1);
Vy1 := speed1*sin(angle1);
Vx2 := speed2*cos(angle2);
Vy2 := speed2*sin(angle2);
t1 := m2/(m1*(m2 + m1));
t2 := (Vx1 - Vx2);
t3 := (m1*m1*m2 - m1);
Vx1 := Vx1 + t1*t2*t3;
t4 := (Vy1 - Vy2);
Vy1 := Vy1 + t1*t4*t3;
t5 := Vx1*m1 + m2*Vx2;
t6 := m1*m1*Vx1;
t7 := m1*m1*m2*Vx2;
vx2 := (t5 - t6 + t7)/(m2 + m1);
t8 := Vy1*m1 + m2*Vy2;
t9 := m1*m1*Vy1;
t10 := m1*m1*m2*Vy2;
vy2 := (t8 - t9 + t10)/(m2 + m1);
speed1 := round(sqrt(Vx1*Vx1 + Vy1*Vy1));
Angle1 := Arctan(Vy1/Vx1);
if abs(Vx1) < 1e - 5 then begin
Angle1 := pi/2;
if Vy1 < 0 then Angle1 := - angle1
end
else begin
Angle1 := ArcTan(Vy1/Vx1);
if Vx1 < 0 then Angle1 := - angle1
end;
speed2 := round(sqrt(Vx2*Vx2 + Vy2*Vy2));
Angle2 := Arctan(Vy2/Vx2);
if abs(Vx2) < 1e - 5 then begin
Angle2 := pi/2;
if Vy2 < 0 then Angle2 := - angle2
end
else begin
Angle2 := ArcTan(Vy2/Vx2);
if Vx2 < 0 then Angle2 := - angle2
end;
end;



 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #56


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 26.04.2007 20:01) *

перед тем, как шарики сталкиваются, программа вылетает и выдаёт ошибку 207....первое, о чём подумала- стек переполнился из длинных выражений для скоростей, разбила на более простые - не помогло...

Почему, собственно, стек?.. blink.gif А, ты что ли о стеке ко-процессора?.. Нет, это маловероятно, а главное - это все равно означает ошибку, а не большие формулы smile.gif.
Короче, либо корень из отрицательного числа, либо перевод в целые (round) очень большого числа..

Я прогнал ее с некими среднепотолочными значениями - все прошло нормально, не повезло мне.
Ищи ошибку в математике. Не найдешь - приходи, будем искать вместе smile.gif.

Кстати, а в какой строке это происходит? Это же ключ к поиску! Обязательно обрати внимание.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #57


Профи
****

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

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


Ошибок в математике не нашла.... (но у меня получилось 2 набора значений для Vx1' и Vx2' (а также Vy1' и Vy2'), подставляла каждое - результат тот же)

в какой строке это происходит - не разберусь...



Эскизы прикрепленных изображений
Прикрепленное изображение Прикрепленное изображение

Прикрепленные файлы
Прикрепленный файл  CIRCLES8.PAS ( 10.55 килобайт ) Кол-во скачиваний: 370
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #58


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 27.04.2007 23:41) *

в какой строке это происходит - не разберусь...

В чем ты работаешь? в ТР/ВР или FPC?


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #59


Профи
****

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

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


Цитата(Lapp @ 27.04.2007 23:49) *

В чем ты работаешь? в ТР/ВР или FPC?

ТР
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #60


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 28.04.2007 0:05) *

ТР

ТР обычно показывает строку с ошибкой.. Странно.

Хорошо, сделай, пожалуйста, вот, что.
Перед передачей параметров в эту процедуру, распечатай их. И покажи тут результат. Сделаешь?


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





- Текстовая версия 28.03.2024 19:51
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name