КомпГр_ЛР1_Заболотников_Петрова_Романова_9373
.pdfВыводы.
В данной работе было сформировано решение и реализована программа отображения касательной к двум окружностям с внешней стороны с возможностью редактирования положения и параметров окружностей.
11
ПРИЛОЖЕНИЕ А
Файл «mainwindow.h»
#ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow> #include <QVector> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include "paint.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr); ~MainWindow();
private slots:
void on_btnUpdate_clicked(); void on_btnBuildLine_clicked();
private:
Ui::MainWindow *ui; Paint P;
};
#endif // MAINWINDOW_H
Файл «paint.h»
#ifndef PAINT_H #define PAINT_H #include<QVector>
#include<QtCore/qmath.h>
class Paint
{
public:
Paint();
//Для того, чтобы вытащить полученные значения в дугой класс
QVector<double> getXFigure1(); QVector<double> getXFigure2(); QVector<double> getYUpFigure1(); QVector<double> getYDownFigure1(); QVector<double> getYUpFigure2(); QVector<double> getYDownFigure2(); QVector<double> getXTang(); QVector<double> getYTang();
//Для нахождения x и y
QVector<double> getX(QVector<double>, double);
QVector<double> getUpY(QVector<double>,QVector<double>, double); QVector<double> getDownY(QVector<double>,QVector<double>, double);
//Для задания координат новых кругов
12
void calculateXY();
void setNewCircles(QVector<double>, QVector<double>, double, double); void findTangent();
private: double r1; double r2;
QVector<double> center1; QVector<double> center2; QVector<double> top1; QVector<double> bottom1; QVector<double> x1; QVector<double> top2; QVector<double> bottom2; QVector<double> x2; QVector<double> xTan; QVector<double> yTan;
};
#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);
ui->widget->xAxis->setRange(-10,10); ui->widget->yAxis->setRange(-10,10); ui->widget->setInteraction(QCP::iRangeZoom, true); ui->widget->setInteraction(QCP::iRangeDrag, true);
ui->widget->addGraph(); ui->widget->graph(0)->setData(P.getXFigure1(),P.getYUpFigure1()); ui->widget->addGraph(); ui->widget->graph(1)->setData(P.getXFigure1(),P.getYDownFigure1()); ui->widget->addGraph(); ui->widget->graph(2)->setData(P.getXFigure2(),P.getYUpFigure2()); ui->widget->addGraph(); ui->widget->graph(3)->setData(P.getXFigure2(),P.getYDownFigure2()); ui->widget->addGraph(); ui->widget->graph(4)->setData(P.getXTang(),P.getYTang()); ui->widget->replot();
setMinimumSize(QSize(410,450));
}
13
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnUpdate_clicked()
{
double CX1 = ui->lineEdit->text().toDouble(); double CY1 = ui->lineEdit_2->text().toDouble(); double R1 = ui->lineEdit_3->text().toDouble(); double CX2 = ui->lineEdit_5->text().toDouble(); double CY2 = ui->lineEdit_6->text().toDouble(); double R2 = ui->lineEdit_4->text().toDouble();
P.setNewCircles({CX1,CY1}, {CX2,CY2}, R1, R2);
P.calculateXY();
ui->widget->graph(0)->setData(P.getXFigure1(),P.getYUpFigure1()); ui->widget->graph(1)->setData(P.getXFigure1(),P.getYDownFigure1()); ui->widget->graph(2)->setData(P.getXFigure2(),P.getYUpFigure2()); ui->widget->graph(3)->setData(P.getXFigure2(),P.getYDownFigure2()); ui->widget->graph(4)->setVisible(false);
ui->widget->replot();
}
void MainWindow::on_btnBuildLine_clicked()
{
P.findTangent(); ui->widget->graph(4)->setData(P.getXTang(),P.getYTang()); ui->widget->graph(4)->setVisible(true); ui->widget->replot();
}
Файл «paint.cpp»
#include "paint.h"
Paint::Paint()
{
r1 = 1;
center1 = {1, 2}; r2 = 1;
center2 = {-2, -3};
calculateXY();
findTangent();
}
QVector<double> Paint::getXFigure1()
{
return x1;
}
QVector<double> Paint::getXFigure2()
14
{
return x2;
}
QVector<double> Paint::getYUpFigure1()
{
return top1;
}
QVector<double> Paint::getYDownFigure1()
{
return bottom1;
}
QVector<double> Paint::getYUpFigure2()
{
return top2;
}
QVector<double> Paint::getYDownFigure2()
{
return bottom2;
}
QVector<double> Paint::getXTang()
{
return xTan;
}
QVector<double> Paint::getYTang()
{
return yTan;
}
QVector<double> Paint::getX(QVector<double> center, double r)
{
QVector<double> x;
double lend = center[0] - r; double rend = center[0] + r;
for(float i = lend; i < rend; i = i + 0.01)
{
x.push_back(i);
}
x.push_back(rend); return x;
}
QVector<double> Paint::getUpY(QVector<double> x,QVector<double> center, double r)
{
QVector<double> y;
double c = center[0]*center[0] + center[1]*center[1] - r*r; double d = 2*center[1];
double buf;
for(int i = 0; i < x.count(); i++)
{
buf = d+sqrt(d*d-4*(c+x[i]*x[i]-2*center[0]*x[i])); y.push_back(buf/2);
}
15
return y;
}
QVector<double> Paint::getDownY(QVector<double> x,QVector<double> center, double r)
{
QVector<double> y;
double c = center[0]*center[0] + center[1]*center[1] - r*r; double d = 2*center[1];
double buf;
for(int i = 0; i < x.count(); i++)
{
buf = d-sqrt(d*d-4*(c+x[i]*x[i]-2*center[0]*x[i])); y.push_back(buf/2);
}
return y;
}
void Paint::calculateXY()
{
x1 = getX(center1, r1);
top1 = getUpY(x1, center1, r1); bottom1 = getDownY(x1, center1, r1);
x2 = getX(center2, r2);
top2 = getUpY(x2, center2, r2); bottom2 = getDownY(x2, center2, r2);
}
void Paint::setNewCircles(QVector<double> center1_new, QVector<double> center2_new, double r1_new, double r2_new)
{
center1 = center1_new; center2 = center2_new; r1 = r1_new;
r2 = r2_new;
}
void Paint::findTangent()
{
xTan.clear();
yTan.clear();
//Найдём расстояние между центрами double len;
len = sqrt(pow((center1[0]-center2[0]),2)+(pow((center1[1]- center2[1]),2)));
//Найдем отношения радиусов
double r_max, r_min, x_min, x_max, y_min, y_max; double b_new;
double beta_ang; double beta_cos;
double x_max_new, y_max_new, k,b, buf1, buf2; double sin_alpha, cos_alpha;
if(r1 >= r2)
{
r_max = r1; r_min = r2;
x_max = center1[0]; y_max = center1[1]; x_min = center2[0]; y_min = center2[1];
}
16
else
{
r_max = r2; r_min = r1;
x_max = center2[0]; y_max = center2[1]; x_min = center1[0]; y_min = center1[1];
}
// Проверим есть ли касательная в принципе if (len < r_max-r_min)
{
return;
}
else
{
if((x_max + r_max == x_min + r_min) && (y_max >= y_min))
{
xTan.push_back(x_max+r_max); xTan.push_back(x_min+r_min); yTan.push_back(y_max+r_max); yTan.push_back(y_min-r_min); return;
}
else if ((x_max - r_max == x_min - r_min) && (y_max <= y_min))
{
xTan.push_back(x_max-r_max); xTan.push_back(x_min-r_min); yTan.push_back(y_max-r_max); yTan.push_back(y_min+r_min); return;
}
else
{
//Найдём угол поворота b_new = 0;
sin_alpha = (r_max-r_min)/len;
cos_alpha = sqrt(1 - pow(sin_alpha, 2));
//Повернём центр большей окружности относительно малой //Сместимм прямую на расстояние меньшего радиуса
x_max_new = (x_max-x_min)*cos_alpha - (y_max-y_min)*(-sin_alpha)
+ x_min;
y_max_new = (x_max-x_min)*(-sin_alpha) + (y_max-y_min)*cos_alpha
+ y_min;
k = (y_max_new - y_min)/(x_max_new - x_min);
buf1 = (x_min*(y_min - y_max_new)+y_min*(-x_min+x_max_new)); buf2 = (x_max_new - x_min);
b = buf1/buf2; beta_ang = qAtan(k);
beta_cos = qCos(beta_ang);
if (((x_max + r_max > x_min + r_min) && (y_max > y_min)) || ((x_max - r_max > x_min - r_min) && (y_max == y_min)) || ((x_max - r_max > x_min - r_min) && (y_max < y_min)))
{
b_new = b - r_min/beta_cos;
}
else if (((x_max - r_max < x_min - r_min) && (y_max < y_min)) || ((x_max + r_max < x_min + r_min) && (y_max == y_min)) || ((x_max + r_max < x_min + r_min) && (y_max > y_min)))
{
b_new = b + r_min/beta_cos;
}
17
double lend = qMin(x_max,x_min)-2*r_max; double rend = qMax(x_max,x_min)+2*r_max; xTan.push_back(lend); xTan.push_back(rend); yTan.push_back((k)*xTan[0]+b_new); yTan.push_back((k)*xTan[1]+b_new);
}
}
}
18