Вопрос № 183471: Здравствуйте! Прошу помощи в следующем вопросе: Прошу помощи в алгоритме одной очень интересной задачки. На экране в центре вращается полуокружность, а из левого крайнего угла из нарисованой трубки(небольшого диаметра) вылетает шары(окружности)...
Вопрос № 183471:
Здравствуйте! Прошу помощи в следующем вопросе: Прошу помощи в алгоритме одной очень интересной задачки. На экране в центре вращается полуокружность, а из левого крайнего угла из нарисованой трубки(небольшого диаметра) вылетает шары(окружности) разных цветов. Они летят в окружность и когда с ней сталкиваются то происходит 1 из 2 возможных событий. 1)Шарик попадая в плоскость (не в дугу окружности) просто уменьшается в размерах и уничтожается) 2)Шарик отскакивает от дуги и летит в сторону - по
законам математики (угол падения, равен углу отражения).
Собственно с 1 событием нет проблем...перемещаем шарик от трубки к окружности и если он попадает в этот момент времени на отрезок плоскости и его касается, то шарик начинает поворачиваться с окружностью какие то 4 секунды и исчезает. Как поворачивать полуокружность имею представление - через афинные преобразования!
Но вот в чем вопрос - как организовать отскок по математическим законам от дуги полу
окружности. Желательно покажите это на примере математики и кода на Паскале TP7.
Чуть позже сегодня приведу пример того что получилось. Надеюсь с вами, эксперты, собрать эту программу полностью.
uses
Crt,Graph;
const
R=90;{радиус большого шара}
BallColor=15;{цвет большого шара}
FonColor=0;{цвет фона}
ck=3;{сенсорное смещение}
var
x,y,X0,Y0,x1,y1,z1,kx,ky:integer;
z:boolean;
{функция конроля растояния}
function Range:boolean;
var
a,b,c:longint;
begin
c:=R +z1;{гипотенуза}
a:=abs(X0-x1-kx*ck);{катет}
b:=abs(Y0-y1-ky*ck);{катет}
Range:=(a*a+b*b)>(c*c){проверка условия}
end;
{функция контроля цвета пикселя под сенсором}
function Point:boolean;
begin
Point:=GetPixel(x1+kx*(z1+ck),y1+ky*(z1+ck))<>BallColor
end;
{процедура рисования-стирания изображений}
Procedure ShowOS(var a:integer;b:integer);
begin
SetColor(b);{цвет фигуры}
SetFillStyle(1,b);{цвет заполнения}
Circle(x1,y1,z1);{рисуем малый шар}
if a=359 then{ситуация перехода через ноль}
begin{рисуем два сектора}
PieSlice(X0,Y0,359,360,R);
PieSlice(X0,Y0,0,1,R)
end
else PieSlice(X0,Y0,a,a+2,R);{общая ситуация-рисуем один сектор}
a:=(a+1)mod 360{увеличиваем координату}
end;
begin
{запускаем графику}
x:=detect;
InitGraph(x,y,'');
y:=GraphResult;
if y<>0 then{проверка ошибки щапуска}
begin
write('InitGraph error :',y){выводим сообщение об ошибке}
end
else
begin
{центр экрана}
X0:=GetMaxX div 2;
Y0:=GetMaxY div 2;
{общая полготовка к графике}
ClearDevice;{чистим экран}
SetColor(BallColor);{цвер кисти}
SetFillStyle(1,BallColor);{цвет заполнения}
{координаты большого шара}
x:=0;{начальный угол}
y:=180;{конечный угол}
PieSlice(X0,Y0,x,y,R);{рисуем сектор}
{начальные координаты и параметры малого шара}
z:=false;{событие внутри шара}
{направление движения}
kx:=1;
ky:=-1;
{радиус и координаты шара}
z1:=5;
x1:=z1+2;
y1:=GetMaxY-z1-2;
{рисуем трубу}
Line(0,GetMaxY-10,20,GetMaxY-30);
Line(10,GetMaxY,30,GetMaxY-20);
{основной цикл}
repeat
ShowOS(x,FonColor);{стираем изображение}
if Range then
begin{вне шара двигаемся дальше}
x1:=x1+kx;
y1:=y1+ky;
end
else{внутри большого шара}
if Point then
begin{двигаемся дальше, т.к. малый шар ещё не коснулся большого}
x1:=x1+kx;
y1:=y1+ky;
z:=true;
end
else
begin{касание большого шара}
if z then dec(z1)else kx:=-kx;{событие внутри шара: есть уменьшаем радиус
иначе меняем направление}
x1:=x1+kx;{изменяем координаты}
y1:=y1+ky;
end;
{проверка выхода за пределы экрана}
if(x1=0)or(y1=0)or(x1=GetMaxX)or(y1=GetMaxY)or(z1=0)then
begin{востанавливаем начальные координаты}
kx:=1;
ky:=-1;
z1:=5;
x1:=z1+2;
y1:=GetMaxY-z1-2;
z:=false;
end;
ShowOS(y,BallColor);{рисуем новый сектор}
delay(10000){вмзуальная задержка}
until KeyPressed;{ждем любую клавишу}
CloseGraph{закрываем графику}
end;
ReadKey{чистим поток ввода}
end.
вопросы задавайте в мини-форум Удачи!
----- Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч
Ответ отправил: Зенченко Константин Николаевич (Модератор)
Ответ отправлен: 03.06.2011, 21:06
Номер ответа: 267564 Украина, Киев Тел.: +38-097-238-60-03 Адрес: Украина, Киев
Оценка ответа: 5
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 267564
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.