![]() |
![]() ![]() |
![]() |
18192123 |
![]()
Сообщение
#41
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Мне бы хотелось, чтобы шарики, при столкновении друг с другом, изменяли угол движения... но добиться этого не удаётся:
{изменяем скорость и угол после столкновения}
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 - 21.04.2007 23:23 |
18192123 |
![]()
Сообщение
#42
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
|
Lapp |
![]()
Сообщение
#43
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
не пойму, в чём причина? Причин несколько. 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;
Разве так не проще? Все сразу видно.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#44
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Например, функция 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 - 22.04.2007 15:33 |
18192123 |
![]()
Сообщение
#45
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
|
18192123 |
![]()
Сообщение
#46
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
|
Lapp |
![]()
Сообщение
#47
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
не совсем тебя поняла....какие параметры я ещё должна описать внутри ф-ции? (всё, что нужно я уже передаю из программы) Вот смотри - ты вычисляешь переменные: 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); То же самое касается других параметров, которые ты хочешь передать не только туда, но и обратно. Это понятно? Прочти про это в учебнике, плз. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#48
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
То же самое касается других параметров, которые ты хочешь передать не только туда, но и обратно. Это понятно? Прочти про это в учебнике, плз. Да, понятно. Извини, с этим я "стормозила" по полной программе. Но у меня шарики всё равно проходят друг через друга...
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;
![]() |
Lapp |
![]()
Сообщение
#49
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Но у меня шарики всё равно проходят друг через друга... Значит, так. 1. Ты выбрала очень неудобное представление - через углы (модули скоростей и углы). Я рекомендовал тебе давно иметь просто Vx и Vy для каждого шара вместо модуля скорости и угла. Ты бы избежала очень многих проблем (это я все брюзжу про то, что то, что кажется на первый взгляд сложнее, на самом деле легче). 2. Тебе совсем не нужно вычислять координаты (x и y) в этой процедуре. Вычисляй только параметры скорости (в твоем представлении - модуль и угол). Только эти параметры используй в загаловке процедуры и описывай их как var. 3. Скорость персчитывай по ЗСИ по каждой компоненте вектора (Vx и Vy). Для этого сначала высчитай эти компоненты (как модуль скорости умножить на косинус и синус угла), потом для каждой реши уравнение ЗСИ и пересчитай. По этим новым компонентам рассчитай новый модуль скорости и угол. Эти значения нужно вернуть в вызывающую программу. Вот так все будет работать.. PS Представление в виде модуля и угла удобно только в реальном пространстве. Если осилишь - переделай всю прогу, замени их на компоненты по осям. Ты сама увидишь, насколько будет проще. Я уж не говорю, что на том способе, который я предлагал в начале (абстрактные координаты) ты могла бы сэкономить себе много дней времени.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#50
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
3. Скорость персчитывай по ЗСИ по каждой компоненте вектора (Vx и Vy). Для этого сначала высчитай эти компоненты (как модуль скорости умножить на косинус и синус угла), потом для каждой реши уравнение ЗСИ и пересчитай. По этим новым компонентам рассчитай новый модуль скорости и угол. Эти значения нужно вернуть в вызывающую программу. вот что написала:
Vx1 := speed1*cos(angle1);
Vy1 := speed1*sin(angle1);
Vx2 := speed2*cos(angle2);
Vy2 := speed2*sin(angle2);
дальше не пойму...объясни, пожалуйста, подробнее. |
Lapp |
![]()
Сообщение
#51
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Дальше для каждой компоненты записываешь (на бумажке) ЗСИ и ЗСЭ:
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; - и плюс аналогично для второго шарика. Сделай и выложи тут, я проверю. Если все еще непонятно - говори. Теперь ты видишь, сколько мороки с углами? Если бы не они, то все, что нужно было бы в этой процедуре - это те четыре строчки с решениями ЗСИ и ЗСЭ.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#52
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Находишь 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? А морока с углами - не куда не денешься, как сказали, так и приходиться делать....( имею ввиду в универе) |
Lapp |
![]()
Сообщение
#53
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
ты имел ввиду Vx1' := ? Abs(Vx1)< 1e-5 - что такое 1е-5? А морока с углами - не куда не денешься, как сказали, так и приходиться делать....( имею ввиду в универе) ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#54
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Дальше для каждой компоненты записываешь (на бумажке) ЗСИ и ЗСЭ: 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 - 25.04.2007 18:51 Эскизы прикрепленных изображений ![]() |
18192123 |
![]()
Сообщение
#55
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
перед тем, как шарики сталкиваются, программа вылетает и выдаёт ошибку 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(r);
m2 := value(r);
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;
|
Lapp |
![]()
Сообщение
#56
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
перед тем, как шарики сталкиваются, программа вылетает и выдаёт ошибку 207....первое, о чём подумала- стек переполнился из длинных выражений для скоростей, разбила на более простые - не помогло... Почему, собственно, стек?.. ![]() ![]() Короче, либо корень из отрицательного числа, либо перевод в целые (round) очень большого числа.. Я прогнал ее с некими среднепотолочными значениями - все прошло нормально, не повезло мне. Ищи ошибку в математике. Не найдешь - приходи, будем искать вместе ![]() Кстати, а в какой строке это происходит? Это же ключ к поиску! Обязательно обрати внимание. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#57
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Ошибок в математике не нашла.... (но у меня получилось 2 набора значений для Vx1' и Vx2' (а также Vy1' и Vy2'), подставляла каждое - результат тот же)
в какой строке это происходит - не разберусь... Эскизы прикрепленных изображений ![]() ![]() Прикрепленные файлы ![]() |
Lapp |
![]()
Сообщение
#58
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
в какой строке это происходит - не разберусь... В чем ты работаешь? в ТР/ВР или FPC? -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
18192123 |
![]()
Сообщение
#59
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
|
Lapp |
![]()
Сообщение
#60
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
ТР ТР обычно показывает строку с ошибкой.. Странно. Хорошо, сделай, пожалуйста, вот, что. Перед передачей параметров в эту процедуру, распечатай их. И покажи тут результат. Сделаешь? -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
![]() ![]() |
![]() |
Текстовая версия | 18.07.2025 11:12 |