это быстро и бесплатно
Оформите заказ сейчас и получите скидку 100 руб.!
ID (номер) заказа
3710838
Ознакомительный фрагмент работы:
1. Основные идеи
В первую очередь создадим модуль для приложения, содержащий необходимые классы для отображения и перемещения картинки сердца со стрелой. Модуль под названием Heart включает два основных класса, которые будут использоваться в программе: класс объекта, отображающего сердце и класс объекта, отображающего стрелу. При этом стрела будет состоять из трех независимых объектов: хвост, стержень и наконечник стрелы.
Добавим функциональность для перемещения сердца со стрелой и поворота стрелы вместе с ее составными элементами. Понадобится один абстрактный класс DisplayObject для хранения координат и размеров объектов, а также его подкласс RotatableObject, выполняющий поворот объекта. Подклассами RotatableObject будет стрела и его части. Также потребуется добавить вспомогательный класс, не подлежащий отображению на экране, роль которого выполнить поворот точки на определенный угол относительно некоего центра.
Чтобы сымитировать положение стрелы внутри сердца, сделаем правую часть сердца фигурой, залитой цветом фона. Так как возникают сложности выполнить такую заливку, поскольку она зависит не только от контура полуседрца, но и от прочих нарисованных объектов, то будем перед перемещением объектов в основной программе очищать экран от прошлых закрашиваний. Поэтому в модуле у классов не будет метода hide, удаляющего объект с экрана.
2. Базовый класс отображаемых на экране объектов
Для того чтобы отобразить и переместить на экране некую фигуру необходимо знать ее координаты, размер, цвет контура и методы рисования и перемещения.
Сделаем свойства закрытыми.
{Abstract Class DisplayObject}
DisplayObject = object
private
_x,_y,_width,_height:integer;
_color:word;
public
constructor init(xx,yy,wid,hei:integer;color:word);
function x:integer;
function y:integer;
function width:integer;
function height:integer;
function getColor:word;
procedure draw; virtual;
procedure move(newX,newY:integer);
end;
В процессе отображения стрелы, необходимо посчитать положения всех ее точек, определяющих ее форму, а затем повернуть их относительно левого верхнего угла стрелы на заданный угол. Затем эти точки соединяются, и закрашивается замкнутая фигура. Для этого понадобится еще один базовый класс для объектов стрелы, подлежащих повороту.
{Abstract Class RotatableObject}
RotatableObject = object(DisplayObject)
private
_rotation:real;
_xc,_yc:integer;
public
constructor init(xx,yy,wid,hei:integer;color:word);
function rotation:real;
function yc:integer;
function xc:integer;
procedure move(newX,newY:integer);
procedure rotate(centerX,centerY:integer;angle:real);virtual;
end;
Конструктор класса не изменился, но его переопределение нужно чтобы задать исходные координаты центральной точки вращения. В качестве этой точки по умолчанию выступает левый верхний угол объект соответственно с координатами xx,yy из параметров конструктора.
constructor RotatableObject.init(xx,yy,wid,hei:integer;color:word);
begin
DisplayObject.init(xx,yy,wid,hei,color);
_xc:=xx;
_yc:=yy;
end;
Метод rotate аналогично методу move задает координаты вращения и выполняет перерисовку объекта. При это в случае с перемещением, также следует переместить точку, относительно которой будет происходить вращение.
procedure RotatableObject.move(newX,newY:integer);
begin
_xc:=_xc+newX-x;
_yc:=_yc+newY-y;
DisplayObject.move(newX,newY);
end;
procedure RotatableObject.rotate(centerX,centerY:integer;angle:real);
begin
_xc:=centerX;
_yc:=centerY;
_rotation:=angle;
draw;
end;
3. Класс HeartObject
Класс, рисующий сердце, является подклассом абстрактного класса DisplayObject. В объявлении содержится только метод draw, который должен отобразить фигуру на экране.
{Class HeartObject}
HeartObject = object(DisplayObject)
public
procedure draw;virtual;
end;
Сначала вычисляются радиусы дуг и центр дуги исходя из размеров, заданных для объекта сердца. После этого дуги соединяются линиями. Правое полусердце закрашивается цветом фона.
procedure HeartObject.draw;
var x1,x2,y1,y2,xc,yc,xr,yr:integer;
begin
xr:=round( width/2/(1+cos(PI/6)) );
yr:=round(3/4*xr);
xc:=x+width-xr;
yc:=y+yr;
x1:=round(xc-xr*cos(PI/6));
y1:=round(yc-yr*sin(PI/6));
setColor(getBkColor);
ellipse(xc,yc,330,150,xr,yr);
line(x1,y1,x1,y+height);
x2:=round(xc+xr*cos(PI/6));
y2:=round(yc+yr*sin(PI/6));
line(x2,y2,x1,y+height);
setFillStyle(1,getBkColor);
floodFill(xc,yc,getBkColor);
setColor(getBkColor);
line(x1,y1,x1,y+height);
setColor(getColor);
ellipse(xc,yc,330,150,xr,yr);
x2:=round(xc+xr*cos(PI/6));
y2:=round(yc+yr*sin(PI/6));
line(x2,y2,x1,y+height);
xc:=x+xr;
yc:=y+yr;
x1:=round(xc-xr*cos(PI/6));
y1:=round(yc-yr*sin(PI/6));
ellipse(xc,yc,30,210,xr,yr);
x2:=round(xc-xr*cos(PI/6));
y2:=round(yc+yr*sin(PI/6));
line(x2,y2,x+(width div 2),y+height);
end;
4. Класс Arrow
Класс Arrow, содержащий методы рисования стрелы, является подклассом класса RotatableObject. Рассмотрим одну из трех его частей - наконечник. Класс ArrowHead, отображающий наконечник стрелы, также наследует класс RotatableObject. По аналогии с сердцем класс наконечника стрелы также изменяет лишь метод рисования.
{Class ArrowHead}
ArrowHead = object(RotatableObject)
public
procedure draw;virtual;
end;
Для рисования наконечника используются четыре точки, положение которых определяется заданными координатами и размерами наконечника.
procedure ArrowHead.draw;
var x1,y1,x2,y2,x3,y3,x4,y4:real;
p1:HPoint;
begin
x3:=width+x; y3:=y+(height div 2);
x2:=x3-width; y2:=y;
x4:=x2; y4:=y+height;
x1:=x2+round(1/3*width); y1:=y3;
setFillStyle(1,getColor);
p1.init(x1,y1); p1.rotate(xc,yc,rotation);
moveTo( round(p1.x),round(p1.y) );
p1.init(x2,y2); p1.rotate(xc,yc,rotation);
lineTo( round(p1.x),round(p1.y) );
p1.init(x3,y3); p1.rotate(xc,yc,rotation);
lineTo( round(p1.x),round(p1.y) );
p1.init(x4,y4); p1.rotate(xc,yc,rotation);
lineTo( round(p1.x),round(p1.y) );
p1.init(x1,y1); p1.rotate(xc,yc,rotation);
lineTo( round(p1.x),round(p1.y) );
p1.init(x1,y1); p1.rotate(xc,yc,rotation);
floodFill(round(p1.x)+2,round(p1.y),getColor);
end;
Здесь используется вспомогательный класс HPoint, который инициализируется координатами, которые изменяются в результате выполнения поворота точки при вызове метода rotate. Измененные координаты используеются в итоге для рисования повернутого объекта.
{Point Methods}
procedure HPoint.init(xx,yy:real);
begin
x:=xx;
y:=yy;
end;
procedure HPoint.rotate(xc,yc,angle:real);
var r,alpha:real;
begin
r:=sqrt( sqr(yc-y)+sqr(xc-x) );
if(r<>0) then
if(r<>y-yc) then
begin
alpha:=Arctan((y-yc)/r/Sqrt(1-sqr((y-yc)/r)));
x:= xc+r*cos(angle+alpha);
y:= yc+r*sin(angle+alpha);
end
else
begin
x:= xc+r*cos(angle+PI/2);
y:= yc+r*sin(angle+PI/2);
end;
end;
Подобным образом, что и класс ArrowHead, реализуются классы хвоста стрелы ArrowTail и стержня стрелы ArrowShaft. Рассмотрим класс стрелы Arrow, который использует объекты трех выше описанных классов.
Сам класс Arrow ничего не рисует, поэтому метод draw остается пустым. В процессе поворота или перемещения объект стрела передает необходимые параметры и перемещает, поворачивает части, из которых состоит. Также в процессе инициализации стрелы необходимо проинициализировать размеры и положения объктов-частей относительно целой конструкции.
{Class Arrow}
Arrow = object(RotatableObject)
public
tail:ArrowTail;
head:ArrowHead;
shaft:ArrowShaft;
constructor init(xx,yy,wid,hei,headWidth:integer;color:word);
procedure move(newX,newY:integer);
procedure rotate(centerX,centerY:integer;angle:real);virtual;
end;
Инициализация объекта стрелы:
constructor Arrow.init(xx,yy,wid,hei,headWidth:integer;color:word);
begin
DisplayObject.init(xx,yy,wid,hei,color);
tail.init(xx,yy,round(2/3*headWidth),hei,color);
shaft.init(xx+tail.width,yy+round(hei/2),wid-round(2/3*headWidth)-tail.width,hei,color);
head.init(xx+wid-headWidth,yy,headWidth,hei,color);
end;
Поворот стрелы, заключается в повороте его частей относительно точки регистрации - точки левого верхнего угла фигуры:
procedure Arrow.rotate(centerX,centerY:integer;angle:real);
begin
RotatableObject.rotate(centerX,centerY,angle);
tail.rotate(xc,yc,rotation);
shaft.rotate(xc,yc,rotation);
head.rotate(xc,yc,rotation);
end;
В данном случае xc=centerX, yc=centerY.
Аналогичным образом происходит перемещение стрелы, при котором сначала изменяются координаты самой стрелы, затем идет перерисовка стрелы (в нашем случае ничего не происходит здесь), затем составные части стрелы меняют свое положение и заново перерисовываются.
procedure Arrow.move(newX,newY:integer);
var xOffset,yOffset:integer;
begin
xOffset:=newX-x;
yOffset:=newY-y;
RotatableObject.move(newX,newY);
tail.move(tail.x+xOffset,tail.y+yOffset);
shaft.move(shaft.x+xOffset,shaft.y+yOffset);
head.move(head.x+xOffset,head.y+yOffset);
end;
Конечно же, можно было бы создать еще один класс, объединяющий сердце со стрелой. Но было решено, что два данных независимых класса будут использоваться отдельно в основном приложении, где можно будет самостоятельно "поиграться" с размерами и положением стрелы и сердца относительно друг друга, а не добавлять эти параметры положения и размеров внутрь модуля, делая класс стрелы с сердцем не гибким, сильно зависящим от этих параметров.
5. Подключение модуля
Подключим модуль Heart в основной программе и создадим два объекта из классов: HeartObject, Arrow.
В теле программы до тех пор пока пользователь не нажмет ESC и не выйдет из программы, последовательно происходит выбор режима перемещения фигур и отображения их на экране.
{body}
begin
clrscr;
gd := detect;
initgraph(gd,gm,'c:\BGI');
if graphresult <> 0 then
begin
write('graph error!');
halt;
end;
randomize;
while true do
begin
selectedMoveMode := selectMoveMode;
if selectedMoveMode = -1 then break
else showFigures(selectedMoveMode);
end;
end.
Перед тем как на экране отобразятся необходимые фигуры, в методе showFigures происходит инициализация объектов:
procedure showFigures(moveMode:integer);
var key:char;
xOffset,yOffset:integer;
begin
setGraphMode(gm);
setBkColor(white);
width:=300;
height:=300;
x:=(getMaxX-width) div 2+50;
y:=(getMaxY-height) div 2+50;
A.init(50,20,600,30,40,darkGray);
A.rotate(50,20,35*PI/180);
H.init(x,y,width,height,darkGray);
H.draw;
//------------------------//---------------------------//
Далее, если выбран режим случайного перемещения фигур, то для каждого объекта выполняем метод move с одинаковыми случайными параметрами смещения:
//------------------------//---------------------------//
if(moveMode=MOVE_RANDOM) then
begin
key:='o';
while(key<>#27) do
begin
clearDevice;
setBkColor(white);
xOffset:=random(2*STEP_MOVE+1)-STEP_MOVE;
yOffset:=random(2*STEP_MOVE+1)-STEP_MOVE;
A.move(A.x+xOffset, A.y+yOffset);
H.move(H.x+xOffset, H.y+yOffset);
key:=readKey;
end;
key:='o';
end
//------------------------//---------------------------//
Если выбран ручной режим перемещения, то в зависимости от нажатой клавиши со стрелкой фигура переместится в заданном направлении.
//------------------------//---------------------------//
else if(moveMode=MOVE_MANUAL)then
begin
key:='o';
while(key<>#27) do
begin
key:=readkey;
case key of
#80: begin
moveFigures(0,STEP_MOVE);
end;
#75: begin
moveFigures(-STEP_MOVE,0);
end;
#77: begin
moveFigures(STEP_MOVE,0);
end;
#72: begin
moveFigures(0,-STEP_MOVE);
end;
end;
end;
key:='o';
end;
end;
Вспомогательный метод перемещения moveFigures:
procedure moveFigures(xOffset, yOffset:integer);
begin
clearDevice;
setBkColor(white);
A.move(A.x+xOffset, A.y+yOffset);
H.move(H.x+xOffset, H.y+yOffset);
end;
И для случайного, и для ручного режима перед смещением и новой отрисовки фигуры, очищаем экран и закрашиваем его белым цветом, вызвав пару методов: clearDevice и setBkColor.
6. Результаты программы
Программа отображает и перемещает необходимые фигуры на экране.
При запуске приложения на экране отображается меню с выбором режима перемещения фигур:
После выбора режима перемещения на экране отображаются фигуры сердца и стрелы:
Сделайте индивидуальный заказ на нашем сервисе. Там эксперты помогают с учебой без посредников
Разместите задание – сайт бесплатно отправит его исполнителя, и они предложат цены.
Цены ниже, чем в агентствах и у конкурентов
Вы работаете с экспертами напрямую. Поэтому стоимость работ приятно вас удивит
Бесплатные доработки и консультации
Исполнитель внесет нужные правки в работу по вашему требованию без доплат. Корректировки в максимально короткие сроки
Гарантируем возврат
Если работа вас не устроит – мы вернем 100% суммы заказа
Техподдержка 7 дней в неделю
Наши менеджеры всегда на связи и оперативно решат любую проблему
Строгий отбор экспертов
К работе допускаются только проверенные специалисты с высшим образованием. Проверяем диплом на оценки «хорошо» и «отлично»
Работы выполняют эксперты в своём деле. Они ценят свою репутацию, поэтому результат выполненной работы гарантирован
Ежедневно эксперты готовы работать над 1000 заданиями. Контролируйте процесс написания работы в режиме онлайн
Выполнить 2 контрольные работы по Информационные технологии и сети в нефтегазовой отрасли. М-07765
Контрольная, Информационные технологии
Срок сдачи к 12 дек.
Архитектура и организация конфигурации памяти вычислительной системы
Лабораторная, Архитектура средств вычислительной техники
Срок сдачи к 12 дек.
Организации профилактики травматизма в спортивных секциях в общеобразовательной школе
Курсовая, профилактики травматизма, медицина
Срок сдачи к 5 дек.
краткая характеристика сбербанка анализ тарифов РКО
Отчет по практике, дистанционное банковское обслуживание
Срок сдачи к 5 дек.
Исследование методов получения случайных чисел с заданным законом распределения
Лабораторная, Моделирование, математика
Срок сдачи к 10 дек.
Проектирование заготовок, получаемых литьем в песчано-глинистые формы
Лабораторная, основы технологии машиностроения
Срок сдачи к 14 дек.
Вам необходимо выбрать модель медиастратегии
Другое, Медиапланирование, реклама, маркетинг
Срок сдачи к 7 дек.
Ответить на задания
Решение задач, Цифровизация процессов управления, информатика, программирование
Срок сдачи к 20 дек.
Написать реферат по Информационные технологии и сети в нефтегазовой отрасли. М-07764
Реферат, Информационные технологии
Срок сдачи к 11 дек.
Написать реферат по Информационные технологии и сети в нефтегазовой отрасли. М-07764
Реферат, Геология
Срок сдачи к 11 дек.
Разработка веб-информационной системы для автоматизации складских операций компании Hoff
Диплом, Логистические системы, логистика, информатика, программирование, теория автоматического управления
Срок сдачи к 1 мар.
Нужно решить задание по информатике и математическому анализу (скрин...
Решение задач, Информатика
Срок сдачи к 5 дек.
Заполните форму и узнайте цену на индивидуальную работу!