Воскресенье, 05.01.2025
Pascal 4 All
[ · Новые сообщения · Участники · Правила форума · Поиск · RSS ]

 

  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: Seqular, Pavel  

Закон отражения
MatrixДата: Пятница, 10.12.2010, 20:40 | Сообщение # 1
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
Задача примерно выглядит таким образом.Нужно нарисовать бильярдный стол,шар и четыре лузы,естественно схематически.Надо,чтобы шарик рандомно катался по этому столу,отскакивая от граней по закону отражения.И если попадает в лузу,то программа заканчивается.В принципе особо сложного я тут ничего не вижу,кроме того,как описать этот закон в этом случае?Можно как-то выразить угол через стороны или ещё как то.Подскажите как действовать лучше..Я паскаль только начал изучать,так что объясняйте по доступнее)))
 
SeqularДата: Суббота, 11.12.2010, 21:53 | Сообщение # 2
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Эх... ща че-то не могу никак паскаль на новой системе развернуть для работы с графикой. Но такую задачу я решал примерно так:
1) Задавал 2 переменные dx, dy - это были изменения соответствующих координат.
2) Очищал заднюю графическую страницу, рисовал объект с новыми координатами x + dx; y + dy.
3) Менял местами страницы. (это для того, чтобы не было мерцания, а все гладенько проигрывалось).
4) Это все в цикле с delay(20) примерно.

Ну и само-собой, при столкновении со стенкой - изменялось это смещение dx и dy, в зависимости от того, с какой стенкой столкнулись..

Например, изначально у нас было dx = 3; dy = 1;
Т.е. с каждым новым фреймом мы перемещаем шарик на 1 пиксел вверх и на 3 - вправо.. Как только x стала равна координате правой (левой) стенки (например, прямоугольник (20,20, 400, 350), (нужно еще учитывать радиус шарика), т.е. (x + r + dx) >= X2 - для отскока от правой стены -- умножаем dx на -1. Вообще, любую переменную смещения умножаем на -1.
Таким образом теперь будем двигаться на dx = -3; dy = 1; т.е. вправо на -3 пиксела (влево на 3 пиксела), вверх на 1 пиксел. Т.е. правильное отражение!

Ну и лузы указать если по углам, то как бы области нарисовать, и если координаты x,y входят в эту область (x <= 40 and y <= 40) - для одного из углов (ширина лузы - 20) то скрываем шарик и выходим из программы. )

Ну надеюсь, ты понял общие идеи


Поддерживаю также проект сообщество молодых сисадминов
 
MatrixДата: Суббота, 11.12.2010, 23:38 | Сообщение # 3
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
Да!Всё в принципе понял,спасибо большое.Я эту задачу пытался решить полностью углубившись в геометрию)).

Сообщение отредактировал Matrix - Суббота, 11.12.2010, 23:44
 
SeqularДата: Суббота, 11.12.2010, 23:45 | Сообщение # 4
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Matrix, Да без проблем, обращайся! Если сделаешь нормально задачку - выкинь в этой теме! Может кому-нибудь еще пригодится!

Поддерживаю также проект сообщество молодых сисадминов
 
MatrixДата: Четверг, 16.12.2010, 02:14 | Сообщение # 5
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
Ок,договорились!

Добавлено (15.12.2010, 22:06)
---------------------------------------------
Вот набросал,только вопрос один есть.Почему у меня шарик не отскакивает от границ х=0 и у=0?У меня он отталкивается от границ конца монитора)).А от других двух границ отталкивается,всё в норме.

Code
uses Graph,CRT;
var x,dx,y,dy,Device,Mode:Integer;
Begin
Device:=0;
InitGraph(Device,Mode,'c:\tp7\BGI');
dx:=1;
dy:=1;
WriteLn('Введите координату x');
ReadLn(x);
WriteLn('Введите координату у');
ReadLn(y);
SetLineStyle(0,0,ThickWidth);
Rectangle(0,0,600,400);
Line(40,0,0,40);
Line(560,0,600,400);
Line(0,360,40,400);
Line(560,400,600,360);
SetLineStyle(0,0,NormWidth);
While x<650 do begin
SetColor(Red);
Circle(x,y,20);
Delay(1500);
SetColor(Black);
Circle(x,y,20);
x:=x+dx;
y:=y+dy;
if (x=578) or (x=0) then dx:=dx*(-1);
if (y=378) or (y=0) then dy:=dy*(-1);
if (x<=40) and (y<=40) then Halt;
if (x>=560) and (y<=40) then Halt;
if (x>=560) and (y>=360) then Halt;
if (x<=40) and (y>=360) then Halt;
end;
END.


Сообщение отредактировал Matrix - Четверг, 16.12.2010, 02:14
 
SeqularДата: Пятница, 17.12.2010, 19:54 | Сообщение # 6
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Не советую в отражении делать равенства. Подправь на
Code
if (x>=578) or (x<=20) then dx:=dx*(-1);  
if (y>=378) or (y<=20) then dy:=dy*(-1);
и посмотри, как будет! Ну там подкалибруй!


Поддерживаю также проект сообщество молодых сисадминов
 
MatrixДата: Пятница, 17.12.2010, 20:30 | Сообщение # 7
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
Спасибо огромное.Подправил на:
Code
if (x>=578) or (x<=22) then dx:=dx*(-1);
if (y>=378) or (y<=22) then dy:=dy*(-1);

Ещё вопрос.Почему по этим осям,при 'x' и 'y' равными нулю,надо отступ брать в 20 пикселей?


Сообщение отредактировал Matrix - Пятница, 17.12.2010, 20:36
 
SeqularДата: Пятница, 17.12.2010, 20:33 | Сообщение # 8
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Потому что ты круг (шар) рисуешь с координатами от центра. А у него еще свой радиус есть! И пока сравниваешь, "если x = 0", то это значит, что центр шара находится в точке 0, а сам шар, получается, уже "влез в стенку наполовину", поэтому и делается поправка.

Вот пример:

Прикрепления: 2661572.gif (3.2 Kb)


Поддерживаю также проект сообщество молодых сисадминов
 
MatrixДата: Пятница, 17.12.2010, 20:37 | Сообщение # 9
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
А да,точно,что-то я забыл это учесть))).Сорри за надоедливость))).
 
SeqularДата: Пятница, 17.12.2010, 20:40 | Сообщение # 10
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Да ничего! Мы все учились с нуля ))
Еще б хорошо было бы в твоей программе реализовать смену графических страниц, чтобы мерцание убрать... Тут я уже плохо помню! Нужно использовать процедуры
Code
setActivePage(N)
и
Code
SetVisualPage(N)
для этого... ) Хотя можно и обойтись


Поддерживаю также проект сообщество молодых сисадминов
 
MatrixДата: Пятница, 17.12.2010, 21:53 | Сообщение # 11
Старый знакомый
Группа: Пользователи
Сообщений: 34
Репутация: 2
Замечания: 0%
Статус: Offline
Мерцания кстати почти нет,благодаря Delay(1500).А таких процедур я кстати пока не знаю.Я думаю можно пока и без них.)Ещё раз спс).
 
SeqularДата: Пятница, 17.12.2010, 22:24 | Сообщение # 12
Хранитель
Группа: Администраторы
Сообщений: 859
Репутация: 35
Статус: Offline
Ну Delay уменьшает скорость )) А вообще суть смены страниц вот в чем:
  • Делаем активной страницу 0;
  • Очищаем ее;
  • Рисуем на ней все, что хотим;
  • Делаем ее видимой;
  • Делаем активной страницу 1;
  • ...
  • ...
  • ...
  • Делаем активной страницу 0;
    и т.д... В общем фишка в том, что переключение страниц просиходит сразу (без мерцания).. А все, что рисуем на невидимой странице - происходит в буфере. Такм образом, получается, что сначала готовим кадр, потом выводим его. Работал бы у меня Graph-модуль, я б тебе пример привел!

    Поддерживаю также проект сообщество молодых сисадминов
  •  
    MatrixДата: Вторник, 21.12.2010, 05:10 | Сообщение # 13
    Старый знакомый
    Группа: Пользователи
    Сообщений: 34
    Репутация: 2
    Замечания: 0%
    Статус: Offline
    Смысл понятен в принципе.Ну я думаю в задании основное мы сделали,а детали пока можно упустить.Но всё-таки с Delay намного лучше проигрывается,не так мерцает,но конечно не идеально)).
     
    Olechka35Дата: Воскресенье, 26.12.2010, 23:59 | Сообщение # 14
    Новичок
    Группа: Пользователи
    Сообщений: 5
    Репутация: 0
    Замечания: 0%
    Статус: Offline
    А подскажите пожалуйста, как в задачке с таким алгоритмом сделать, чтобы шарик при ударе об стенку снижал скорость ну например на 5%. Если увеличивать delay, то экран мерцать начинает, а другого способа не вижу. dx и dy и так маленькие, чтобы их еще пропорционально уменьшать. А если их изначально задавать побольше (ну например не 3 и 1, а 30 и 10, то плохо получается. Шарик или не долетев до стенки уже отражается, или наоборот за пределы поля вылетает). Что то никак не могу придумать(

    Сообщение отредактировал Olechka35 - Воскресенье, 26.12.2010, 23:59
     
    SeqularДата: Понедельник, 27.12.2010, 07:27 | Сообщение # 15
    Хранитель
    Группа: Администраторы
    Сообщений: 859
    Репутация: 35
    Статус: Offline
    Olechka35, оба варианта разумны! Кое-что попробую рассказать подробней:
    1) Если изначально задавать большие dx, dy (самый очевидный способ) - то действительно, отражения будут происходить до стенок (т.к. следующий кадр переместит шарик за стену, поэтому он отражается немного не долетев). Это нам не подходит, значит dx, dy будем оставлять малыми.
    2) Остается delay. На основе этого алгоритма с delay работать не получится, вы правильно заметили. Но обратите внимание на мой пост в этой теме о графических страницах! они избавляют от мерцания! Поэтому сначала мы задаем минимальные dx, dy и маленький delay. Постепенно увеличивая delay мы как раз получим плавное снижение скорости. (размерность delay - в миллисекундах - как раз обеспечит нам большой запас для плавного изменения скорости).


    Поддерживаю также проект сообщество молодых сисадминов
     
    • Страница 1 из 2
    • 1
    • 2
    • »
    Поиск:

    Copyright MyCorp © 2025
    Используются технологии uCoz
    javascript:;" rel="nofollow" onclick="loginPopupForm(); return false;