В методе PaintEvent описан алгоритм обработки и рисования графа.
QLinearGradient lg = QLinearGradient(QPointF(0,0),QPointF(0,1));
lg.setCoordinateMode(QGradient::ObjectBoundingMode );
lg.setSpread(QGradient::PadSpread);
lg.setColorAt(0.0,Qt::green);
lg.setColorAt(1.0,Qt::red);brush = QBrush(lg);painter(this);
painter.setBrush(brush);
QPen p2;
p2.setBrush(brush);
p2.setWidth(2);
В этой части кода устанавливаются цвет линии, которой будут нарисованы дуги. В этом случае цветом дуги будет градация цвета от зеленого к красному. Это сделано для того, чтобы можно было обозначить, из какой вершины дуга выходит, и в какую входит. Зеленым цветом обозначается часть дуги, выходящая из вершины, а красным цветом часть, которая входит в смежную с ней вершину. Полностью красным цвет дуги будет в том случае, если дуга является двунаправленной.
if (f)
{
int aK=0;
int x=this->width()/2;
int y=this->height()/2;
double pi=3.14;
struct VertCoor* VCoor3;
VCoor=(struct VertCoor*)malloc(sizeof(struct VertCoor));
VCoor->X=(int)(x+120*cos(aK*pi/180));
VCoor->Y=(int)(y-120*sin(aK*pi/180));
VCoor->sign=VList->sign;
VCoor->type=VList->name;
VCoorL=VCoor;
aK=aK+360/(n+1);
VList=VList->next;
for (int i=0;i!=n;i++)
{
VCoor3=(struct VertCoor*)malloc(sizeof(struct VertCoor));
VCoor3->sign=VList->sign;
VCoor3->type=VList->name;
VCoor3->X=(int)(x+120*cos(aK*pi/180));
VCoor3->Y=(int)(y-120*sin(aK*pi/180));
VCoor->next=VCoor3;
VCoor=VCoor3;
VList=VList->next;
aK=aK+360/(n+1);
}
VCoor->next=NULL;
}
В этой части программного кода реализован алгоритм поиска оптимальных координат для вершин, запись этих координат в параметры вершин списка VCoor и запись имени соответствующей вершины.
Алгоритм построения изображения сводится к алгоритму построения правильного n-угольника. В правильном многоугольнике все углы равны, значит надо 360 градусов поделить на n углов n-угольника. Получим внутренний угол многоугольника. Далее для нахождения координат определенных вершин используем формулу окружности. Для того чтобы получить координату, нужно перевести градусы в радианы. Для этого угол мы умножаем на число Пи, и делим на 180 градусов.
В цикле мы движемся по списку вершин, находящемуся в структуре дескриптора графа, и пока не доходим до конца, каждой вершине присваиваем координаты следующей точки на окружности (из n точек), конвертируя их в целочисленный тип.
Этот алгоритм выполняется только при запуске программы. Дальше его не зачем повторять, потому что все значения хранятся в глобальной переменной, и чтобы можно было отрисовывать граф заново с измененными значениями координат.
struct descV* vert2;
vert2=g1->LVert;
while (vert2!=NULL)
{
struct SupportInOutArc* ALIST2 = vert2->LOut->LArc;
while (ALIST2!=NULL)
{
sign1=ALIST2->arch->LOut->Out->vert->sign;
VCoor=VCoorL;
while (VCoor!=NULL)
{
if (VCoor->sign == sign1 )
{
x1=VCoor->X;
y1=VCoor->Y;
n1=sign1;
}
VCoor=VCoor->next;
}
sign1=ALIST2->arch->LIn->In->vert->sign;
VCoor=VCoorL;
while (VCoor!=NULL)
{
if (VCoor->sign==sign1 )
{
x2=VCoor->X;
y2=VCoor->Y;
n2=sign1;
}
VCoor=VCoor->next;
}
painter.drawLine(x1,y1,x2,y2);
ALIST2 = ALIST2->next;
}
vert2 = vert2->next;
}
В этой части кода происходит обход всех вершин в цикле, поиск выходящий из нее дуг, и далее в цикле происходит поиск координат вершин, соответствующих входу и выходу дуги. В этих координатах, соответственно от выхода к входу, рисуется линия методом drawLine.
QPainter p3(this);
QBrush brush1 = QBrush(Qt::darkCyan,Qt::SolidPattern);
p3.setBrush(brush1);=VCoorL;
while (VCoor!=NULL)
{
p3.drawRect(VCoor->X-15,VCoor->Y-15,30,30);
VCoor=VCoor->next;
}
QPainter p4(this);
QPen penB2(Qt::white);
p4.setPen(penB2);
p4.setFont(QFont("Times", 14));=VCoorL;
while (VCoor!=NULL)
{
QString text=(QString)VCoor->type;
p4.drawText(VCoor->X-8,VCoor->Y+8,text);
VCoor=VCoor->next;
}
}
Далее на координатах вершин рисуются прямоугольники, в которых будут записаны имена соответствующих вершин.
В методе StartDraw() происходит создание графа, который будет рисовать программный модуль.
Метод Grab() получает скриншот изображения окна виждета с нарисованным графом и сохраняет его в память компьютера под именем screen.jpg.
В методе keyPressEvent() описываются клавиши клавиатуры, при нажатии на которые вызываются соответствующие методы.
При нажатии на клавишу W вызывается метод zoomIn(2), который увеличивает значения координат вершин в два раза, тем самым увеличивая в два раза изображение, которое мы в итоге получаем.
При нажатии на клавишу S вызывается метод zoomOut(2), который описанным выше методом уменьшает координаты и изображение в два раза.
При нажатии на клавишу Up вызывается метод moveUp(10), в котором координаты по оси y увеличиваются на 10, тем самым передвигая изображение вверх.
При нажатии Down изображение методом moveDown(10) аналогичным образом смещается вниз.
При нажатии Right и Left вызываются соответственно методы moveRight(10) и moveLeft(10), которые увеличивают и уменьшают координаты по оси х на 10, тем самым сдвигая изображения вправо и влево.
При нажатии на клавишу Escape программа закрывается вызовом метода Close().
Файл “main.cpp”.
В этом файле создается экземпляр w
класса MainWindow.
Затем вызывается метод этого класса StartDraw()
и создается граф. Далее методом show()
создается виджет и происходит реализация алгоритма рисования. После вызывается
метод Grab() и
изображение графа сохраняется в память компьютера. Также была реализована
версия модуля, специально для использования под Веб-интерфейс, которая
автоматически закрывает приложение методом Close().
3.2 Пример работы программного модуля
Для примера выведем по очереди два ориентированных
графа. Изображение графа мы получаем сразу при запуске программы (рис.2).Как
ранее и описывалось, зеленый цвет дуги обозначает выход из вершины, а красный
вход. Полностью красная дуга С-B
означает, что эта дуга двунаправленная. Имена вершин записаны в прямоугольных
областях.
Рисунок 2 - запуск программы
Рисунок 3 - сдвиг в нижнюю левую часть
Далее показано изменение положения графа в окне
виджета. На рисунке 3 показано передвижение графа в нижнюю левую часть окна. На
рисунке 4 - в верхнюю правую часть окна. На рисунке 5 показано увеличение
изображения графа, для более удобного и подробного изучения более больших
структур.
Рисунок 4 - сдвиг в правую верхнюю часть
Рисунок 5 - увеличение изображения
На рисунке 6 показаны изображения двух графов, взятых для примера. Второй граф, взятый для примера, имеет 10 вершин и состоит из двух частей.
Выход из программы осуществляется при нажатии
клавиши Escape.
Рисунок 6 - изображение двух графов
3.3 Подключение программного модуля к
Веб-странице.
Главной веб-страницей является файл “indexOh.html”. В нем описаны переходы по двум ссылкам. Первая это ссылка на страницу “Oh.php”, где реализуется алгоритм вызова выполнения программного модуля на стороне сервера. Вторая ссылка на страницу “index.html”, куда будет загружаться изображение с результатом работы программы.
На рисунке 7 показано окно страницы “indexOh.html”.
Рисунок 7 - indexOh.html
При нажатии на ссылку «Нажмите на эту ссылку для выполнения программы» программа запускается на стороне сервера, сохраняет изображение графа на сервере и автоматически закрывается. При нажатии на ссылку «Здесь результат!» мы переходим на страницу “index.html”,показанную на рисунке 8, и видим результат выполнения программы.
Также изображение графа сохраняется в памяти компьютера, и его можно использовать для дальнейших работ.
Рисунок 8 - страница index.html
с результатом
ЗАКЛЮЧЕНИЕ
Разработан программный модуль, который получая
на входе ссылку на граф, используя методы из прилагаемого модуля, выводит
изображение графа на экран и сохраняет это изображение в память компьютера.
Можно использовать разные модули реализации графа (с одинаковыми наименованиями
структур и методов). Изображением можно управлять, сдвигая вверх, вниз, вправо,
влево, а также увеличивая и уменьшая. Это способствует более удобному изучению
изображения структуры. Также этот программный модуль был подключен в
Веб-странице, что позволяет через веб-интерфейс запускать программу и получать
результат. Программа исполняет свое задание верно.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Шеннон Р. Имитационное моделирование систем: искусство и наука. - М.: Мир, 1978. -- 302 с.
2. Майер Р.В. Компьютерное моделирование. Электронная конференция. URL: http://econf.rae.ru/article/6722 (дата обращения 5.06.2014)
3. Кудинов Ю.И., Пащенко Ф.Ф. Основы современной информатики. - 2-е изд. испр. - М.: Издательство "Лань", 2011.
. Макарова Н.В., Волков В.Б. Информатика: Учебник для вузов. - СПб.: Питер, 2011.
5. Описание класса QPainter. URL: http://qtdocs.narod.ru/4.1.0/doc/html/qpainter.html#details (дата обращения 5.05.2014)
6. Описание класса QWidget. URL: http://doc.crossplatform.ru/qt/4.5.0/qwidget.html (дата обращения 26.04.2014)
. Макс
Шлее: Qt 4.8. Профессиональное программирование на C++//- СПб.: БХВ-Петербург,
2012. - 912 с.: ил. - (В подлиннике)
ПРИЛОЖЕНИЕ А
Описание программы.
. Общие сведения.
Данная программа реализована на языке С++. Основные файлы исходного кода программ: graph.h, mainwindow.h, mainwindow.cpp, main.cpp. Для ее реализации использовались: библиотеки Qt, среда разработки Qt Creator, операционная система Linux, веб-сервер Apache.
. Функциональное назначение.
Программа визуализирует компьютерную структуру в виде графа. Изображение можно передвигать, увеличивать и уменьшать для более удобного изучения изображения структуры. Изображение сохраняется в памяти компьютера. Так же программа может выполняться с веб-страницы на стороне сервера и выводить изображение с результатом на веб-страницу.
Программный модуль является составным компонентом системы моделирования, cоздающейся в рамках проекта «Разработка и реализация информационно-аналитической среды, предназначенной для исследования и проектирования информационно-коммуникационных систем» Программы развития КубГУ.
. Описание логической структуры.
В файле graph.h описаны методы реализации графа, представленного совокупностью дескрипторов. Для представления графа в виде связанных дескрипторов понадобилось 8 структур: 5 для дескрипторов и 3 вспомогательных. Структура DescG представляет собой дескриптор графа. DescV - дескриптор вершины. DescIn и DescOut - дескрипторы входа и выхода. DescAr - дескриптор дуги. SupportInOutArc, SupportArcOut, SupportArcIn - это вспомогательные структуры для оптимизации связи вершин и дуг.
В классе “MainWindow” описан весь алгоритм работы программного модуля.
В методе PaintEvent описан алгоритм обработки и рисования графа. Граф отрисовывается методами drawLine, drawRect и drawText. Сначала рисуются дуги графа. Зеленым цветом обозначен выход дуги, красным вход. Полностью красная дуга означает, что она двунаправленная. Далее рисуются прямоугольники, означающие вершины. В прямоугольниках записаны имена вершин.
В методе StartDraw() происходит создание графа, который будет рисовать программный модуль.
Метод Grab() получает скриншот изображения окна виждета с нарисованным графом и сохраняет его в память компьютера под именем screen.jpg.
В методе keyPressEvent() описываются клавиши клавиатуры, при нажатии на которые вызываются соответствующие методы.
При нажатии на клавишу W вызывается метод zoomIn(2), который увеличивает значения координат вершин в два раза, тем самым увеличивая в два раза изображение, которое мы в итоге получаем.
При нажатии на клавишу S вызывается метод zoomOut(2), который описанным выше методом уменьшает координаты и изображение в два раза.
При нажатии на клавишу Up вызывается метод moveUp(10), в котором координаты по оси y увеличиваются на 10, тем самым передвигая изображение вверх.
При нажатии Down изображение методом moveDown(10) аналогичным образом смещается вниз.
При нажатии Right и Left вызываются соответственно методы moveRight(10) и moveLeft(10), которые увеличивают и уменьшают координаты по оси х на 10, тем самым сдвигая изображения вправо и влево.
При нажатии на клавишу Escape программа закрывается вызовом метода Close().
В файле “main.cpp” создается экземпляр w класса MainWindow. Затем вызывается метод этого класса StartDraw() и создается граф. Далее методом show() создается виджет и происходит реализация алгоритма рисования. После вызывается метод Grab() и изображение графа сохраняется в память компьютера. Также была реализована версия модуля, специально для использования под Веб-интерфейс, которая автоматически закрывает приложение методом Close().
Файл “indexOh.html” является главной веб-страницей. В нем описаны переходы по двум ссылкам. Первая это ссылка на страницу “Oh.php”, где реализуется алгоритм вызова выполнения программного модуля на стороне сервера. Вторая ссылка на страницу “index.html”, куда будет загружаться изображение с результатом работы программы.