Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Модуль GRAPH.

Автор: Psychologist 18.03.2008 23:56

Добрый вечер.
Вот задача: нарисовать и анимировать неск. объектов. (ну вообще-то задача намного длиннее, но не суть...).
Код программы:

Program Lab_09;
Uses
GRAPH, CRT;
Type
TPoint=object
x , y : Integer;
ox, oy : Integer;
color : Word;
R : Integer;
alpha : Real;
step : Real;
Procedure Show;
Procedure Hide;
Procedure Move;
end;

Procedure TPoint.Show;
Begin
putPixel (x, y, color);
end;

Procedure TPoint.Hide;
Begin
putPixel (x, y, black);
end;

Procedure TPoint.Move;
Begin
Hide;
if (abs(alpha)>=180) or (abs(alpha)<=0) then step:=step*(-1);
alpha:=alpha+step;
x:=round (cos(alpha*Pi/180)*R)+ox;
y:=round (sin(alpha*Pi/180)*R)+oy;
Show;
end;

Var
P1, P2, P3, C1, C2 : TPoint;
a : Integer;
grDr, grMode : Integer;
Begin
grDr:=detect;
grMode:=0;
InitGraph (grDr, grMode, '');

Line (000,240,640,240);
Line (214,000,214,240);
Line (426,000,426,240);
Line (320,240,320,480);
Rectangle (1,1,639,479);

P1.R:=75;
P1.ox:=110; P1.oy:=120;
P1.step:=0.5;
P1.color:=yellow;
P1.Show;

P2.R:=95;
P2.ox:=320; P2.oy:=120;
P2.step:=-0.5;
P2.color:=green;
P2.Show;

P3.R:=55;
P3.ox:=530; P3.oy:=120;
P3.step:=0.3;
P3.color:=white;
P3.Show;

Repeat
P1.Move;
P2.Move;
P3.Move;
Delay (1000);
Until KeyPressed;

closeGraph;
End.

Скачать исходник можно здесь: http://narod.ru/disk/11290000/LAB_09.PAS

Проблема заключается в том, что траектория движение точек - дуга. Программа, после каждого перемещения смотрит: не достигла ли точка 0 или 180 градусов. И если точка доехала до указанных углов, то начинается обратное действие. Всё вроде норм. Только последний объект почему-то "разворачивается" только при 180 градусах, а при 0 - нет. Скажите, в чём ошибка?

Автор: volvo 19.03.2008 0:55

Во-первых, ты не инициализировал поле Angle, а во-вторых, лучше:

...
if (abs(alpha)>=180) or (abs(alpha)<abs(step)) then step:=step*(-1);
...


Автор: Psychologist 19.03.2008 1:02

volvo, Огромное спасибо! IF исправил. (Angle - у меня это alpha).

Автор: volvo 19.03.2008 1:17

Ну, какая разница. Оно у тебя все равно не инициализировано. А надо бы, это источник ошибок... Кстати, у тебя тема-то какая? ООП или графика? Ибо если ООП - то я бы не принял такую программу: основной принцип ООП нарушен.

Автор: Psychologist 19.03.2008 1:24

ООП, конечно. Но сдавать, слава Богу, не завтра. Я ещё доработаю, как виртуальные методы (сли ты по поводу 3-х кратного описания точек).

Автор: volvo 19.03.2008 1:29

Нет, я по поводу отсутствия инкапсуляции... Вот этого:

Цитата
   P1.R:=75;
P1.ox:=110; P1.oy:=120;
P1.step:=0.5;
P1.color:=yellow;
быть не должно. К полям объекта должны иметь доступ только методы объекта.

Автор: Psychologist 19.03.2008 23:12

Продолжение... rolleyes.gif
Теперь (по идее) должна появиться окружность в нижнем прямоугольнике и действовать так же, как точки (двигаться по дуге, менять направление при 0 и 180 градусах).
Я сделал вот так, ничего не изменилось:

Program Lab_09;
Uses
GRAPH, CRT;
Type
TPoint=object
x , y : Integer;
ox, oy : Integer;
color : Word;
R : Integer;
alpha : Real;
step : Real;
Procedure Show;
Procedure Hide;
Procedure Move;
end;

TCircle=object (TPoint)
RCirc : Integer;
Procedure Show;
Procedure Hide;
end;

{//--------------------TPoint-------------------//}
Procedure TPoint.Show;
Begin
putPixel (x, y, color);
end;

Procedure TPoint.Hide;
Begin
putPixel (x, y, black);
end;

Procedure TPoint.Move;
Begin
Hide;
if (abs(alpha)>=180) or (abs(alpha)<abs(step)) then step:=step*(-1);
alpha:=alpha+step;
x:=round (cos(alpha*Pi/180)*R)+ox;
y:=round (sin(alpha*Pi/180)*R)+oy;
Show;
end;
{//------------------END_TPoint-----------------//}

{//-------------------TCircle-------------------//}
Procedure TCircle.Show;
Begin
Circle (ox, oy, RCirc);
end;

Procedure TCircle.Hide;
Begin
SetColor (black);
Circle (ox, oy, RCirc);
end;
{//-----------------END_TCircle-----------------//}

Var
P1, P2, P3, C1, C2 : TPoint;
a : Integer;
grDr, grMode : Integer;
Begin
{//--------------------GRAPH--------------------//}
grDr:=detect;
grMode:=0;
InitGraph (grDr, grMode, '');
{//------------------END_GRAPH------------------//}

{//--------------------TABLE--------------------//}
SetColor (green);
Line (000,240,640,240);
Line (214,000,214,240);
Line (426,000,426,240);
Line (320,240,320,480);
Rectangle (1,1,639,479);
{//------------------END_TABLE------------------//}

SetColor (white);

{//-------------------PIXELES-------------------//}
P1.R:=75;
P1.ox:=110; P1.oy:=120;
P1.step:=0.5;
P1.color:=yellow;
P1.Show;
OutTextXY (20, 220, 'R=75 | Step=0.5');

P2.R:=95;
P2.ox:=320; P2.oy:=120;
P2.step:=-0.5;
P2.color:=green;
P2.Show;
OutTextXY (234, 220, 'R=95 | Step=-0.5');

P3.R:=55;
P3.ox:=530; P3.oy:=120;
P3.step:=0.3;
P3.color:=white;
P3.Show;
OutTextXY (446, 220, 'R=55 | Step=0.3');
{//-----------------END_PIXELES-----------------//}

{//-------------------CIRCLES-------------------//}
C1.R:=75;
C1.ox:=160; C1.oy:=360;
C1.step:=0.5;
SetColor (red);
C1.Show;

Repeat
P1.Move;
P2.Move;
P3.Move;
C1.Move;
Delay (1000);
Until KeyPressed;

closeGraph;
End.

В чём ошибка?

Автор: volvo 19.03.2008 23:30

Во-первых, C1 и C2 - это окружности, а значит - тип TCircle... А во-вторых - для того, чтобы вызвать из метода предка (Move) метод потомка (Hide/Show), надо использовать виртуальные функции, иначе будут вызываться одноименные методы объекта того же уровня, из которого вызывается Move...

P.S. Не забудь про конструкторы, иначе будут проблемы. yes2.gif

Автор: Psychologist 19.03.2008 23:47

volvo, ещё раз СПС!
Про тип, конечно, забыл, а вот с виртуальными методами прйдётся сейчас повозиться...