Автор работы: Пользователь скрыл имя, 04 Ноября 2014 в 17:33, курсовая работа
Цель данной курсовой работы –разработка приложения, позволяющего построить график функции по заданным точкам.
В данном приложение реализуется программное построение графика данной функции. Очень удобным на практике является тот факт, что график строится по заданным точкам. Это актуально в случаях, когда график в силу каких-либо причин невозможно задать уравнением.
При выполнении данной курсовой работы были поставлены следующие задачи:
• Изучение методов построения графиков и их анализ;
• Выбор среды разработки;
• Изучение методов реализации приложения в выбранной среде;
• Разработать приложение, позволяющее строить график по заданным точкам.
ВВЕДЕНИЕ 3
1. КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ 4
1.1 ОСНОВНЫЕ ПОНЯТИЯ 4
1.2 СПОСОБЫ ЗАДАНИЯ ФУНКЦИИ 5
1.3 СРЕДСТВА СОЗДАНИЯ ГРАФИЧЕСКОГО ИНТЕРФЕЙСА 6
1.4 СРАВНЕНИЕ OPENGL И DIRECTX 15
2. ОПИСАНИЕ ПРИЛОЖЕНИЯ 18
2.1 ОПИСАНИЕ ИСХОДНОГО КОДА 18
2.2 ИНТЕРФЕЙС ПРИЛОЖЕНИЯ 19
ТЕСТИРОВАНИЕ РАБОТЫ ПРИЛОЖЕНИЯ НА ПРИМЕРЕ 23
ЗАКЛЮЧЕНИЕ 27
СПИСОК ЛИТЕРАТУРЫ 28
ПРИЛОЖЕНИЕ А 29
{
if (index.isValid() && role == Qt::EditRole)
{
QPointF point = function->points.takeAt(index.
int row, pos;
qreal x;
switch (index.column())
{
case 0: x = point.x();
point.setX(value.toReal());
pos = function->addPoint(point);
if (pos >= 0)
{
points[index.row()]->x = value.toString();
row = index.row();
beginRemoveRows(QModelIndex(), row, row);
points.removeAt(row);
endRemoveRows();
beginInsertRows(QModelIndex(), pos, pos);
points.insert(pos, new Item(point.x(), point.y()));
endInsertRows();
}
else
{
point.setX(x);
function->addPoint(point);
QMessageBox::warning(0, tr("Недопустимая точка"), tr("Для данного x уже задана другая точка."));
}
break;
case 1: points[index.row()]->y = value.toString();
point.setY(value.toReal());
function->addPoint(point);
break;
}
emit needUpdate();
return true;
}
return false;
}
// Число строк и столбцов.
int rowCount(const QModelIndex & parent = QModelIndex()) const {return points.size();}
int columnCount(const QModelIndex & parent) const {return headers.count();}
// Заполнение заголовков строк и столбцов.
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
{
if (role != Qt::DisplayRole) return QVariant();
if (orientation == Qt::Horizontal &&
role == Qt::DisplayRole)
return headers.at(section);
else
return QString::number(section + 1);
}
// Флаги редактирования, всю таблицу можно редактировать.
Qt::ItemFlags flags (const QModelIndex & index) const
{
if (!index.isValid()) return Qt::ItemIsEnabled;
return QAbstractItemModel::flags(
Qt::ItemIsEditable;
}
// Добавление новой строки в модель.
bool addRow(QPointF point)
{
int row = function->addPoint(point);
if (row < 0)
{
QMessageBox::warning(0, tr("Недопустимая точка"), tr("Для данного x уже задана другая точка."));
return false;
}
beginInsertRows(QModelIndex(), row, row);
Item * item = new Item(point.x(), point.y());
points.insert(row, item);
endInsertRows();
++countOfPoints;
emit needUpdate();
return true;
}
// Удаление строки таблицы.
bool deleteRow(int row)
{
if (!countOfPoints || (row < 0)) return false;
if (countOfPoints == 2)
{
QMessageBox::warning(0, tr("Невозможно удалить точку"), tr("Минимальное количество точек досигнуто"));
return false;
}
beginRemoveRows(QModelIndex(), row, row);
points.removeAt(row);
function->points.removeAt(row)
if (row == 0)
function->xMin = function->points.first().x();
if (row == (countOfPoints - 1))
function->xMax = function->points.last().x();
--countOfPoints;
endRemoveRows();
emit needUpdate();
return true;
}
signals:
void needUpdate();
};
// Класс таблицы для отображения точек.
class PointsWidget : public QTableView
{
Q_OBJECT
public:
explicit PointsWidget(QWidget *parent = 0) :
QTableView(parent)
{
setItemDelegate(new Delegate()); // Использует разработанный делегат.
setSelectionMode(QAbstractItem
setContextMenuPolicy(Qt::Custo
}
// Позволяет получить индекс выбранной строки.
int selectedRow()
{
if (selectedIndexes().isEmpty()) return -1;
return selectedIndexes().takeFirst().
}
};
#endif // WIDGETS_H
dialogaddfunction.h
#ifndef DIALOGADDFUNCTION_H
#define DIALOGADDFUNCTION_H
#include <QDialog>
#include <QColor>
#include <QTime>
#include <QColorDialog>
#include <QMessageBox>
namespace Ui
{
class DialogAddFunction;
}
// Диалог добавления новой функции.
// Позволяет задавать имя функции, цвет и две крайние точки.
class DialogAddFunction : public QDialog
{
Q_OBJECT
public:
QString name; // Параметры функции.
QColor color;
qreal x1, y1, x2, y2;
explicit DialogAddFunction(QWidget *parent = 0);
~DialogAddFunction();
private:
Ui::DialogAddFunction *ui;
void changeColor(); // Изменения цвета метки диалога.
private slots:
void setColor(); // Задание цвета диалогом.
void check(); // Подтверждение.
};
#endif // DIALOGADDFUNCTION_H
dialogsettings.h
#ifndef DIALOGSETTINGS_H
#define DIALOGSETTINGS_H
#include <QDialog>
#include <QLabel>
#include <QColorDialog>
#include <QColor>
#include <QPalette>
#include <QMessageBox>
namespace Ui {
class DialogSettings;
}
// Диалог настроек графика.
// Позволяет задавать границы графика и его оформление.
class DialogSettings : public QDialog
{
Q_OBJECT
public:
qreal xMin, xMax, yMin, yMax; // Границы.
int outline, gridStep; // Отступ графика и шаг сетки.
QColor gridColor, background, textColor; // Цветовое оформление.
explicit DialogSettings(qreal xMin, qreal xMax, qreal yMin, qreal yMax,
int outline, int gridStep,
QColor gridColor, QColor background, QColor textColor,
QWidget *parent);
~DialogSettings();
private:
Ui::DialogSettings *ui;
void setColor(QLabel * label, QColor color); // Изменение цвета метки.
private slots:
void check();
void on_btnBackgroundColor_clicked(
void on_btnGridColor_clicked();
void on_btnTextColor_clicked();
};
#endif // DIALOGSETTINGS_H
dialogaddpoint.h
#ifndef DIALOGADDPOINT_H
#define DIALOGADDPOINT_H
#include <QDialog>
namespace Ui {
class DialogAddPoint;
}
// Диалог добавления новой точки.
// Позволяет задавать координаты точки.
class DialogAddPoint : public QDialog
{
Q_OBJECT
public:
qreal x, y; // Координаты точки.
explicit DialogAddPoint(QWidget *parent = 0);
~DialogAddPoint();
private:
Ui::DialogAddPoint *ui;
private slots:
void check(); // Подтверждение.
};
#endif // DIALOGADDPOINT_H
Файлы исходники:
main.cpp
#include <QtGui>
#include <QApplication>
#include "mainwindow.h"
#include <QTextCodec>
#include <QStyleFactory>
int main(int argc, char *argv[])
{
QTextCodec::setCodecForLocale(
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
graph.cpp
#include "graph.h"
#include <qmath.h>
Graph::Graph( Functions *functions,
QWidget *parent) :
QGLWidget(parent)
{
left = -5; // Границы графика.
right = 5;
top = 5;
bottom = -5;
outline = 30; // Граничный отступ графика.
gridStep = 25; // Шаг Автосетки.
scale = 100; // Масштаб графика.
// Внешний вид графика.
gridPen = QPen(Qt::lightGray); // Линии сетки.
backgroundBrush = QBrush(Qt::gray); // Задний фон.
textColor = Qt::black; // Цвет текста.
labelFont = QFont("Arial", 8, 1, true); // Шрифт подписей.
setMouseTracking(true); // Отслеживание мыши.
mouseX = mouseY = 0; // Координаты мыши.
this->functions = functions; // Список отображаемых функций.
tracing = &(functions->first()); // Трассировать первую функцию из списка.
setContextMenuPolicy(Qt::Custo
}
// Перерисовка графика, при изменении размера виджета.
void Graph::resizeGL(int w, int h)
{
//////////////////////////////
// Пересчёт размеров графика к новому размеру виджета.
//////////////////////////////
graphSize.setHeight (scale * (bottom - top)); // Размеры графика.
graphSize.setWidth (scale * (right - left));
graph = QRect(QPoint(scale * left, scale * top), graphSize); // Прямоугольная область графика.
setMinimumSize(outline * 3, outline * 3); // Ограничение на минимальный размер виджета.
viewportSize = size(); // Прямоугольная область виджета.
// График будет сжат с обеих сторон на толщину отступа границы.
qreal adjustWidth (viewportSize.width() - 2 * outline),
adjustHeight (viewportSize.height() - 2 * outline);
// Сжатие области рисования на виджете.
viewportSize.scale(
// Сдвигание области рисования на толщину границы.
viewport = QRect(QPoint(outline, outline), viewportSize);
//////////////////////////////
// Пересчёт подписей и разметки сетки.
//////////////////////////////
// Количество подписей сетки.
qreal xLabelCount(1), yLabelCount(1);
// Шаг сетки определяется цикличным делением пополам.
xViewportStep = viewportSize.width();
yViewportStep = viewportSize.height();
for (;;)
{
qreal value(xViewportStep / 2.0);
if (value >= gridStep) xViewportStep = value;
else break;
++xLabelCount;
}
for (;;)
{
qreal value(yViewportStep / 2.0);
if (value >= gridStep) yViewportStep = value;
else break;
++yLabelCount;
}
// Обратная операция для получения количества подписей.
xLabelCount = qPow(2, xLabelCount);
yLabelCount = qPow(2, yLabelCount);
// Шаг графика для виртуальных координат.
xGraphStep = 2 * graph.width() / qreal(xLabelCount);
yGraphStep = 2 * graph.height() / qreal(yLabelCount);
xStepCount = graph.width() / xGraphStep;
yStepCount = graph.height() / yGraphStep;
// Рисование.
paintGL();
}
// Перерисовка графика.
void Graph::paintGL()
{
// Создание и настройка рисовальщика.
QPainter painter(this);
painter.setRenderHint(QPainter
// Серый фон.
painter.setBackground(backgrou
painter.eraseRect(rect());
painter.save();
//////////////////////
// Отображение сетки.
//////////////////////
// Привязывание виртуальных координат.
painter.setWindow(graph);
painter.setViewport(viewport);
// Сетка.
painter.setPen(gridPen);
// Рисование разметки.
for (int i(1); i < xStepCount; ++i)
{
qreal pos(scale * left + i * xGraphStep);
painter.drawLine(QLineF(pos, scale * top,
}
for (int i(1); i < yStepCount; ++i)
{
qreal pos(scale * top + i * yGraphStep);
painter.drawLine(QLineF(scale * left, pos,
}
painter.drawRect(graph);
//////////////////////
// Рисование функций.
//////////////////////
// Проход по функциям.
QListIterator<Function> i(*functions);
while (i.hasNext())
{
const Function * f(&i.next());
// Рисование цветом соответствующим функции.
if (showTracing && f == tracing)
{
painter.setPen(QPen(QBrush(f->
showTracing = false;
}
else
painter.setPen(QPen(f->color))
qreal xStep(0.01), // Величина шага по оси x.
y; // Значение функции в заданной точке.
int xStepCount = (right - left) / xStep; // Количество шагов по оси x.
QPointF prevPoint; // Предыдущая точка функции.
for(int i(0); i <= xStepCount; ++i)
{
// Первая точка графика.
qreal x = left + i * xStep;
// Входит в область определения.
if (!f->has(x)) continue;
y = f->value(x);
// График рисуется от предыдущей точки к следующей.
prevPoint = QPointF(scale * x, scale * y);
bool burst(false);
for(int j(i); j <= xStepCount; ++j)
{
qreal x = left + j * xStep;
// Функция на промежутке непрерывна.
if (!f->has(x)) break;
y = f->value(x);
// Выводятся только значения входящие в границы графика.
if ((y < top) && (y > bottom))
{
painter.drawLine(QLineF(
burst = false;
// Текущая точка становится предыдущей.
prevPoint = QPointF(scale * x, scale * y);
}
else
{
if (y > top)
{
if (!burst)
painter.drawLine(QLineF(
prevPoint = QPointF(scale * x, scale * top);
}
if (y < bottom)
{
if (!burst)
painter.drawLine(QLineF(
prevPoint = QPointF(scale * x, scale * bottom);
}
burst = true;
}
}
break;
}
}
//////////////////////////////
// Отрисовка линий трассировки.
//////////////////////////////
if (tracerOk)
{
painter.setPen(QPen(QBrush(Qt:
painter.drawLine(QLineF(traceX * scale, top * scale, traceX * scale, bottom * scale));
painter.drawLine(QLineF(left * scale, traceY * scale, right * scale, traceY * scale));
}
painter.restore();
painter.eraseRect(QRect(0, 0, width(), outline - 1));
painter.eraseRect(QRect(0, height() - outline + 1, width(), outline));
/////////////////////////
// Отображение подписей.
/////////////////////////
painter.setPen(textColor);
// Задание шрифта подписей.
painter.setFont(labelFont);
// Специальные размеры.
qreal halfSide (outline / 2), // Половина оступа границы.
xMargin (size().height() - outline), // Отступ по горизонтали.
yMargin (0); // Отступ по вертикали.
// Подписи к осям
for(int i(0); i <= xStepCount; ++i)
{
qreal label (left + i * xGraphStep / scale), // Значение метки.
step (halfSide + i * xViewportStep); // Положение метки в реальных координатах.
painter.drawText(QRectF(QPoint
Информация о работе Построение графика функции по заданным точкам