51362

Визуализация графика математической функции

Лабораторная работа

Информатика, кибернетика и программирование

Получение значения объекта step сохранение его в переменную s; получение значения объекта xmin с последующим преобразованием в формат flot и сохранением в переменную x0; получение значения объекта xmx с последующим преобразованием в формат flot и сохранением в переменную x1; получение значения объекта osx сохранение его в переменную sx; получение значения объекта osy сохранение его в переменную sy; получение значения объекта oscle сохранение его в переменную sc; создание сигнала chnge c передачей параметров...

Русский

2014-02-10

1.04 MB

2 чел.

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ,

МОЛОДЕЖИ И СПОРТА УКРАИНЫ

Национальный аэрокосмический университет им. Н.Е. Жуковского

«Харьковский авиационный институт»

Кафедра систем управления летательными аппаратами

Лабораторная работа №5

по дисциплине «Основы алгоритмизации и программирование»

Тема: «Визуализация графика математической функции»

ХАИ.301.050201.312.11 ЛР

Выполнил студент гр. 312 И.В. Кудрявский

(№ группы) (Ф.И.О.)

_____________________________________

(подпись, дата)

Проверил ассист. ______________________ 

(ученая степень, ученое звание)

_________________________ К.И. Руденко

(подпись, дата)    (Ф.И.О.)

ассист. ______________________________

(ученая степень, ученое звание)

_______________________ Е.А. Андронова

(подпись, дата)    (Ф.И.О.)

2013


Цель работы: разработать GUI-приложение выполняющее визуализацию графика математичкой функции.

Задание: разработать GUI-приложение выполняющее визуализацию графика математичкой функции y=cos(cos(cos(cos(x^13))))*3/x*x*x.

Для реализации программы построен алгоритм в виде блок-схемы (рис. 5.1).

Рисунок 5.1 – Алгоритм выполнения задания

Пояснения к рис.5.1:

  1.  установка кодировки окна Windows-1251”;
  2.  установка заголовка окна lab5-312-v11-Кудрявский-Иван;
  3.  устанавка минимального размера окна 400x400 пикселей;
  4.  создание экземпляра класса QGridLayout, сохранение его в переменную glMain;
  5.  создание экземпляра класса QHBoxLayout, сохранение его в переменню hb2;
  6.  создание экземпляра класса Qlabel с текстом f(x) = cos(cos(cos(cos(x^13))))*3/x*x*x”, сохранение его в переменню txt;
  7.  добавление объекта txt в объект hb2;
  8.  добавление растяжки в объект hb2;
  9.  создание экземпляра класса QPushButton c текстом “Координаты точек, сохранение его в переменную pb;
  10.  добавление объекта pb в объект hb2;
  11.  установка объекта hb2 в объект glMain; задание расположения в таблице в ячейке с координатой [0;0];
  12.  создание экземпляра класса QHBoxLayout, сохранение его в переменню hb;
  13.  создание экземпляра класса Qlabel с текстом Хmin”, сохранение его в переменню txt;
  14.  добавление объекта txt в объект hb;
  15.  создание экземпляра класса QLineEdit со значением по умолчанию “-10”, сохранение его в переменную xmin;
  16.  добавление объекта xmin в объект hb;
  17.  создание экземпляра класса QLabel с текстом Хmax”, сохранение его в переменню txt;
  18.  добавление объекта txt в объект hb;
  19.  создание экземпляра класса QLineEdit со значением по умолчанию “10”, сохранение его в переменную xmax;
  20.  добавление объекта xmax в объект hb;
  21.  создание экземпляра класса QLabel с текстом “Шаг”, сохранение его в переменню txt;
  22.  добавление объекта txt в объект hb;
  23.  создание экземпляра класса QDoubleSpinBox ch значениеv по умолчанию 0.1, минимальным значением 0.01, шагог 0.05, сохранение его в переменную step;
  24.  добавление объекта step в объект hb;
  25.  создание экземпляра класса QLabel с текстом “x”, сохранение его в переменню txt;
  26.  добавление объекта txt в объект hb;
  27.  создание экземпляра класса QDoubleSpinBox с минимальным значением 

“-5000”, шагом 2, сохранение его в переменную osx;

  1.  добавление объекта osx в объект hb;
  2.  создание экземпляра класса QLabel с текстом y”, сохранение его в переменню txt;
  3.  добавление объекта txt в объект hb;
  4.  создание экземпляра класса QDoubleSpinBox с минимальным значением
    “-5000”, шагом 2, сохранение его в переменную osy;
  5.  добавление объекта osy в объект hb;
  6.  создание экземпляра класса QLabel с текстом y”, сохранение его в переменню txt;
  7.  добавление объекта txt в объект hb;
  8.  создание экземпляра класса QDoubleSpinBox с шагом 2, сохранение его в переменную oscale;
  9.  добавление объекта oscale в объект hb;
  10.  добавление слоя hb в объект glMain; задание расположения в ячейке таблицы с координатами [1;0];
  11.  создание экземпляра класса Custom, сохранение его в переменную paint;
  12.  установка объекта paint в объект glMain; задание расположения в ячейке таблицы с координатами [2;0];
  13.  создание экземпляра класса QTableWidget c параметрами: количество столбцов – 2, количество строк – 0; сохранение его в переменную table;
  14.  устанавка текста в верхние заголовочные ячейки таблицы table в первую и вторую соответственно: “X”, “Y”;
  15.  сохрание экземпляра класса QVBoxLayout, сохранение его в переменную vb;
  16.  добавление объекта table в объект vb;
  17.  создание экземпляра класса QGroupBox с заголовком Координаты точек графика”, сохранение его в переменную box;
  18.  установка слоя vb в объект box;
  19.  создание объекта класса QWidget, сохранение его в переменную wCenter;
  20.  добавление объекта glMain в объект wCenter;
  21.  установка объекта wCenter в качестве компонента окна;
  22.  связывание сигнала valueChanged объектов step, osx, osy, oscale со слотом paramsUpdate в объекте главного окна;
  23.  связывание сигнала editingFinished объектов xmin, xmax со слотом paramsUpdate в объекте главного окна;
  24.  связывание сигнала clicked объекта pb со слотом show объекта box;
  25.  связывание сигнала change в объекте текущего окна со слотом setParams объекта paint;
  26.  связывание сигнала eventTb объекта paint со слотом addTb в объекте главного окна.

Для создания сигнала change реализована функция paramsUpdate по  подготовленному алгоритму в виде блок-схемы (рис. 5.2).

Рисунок 5.2 – Алгоритм функции paramsUpdate

Пояснения к рис. 5.2:

  1.  получение значения объекта step, сохранение его в переменную s;
  2.  получение значения объекта xmin с последующим преобразованием в формат float и сохранением в переменную x0;
  3.  получение значения объекта xmax с последующим преобразованием в формат float и сохранением в переменную x1;
  4.  получение значения объекта osx, сохранение его в переменную sx;
  5.  получение значения объекта osy, сохранение его в переменную sy;
  6.  получение значения объекта oscale, сохранение его в переменную sc;
  7.  создание сигнала change c передачей параметров s, x0, x1, sx, sy, sc.

Для добавления строк в таблицу с координатами точек реализована функция addTb по  подготовленному алгоритму в виде блок-схемы (рис. 5.3).

Для установки некоторых значений по умолчанию в классе Customs реализован конструктор по  подготовленному алгоритму в виде блок-схемы (рис. 5.4).

Для изменения параметров построения графика в классе Customs реализована функция setParams по  подготовленному алгоритму в виде блок-схемы (рис. 5.5).

Рисунок 5.3– Алгоритм функции addTb

Пояснения к рис. 5.3:

  1.  очистка ячеек таблицы table;
  2.  устанавка текста в верхние заголовочные ячейки таблицы table в первую и вторую соответственно: “X”, “Y;
  3.  установка количества строк в таблице равное значению переменной n;
  4.  устанановка значения переменной points[ii] в ячейку таблицы table с координатами [i,0];
  5.  устанановка значения переменной points[ii+1] в ячейку таблицы table с координатами [i,1].

Рисунок 5.4 – Алгоритм конструктора класса Custom

Рисунок 5.5 – Алгоритм функции setParams класса Custom

Для получения координат по оси ординат и добавления координат точек в соответствующую таблицу реализована функция yP по  подготовленному алгоритму в виде блок-схемы (рис. 5.6).

Рисунок 5.6 – Алгоритм функции yP класса Custom

Для отрисовки объектов в рабочем окне программы реализована функция paintEvent по  подготовленному алгоритму в виде блок-схемы (рис. 5.6).

Рисунок 5.6 – Алгоритм функции paintEvent класса Custom, лист 1

Рисунок 5.6 – Алгоритм функции paintEvent класса Custom, лист 2

Рисунок 5.6 – Алгоритм функции paintEvent класса Custom, лист 3

Пояснения к рис. 5.6:

  1.  создание объекта типа данных QPainter с параметром this (отрисовка в текущем окне) и его сохранение в переменную p;
  2.  включении опцию сглажвания «Antialiasing»;
  3.  изменение параметров пера: цвет – чёрный, прозрачность 50%, толщина – 1 пиксель, тип линий «DotLine»;
  4.  отрисовка линии по координатам двух точек: (a;10), (a;d);
  5.  преобразования переменной n в строковой тип данных и последующая его отрисовка по координатам (b;c);
  6.  отрисовка линии по координатам двух точек: (10;a), (d;a);
  7.  преобразования переменной n в строковой тип данных и последующая его отрисовка по координатам (c;b);
  8.  изменение параметров пера: цвет – чёрный, прозрачность 0%, толщина – 1 пиксель, тип линий «SolidLine»;
  9.  отрисовка линии по координатам двух точек: (x0+sx; h) ,(x0+sx; 0);
  10.  отрисовка ломаной линии по координатам точек: (x0-5+sx;7), (x0+sx;0), (x0+5+sx,7);
  11.  отрисовка текста “y” по координатам (x0-15+sx;10);
  12.  отрисовка линии по координатам двух точек: (0;pXy) ,(w; pXy);
  13.  отрисовка ломаной линии по координатам точек: (w-7;pXy), (w;y0+sy), (x0+5+sx,7);
  14.  отрисовка текста “x” по координатам (x0-15+sx;10);
  15.  отрисовка текста “0” по координатам (x0-9+sx; y0+12+sy);
  16.  изменение параметров пера: цвет – RGB(0;153;255);
  17.  отрисовка ломаной линии по координатам содержащимся в массиве точек points.

Листинг файла mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QtGui>

class Custom : public QWidget{

   Q_OBJECT

public:

   int w,h;

   float xMin,xMax,yMin,yMax,step,x0,y0,sx,sy,scale;

   QVector <float> xPoints;

   QVector <float> yPoints;

   Custom();

public slots:

   void yP(QVector <float> xP);

   void setParams(float s,float xM,float xMM, float esx, float esy, float oscale);

private slots:

   void paintEvent(QPaintEvent*);

signals:

   void eventTb(QVector<float> points);

};

class MainWindow : public QMainWindow{

   Q_OBJECT

public:

   QGridLayout *glMain;

   QGroupBox *box;

   QTableWidget* table;

   QSpinBox *osx,*osy;

   QDoubleSpinBox *oscale,*step;

   Custom *paint;

   QWidget *wCenter;

   QHBoxLayout *hb,*hb2;

   QVBoxLayout *vb;

   QLabel *txt;

   QLineEdit *xmin,*xmax;

   QPushButton *pb;

   MainWindow(QWidget *parent = 0);

public slots:

   void paramsUpdate();

   void addTb(QVector<float>points);

signals:

   void change(float step,float xMin,float Xmax, float sx, float sy,float scale);

};

#endif // MAINWINDOW_H

Листинг файла mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)

   : QMainWindow(parent)

{

   QTextCodec:: setCodecForLocale(QTextCodec::codecForName("Windows-1251"));

   QTextCodec:: setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));

   this->setWindowTitle("lab5-312-v11-Кудрявский-Иван");

   setMinimumSize(400,400);

   glMain = new QGridLayout;

   hb2 = new QHBoxLayout();

   txt=new QLabel("f(x) = cos(cos(cos(cos(x^13))))*3/x*x*x");

   hb2->addWidget(txt);

   hb2->addStretch(1);

   pb = new QPushButton("Координаты точек");

   hb2->addWidget(pb);

   glMain->addLayout(hb2,0,0);

   hb = new QHBoxLayout();

   txt= new QLabel("Хmin");

   hb->addWidget(txt);

   xmin = new QLineEdit("-10");

   hb->addWidget(xmin);

   txt = new QLabel("Хmax");

   hb->addWidget(txt);

   xmax = new QLineEdit("10");

   hb->addWidget(xmax);

   txt=new QLabel("Шаг");

   hb->addWidget(txt);

   step = new QDoubleSpinBox;

   step->setValue(0.1);

   step->setSingleStep(0.05);

   step->setMinimum(0.01);

   hb->addWidget(step);

   txt = new QLabel("x");

   hb->addWidget(txt);

   osx = new QSpinBox;

   osx->setMinimum(-5000);

   osx->setSingleStep(2);

   hb->addWidget(osx);

   txt = new QLabel("y");

   hb->addWidget(txt);

   osy = new QSpinBox;

   osy->setMinimum(-5000);

   osx->setSingleStep(2);

   hb->addWidget(osy);

   txt = new QLabel("М");

   hb->addWidget(txt);

   oscale = new QDoubleSpinBox;

   oscale->setValue(1.0);

   oscale->setSingleStep(0.1);

   hb->addWidget(oscale);

   glMain->addLayout(hb,1,0);

   paint = new Custom();

   glMain->addWidget(paint,2,0,10,1);

   table = new QTableWidget(0,2);

   table->setHorizontalHeaderLabels(QStringList() << "X"<<"Y");

   vb = new QVBoxLayout();

   vb->addWidget(table);

   box = new QGroupBox("Координаты точек графика");

   box->setLayout(vb);

   wCenter = new QWidget;

   wCenter->setLayout(glMain);

   this->setCentralWidget(wCenter);

   connect(step,SIGNAL(valueChanged(double)),this,SLOT(paramsUpdate()));

   connect(xmin,SIGNAL(editingFinished()),this,SLOT(paramsUpdate()));

   connect(xmax,SIGNAL(editingFinished()),this,SLOT(paramsUpdate()));

   connect(osx,SIGNAL(valueChanged(int)),this,SLOT(paramsUpdate()));

   connect(osy,SIGNAL(valueChanged(int)),this,SLOT(paramsUpdate()));

   connect(oscale,SIGNAL(valueChanged(double)),this,SLOT(paramsUpdate()));

   connect(pb,SIGNAL(clicked()),box,SLOT(show()));

   connect(this,SIGNAL(change(float,float,float,float,float,float)),paint,SLOT(setParams(float,float,float,float,float,float)));

   connect(paint,SIGNAL(eventTb(QVector<float>)),this,SLOT(addTb(QVector<float>)));

}

void MainWindow::paramsUpdate(){

   float s=step->value();

   float x0=xmin->text().toFloat();

   float x1=xmax->text().toFloat();

   float sx=osx->value();

   float sy=osy->value();

   float sc=oscale->value();

   emit change(s,x0,x1,sx,sy,sc);

}

void MainWindow::addTb(QVector<float>points){

   int n=points.count()/2;

   table->clear();

   table->setHorizontalHeaderLabels(QStringList() << "X"<<"Y");

   table->setRowCount(n);

   for(int i=0,ii=0;i<n;i++,ii+=2){

       table->setItem(i,0,new QTableWidgetItem(QString::number(points[ii])));

       table->setItem(i,1,new QTableWidgetItem(QString::number(points[ii+1])));

   }

}

Custom::Custom(){

   step = 0.1;

   xMin = -10;

   xMax = 10;

   scale = 1;

   sx=0;

   sy=0;

}

void Custom::setParams(float s,float xmin,float xmax,float esx,float esy,float oscale)

{

   step = s;

   xMin = xmin;

   xMax = xmax;

   sx = -esx*10;

   sy = esy*10;

   scale = oscale;

   repaint();

}

void Custom::yP(QVector <float> xP){

   yMax = -99999;

   yMin = 99999;

   float y,x;

   QVector<float>points;

   for(int i=0;i<xP.count();i++){

       x=xP[i];

       y=cos(cos(cos(cos(pow(x,13)))))*3/x*x*x;

       yPoints<<y;

       if(y<yMin)yMin=y;

       if(y>yMax)yMax=y;

       points<<xP[i]<<y;

   }

       eventTb(points);

}

void Custom::paintEvent(QPaintEvent *)

{

   xPoints.clear();

   yPoints.clear();

   w=width();

   h=height();

  float stepx=w/(abs(xMin)+abs(xMax)+abs(xMax)*0.2);

   x0=stepx*(abs(xMin)+abs(xMax)*0.1);

   if(x0<40)x0=40;

   for(float i=xMin;i<=xMax;i=i+step)xPoints<<i;

   yP(xPoints);

   float stepy=h/(abs(yMin)+abs(yMax)+abs(yMax)*0.2);

   y0=stepy*(abs(yMin)+abs(yMax)*0.1);

   if(y0<40)y0=40;

   QPainter p(this);

   p.setRenderHint(QPainter::Antialiasing);

   p.setPen(QPen(QColor(0,0,0,64),1,Qt::DotLine));

   float n,a,b,c,d;

   c=y0+15+sy;

   d=h-10;

  for(int i=1;x0+i*75+sx<=w;i++){//x

      a=x0+i*75+sx;

      b=x0+i*75-15+sx;

      n=(i*75)/stepx/scale;

           p.drawLine(QPoint(a,10),QPoint(a,d));

           p.drawText(b,c,QString::number(n));

       }

   for(int i=1;x0-i*75+sx>=0;i++){

       a=x0-i*75+sx;

       b=x0-i*75-15+sx;

       n=(-i*75)/stepx/scale;

           p.drawLine(QPoint(a,10),QPoint(a,d));

           p.drawText(b,c,QString::number(n));

       }

   c=x0+sx-50;

   d=w-10;

   for(int i=1;y0+i*75+sy<=h;i++){//y

       a=y0+i*75+sy;

       b=y0+i*75+sy;

       n=(-i*75)/stepy/scale;

           p.drawLine(QPoint(10,a),QPoint(d,a));

           p.drawText(c,b,QString::number(n));

       }

   for(int i=1;y0-i*75+sy>=0;i++){

       a=y0-i*75+sy;

       b=y0-i*75+sy;

       n=(i*75)/stepy/scale;

           p.drawLine(QPoint(10,a),QPoint(d,a));

           p.drawText(c,b,QString::number(n));

       }

  float pXy=y0+sy;

   p.setPen(QPen(QColor(0,0,0,255),1,Qt::SolidLine));

   p.drawLine(QPoint(x0+sx,h),QPoint(x0+sx,0)); //y

   p.drawPolyline(QPolygon()<<QPoint(x0-5+sx,7)<<QPoint(x0+sx,0)<<QPoint(x0+5+sx,7));

   p.drawText(x0-15+sx,10,"y");

   p.drawLine(QPoint(0,pXy),QPoint(w,pXy));//x

   p.drawPolyline(QPolygon()<<QPoint(w-7,y0-5+sy)<<QPoint(w,y0+sy)<<QPoint(w-7,y0+5+sy));

   p.drawText(w-15,y0+13+sy,"x");

   p.drawText(x0-9+sx,y0+12+sy,"0");

   QPolygon points;

   float x,y;

   for(int i=0;i<xPoints.count();i++){

       x=(xPoints[i]*scale*stepx+x0+sx);

       y=(yPoints[i]*scale*stepy+y0+sy);

       points<<QPoint(x,y);

   }

   p.setPen(QPen(QColor(0,153,255)));

   p.drawPolyline(points);

}

Результатом выполнения данной программы является окно соответствующее заданию (рис. 5.7).

Рисунок 5.7 Результат выполнения задания

Вывод: написано сложное GUI-приложение, позволяющее пользователю исследовать график в окне приложения.