Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

КомпГр_ЛР4_Заболотников_Петрова_Романова_9373

.pdf
Скачиваний:
13
Добавлен:
20.06.2023
Размер:
873.64 Кб
Скачать

МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра ИС

ОТЧЕТ по лабораторной работе№4

по дисциплине «Компьютерная графика» Тема: Исследование алгоритмов отсечения отрезков и многоугольников

окнами различного вида

Студент гр. 9373

_______________

Заболотников М. Е.

Студентка гр. 9373

_______________

Петрова С. В.

Студентка гр. 9373

_______________

Романова Е. С.

Преподаватель

_______________

Матвеева И.В.

Санкт-Петербург

2022

Цель работы.

Обеспечить реализацию алгоритма отсечения произвольного многоугольника заданным произвольным выпуклым окном. Исходный и отсеченный многоугольники следует на экране прорисовывать различными цветами.

Задание на работу.

Необходимо написать программу, которая рисует по точкам многоугольник и выпуклое окно и выделить отдельным цветом их пересечение, если оно присутствует.

Общие сведения.

Выпуклым многоугольником называется многоугольник, все точки которого лежат по одну сторону от любой прямой, проходящей через две его соседние вершины (см. рис. 1).

Рисунок 1 – Пример выпуклого многоугольника

Ход работы.

Рассмотрим работу программы. Сперва вызывается функция, в теле которой происходит проверка многоугольника и окна на выпуклость. Данная

проверка происходит следующим образом: совершался обход по контуру

2

многоугольника и контроль за тем, в какую сторону мы поворачиваем при продвижении от текущей вершины многоугольника к следующей. Если повороты были все в одну сторону (скажем, направо – при обходе по часовой стрелке), значит, многоугольник выпуклый; если же в какой-то момент мы повернули в другую сторону – невыпуклый. После проверки происходит отрисовка фигур и находится фигура, являющейся пересечением многоугольника и окна, то есть выделение видимой части многоугольника.

Выполнение работы.

Ссылка на видео с демонстрацией работы программы: https://www.youtube.com/watch?v=5s05NyRd9Q4

Программа была написана в приложении Qt на языке С++ с

использованием графических библиотек.

Для работы с программой необходимо ввести количество точек для полигона и для окна. Затем ввести координаты точек, и нажать на «Обновить»,

если координаты введены верно, то программа построит два многоугольника,

если нет – программа выдаст сообщение о невозможности построение фигур,

в связи их не выпуклостью. После отрисовки следует нажать на кнопку

«Выделить пересечение», и если программой были найдены точки пересечения, то на графике появится отсеченный многоугольник, выделенный темным цветом, если же нет, то в сообщениях будет отображено отсутствие видимой части многоугольника.

Тесты работы программы.

На рис. 2 – 4 представлены результаты выполнения работы программы:

3

Рисунок 2 – Отсеченный многоугольник

Рисунок 3 – Отсеченный многоугольник

4

Рисунок 4 – Многоугольник не виден, так как находится за пределами окна

Рисунок 5 – Невыпуклое окно, Y4=10, изначально было -10, что видно на рисунке

5

Выводы.

В данной работе была реализована программа отображения отсеченного

многоугольника выпуклым окном от исходного многоугольника. Новый

многоугольник имеет тёмный цвет.

6

ПРИЛОЖЕНИЕ А

Файл «mainwindow.h»

#ifndef MAINWINDOW_H #define MAINWINDOW_H

#include <QMainWindow> #include <QVector> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include "paint.h" #define COUNT 5

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; } QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

MainWindow(QWidget *parent = nullptr); ~MainWindow();

void createPlot();

void drawInterPoly(QVector<QVector<double>>);

private slots:

void on_btnUpdate_clicked();

void on_lineNumberPointsWindow_textChanged(const QString &arg1); void on_lineNumberPointsPolygon_textChanged(const QString &arg1);

void on_btnBuildLine_clicked();

private:

Ui::MainWindow *ui; Paint P;

bool flagFirstPlot; bool flagFirstInter;

};

#endif // MAINWINDOW_H

Файл «paint.h»

#ifndef PAINT_H #define PAINT_H #include<QVector>

#include<QtCore/qmath.h>

class Paint

{

public:

Paint();

//Для того, чтобы вытащить полученные значения в дугой класс double getxP(int);

double getyP(int);

7

double getxW(int); double getyW(int); QVector<double> getPx(); QVector<double> getPy(); QVector<double> getWx(); QVector<double> getWy(); void clearP();

void clearW();

void setNewPointsPoly(double, double, double, double, double, double, double, double, double, double);

void setNewPointsWin(double, double, double, double, double, double, double, double, double, double);

void setNumWin(int); void setNumPoly(int); bool ifBump(bool); int getNumWin();

int getNumPoly(); int fact(int);

QVector<double> XOfInter(int,int,int,int); QVector<double> pointAngle(int,int,int);

double Angle(double,double,double,double,double,double); QVector<double> pointAngle2(int,int,int); QVector<QVector<double>> sortPoints(QVector<QVector<double>>);

private:

int numberOfPointsWindow; int numberOfPointsPolygon;

QVector<double> PxBegin; //Позиции иксов среди точек для построения при getPx

QVector<QVector<double>> Px; //Х полигона QVector<QVector<double>> Py; //Y полигона QVector<QVector<double>> Wx; //Х окна QVector<QVector<double>> Wy; //Y окна

};

#endif // PAINT_H

Файл «main.cpp»

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv); MainWindow w;

w.show();

return a.exec();

}

Файл «mainwindow.cpp»

#include "mainwindow.h" #include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this); flagFirstPlot = true; flagFirstInter = true;

8

ui->widget->xAxis->setRange(-10,10); ui->widget->yAxis->setRange(-10,10); ui->widget->setInteraction(QCP::iRangeZoom, true); ui->widget->setInteraction(QCP::iRangeDrag, true);

//Рисуем точки для полигона

P.setNumPoly(4);

P.setNumWin(3);

createPlot(); flagFirstPlot = false;

//Наведём красоту на график полигон for (int i = 0; i < COUNT; i++)

{

ui->widget->graph(i)->setPen(QColor(148,87,235, 255));//задаем цвет

точки

ui->widget->graph(i)->setLineStyle(QCPGraph::lsLine);//убираем линии ui->widget->graph(i)-

>setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 4));

}

//Наведём красоту на график экрана for (int i = COUNT; i < COUNT*2; i++)

{

ui->widget->graph(i)->setPen(QColor(235,76,66, 255));//задаем цвет

точки

ui->widget->graph(i)->setLineStyle(QCPGraph::lsLine);//убираем линии ui->widget->graph(i)-

>setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 4));

}

ui->lineX1->setEnabled(true); ui->lineY1->setEnabled(true); ui->lineX2->setEnabled(true); ui->lineY2->setEnabled(true); ui->lineX3->setEnabled(true); ui->lineY3->setEnabled(true); ui->lineX4->setEnabled(true); ui->lineY4->setEnabled(true);

ui->lineX1_W->setEnabled(true); ui->lineY1_W->setEnabled(true); ui->lineX2_W->setEnabled(true); ui->lineY2_W->setEnabled(true); ui->lineX3_W->setEnabled(true); ui->lineY3_W->setEnabled(true);

ui->lineX5->setEnabled(false); ui->lineY5->setEnabled(false);

ui->lineX4_W->setEnabled(false); ui->lineY4_W->setEnabled(false); ui->lineX5_W->setEnabled(false); ui->lineY5_W->setEnabled(false);

setMinimumSize(QSize(410,450));

}

MainWindow::~MainWindow()

{

delete ui;

}

9

void MainWindow::on_btnUpdate_clicked()

{

if(!flagFirstInter)

{

for (int i = 10; i < 19; i++)

{

ui->widget->graph(i)->setVisible(false);

}

}

int numPoly = ui->lineNumberPointsPolygon->text().toInt(); int numWin = ui->lineNumberPointsWindow->text().toInt(); P.setNumPoly(numPoly);

P.setNumWin(numWin); ui->Massage->setText("Сообщения:");

double x1_new = ui->lineX1->text().toDouble(); double x2_new = ui->lineX2->text().toDouble(); double x3_new = ui->lineX3->text().toDouble(); double x4_new = ui->lineX4->text().toDouble(); double x5_new = ui->lineX5->text().toDouble(); double y1_new = ui->lineY1->text().toDouble(); double y2_new = ui->lineY2->text().toDouble(); double y3_new = ui->lineY3->text().toDouble(); double y4_new = ui->lineY4->text().toDouble(); double y5_new = ui->lineY5->text().toDouble();

double x1_newW = ui->lineX1_W->text().toDouble(); double x2_newW = ui->lineX2_W->text().toDouble(); double x3_newW = ui->lineX3_W->text().toDouble(); double x4_newW = ui->lineX4_W->text().toDouble(); double x5_newW = ui->lineX5_W->text().toDouble(); double y1_newW = ui->lineY1_W->text().toDouble(); double y2_newW = ui->lineY2_W->text().toDouble(); double y3_newW = ui->lineY3_W->text().toDouble(); double y4_newW = ui->lineY4_W->text().toDouble(); double y5_newW = ui->lineY5_W->text().toDouble();

P.setNewPointsPoly(x1_new, x2_new, x3_new,x4_new,x5_new, y1_new, y2_new, y3_new,y4_new,y5_new);

P.setNewPointsWin(x1_newW, x2_newW, x3_newW,x4_newW,x5_newW, y1_newW, y2_newW, y3_newW,y4_newW,y5_newW);

createPlot();

for (int i = 0; i < COUNT; i++)

{

if(i<P.getNumPoly())

{

ui->widget->graph(i)->setVisible(true);

}

else

{

ui->widget->graph(i)->setVisible(false);

}

}

for (int i = COUNT; i < 2*COUNT; i++)

{

if(i-COUNT<P.getNumWin())

{

ui->widget->graph(i)->setVisible(true);

}

else

{

10