-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
226 lines (192 loc) · 9.42 KB
/
main.cpp
File metadata and controls
226 lines (192 loc) · 9.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include <QApplication>
#include <QMainWindow>
#include <QTimer>
#include <QDateTime>
#include <cmath>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
#include <QLabel>
#include "earthwidget.h"
int main(int argc, char *argv[])
{
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSamples(4); // Включаем MSAA
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
format.setSwapInterval(1); // Включаем V-Sync
QSurfaceFormat::setDefaultFormat(format);
QApplication a(argc, argv);
QMainWindow mainWindow;
// Создаем центральный виджет и layout
QWidget* centralWidget = new QWidget(&mainWindow);
QVBoxLayout* layout = new QVBoxLayout(centralWidget);
// Создаем горизонтальный layout для EarthWidget и информационной панели
QHBoxLayout* mainLayout = new QHBoxLayout();
layout->addLayout(mainLayout);
// Создаем EarthWidget
EarthWidget* earthWidget = new EarthWidget(centralWidget);
mainLayout->addWidget(earthWidget, 4); // Соотношение 4:1
// Создаем панель информации
QWidget* infoPanel = new QWidget(centralWidget);
QVBoxLayout* infoPanelLayout = new QVBoxLayout(infoPanel);
QLabel* infoLabel = new QLabel("Satellite Information:", infoPanel);
QLabel* satelliteInfo = new QLabel("No satellite selected", infoPanel);
satelliteInfo->setWordWrap(true);
infoPanelLayout->addWidget(infoLabel);
infoPanelLayout->addWidget(satelliteInfo);
infoPanelLayout->addStretch();
mainLayout->addWidget(infoPanel, 1); // Соотношение 4:1
QHBoxLayout* buttonLayout = new QHBoxLayout();
layout->addLayout(buttonLayout);
// Создаем кнопку для управления вращением Земли
QPushButton* earthRotationButton = new QPushButton("Stop Earth Rotation", centralWidget);
layout->addWidget(earthRotationButton);
// Добавляем кнопку для осей
QPushButton* axisToggleButton = new QPushButton("Hide Axes", centralWidget);
buttonLayout->addWidget(axisToggleButton);
// Устанавливаем центральный виджет
mainWindow.setCentralWidget(centralWidget);
// Обработчик нажатия кнопки вращения Земли
QObject::connect(earthRotationButton, &QPushButton::clicked, [earthWidget, earthRotationButton]() {
bool isAnimating = earthWidget->toggleEarthAnimation();
earthRotationButton->setText(isAnimating ? "Stop Earth Rotation" : "Start Earth Rotation");
});
// QObject::connect(axisToggleButton, &QPushButton::clicked, [earthWidget, axisToggleButton]() {
// bool isVisible = earthWidget->toggleAxisVisibility();
// axisToggleButton->setText(isVisible ? "Hide Axes" : "Show Axes");
// });
// Создаем спутники с разными скоростями вращения
const float EARTH_RADIUS = 6371000.0f; // Радиус Земли в метрах
const float ORBIT_RADIUS = EARTH_RADIUS * 1.5f;
struct SatelliteData {
float angle;
float speed;
int id;
QVector3D position;
// Функция расчета траекторий для дуги в 30 градусов
void calculateTrajectories(float orbitRadius, QVector<QVector3D>& trajectory, QVector<QVector3D>& futureTrajectory) {
trajectory.clear();
// Расчет траектории: 30 градусов назад и вперед от текущей позиции
const int arcPoints = 30; // количество точек для дуги в 30 градусов
const float arcRange = 30.0f; // диапазон в градусах
// Рассчитываем точки для текущей дуги траектории
for (int i = -arcPoints; i <= arcPoints; ++i) {
float arcAngle = qDegreesToRadians(angle + (i * arcRange / arcPoints));
trajectory.append(QVector3D(
orbitRadius * cos(arcAngle),
0.0f,
orbitRadius * sin(arcAngle)
));
}
// Расчет будущей траектории (следующие 30 градусов)
futureTrajectory.clear();
const int futurePoints = 30;
const float predictionTime = 5.0f; // время прогноза в секундах
float timeStep = predictionTime / futurePoints;
for (int i = 0; i <= futurePoints; ++i) {
float futureTime = timeStep * i;
float futureAngle = qDegreesToRadians(angle + speed * futureTime);
futureTrajectory.append(QVector3D(
orbitRadius * cos(futureAngle),
0.0f,
orbitRadius * sin(futureAngle)
));
}
}
};
QVector<SatelliteData> satelliteData;
satelliteData.append({0.0f, 1.0f, 1});
satelliteData.append({72.0f, 2.0f, 2});
satelliteData.append({144.0f, 3.0f, 3});
satelliteData.append({216.0f, 4.0f, 4});
satelliteData.append({288.0f, 5.0f, 5});
// Обновление информации о выбранном спутнике
QObject::connect(earthWidget, &EarthWidget::satelliteSelected,
[satelliteInfo, &satelliteData, ORBIT_RADIUS](int id) {
if (id == -1) {
satelliteInfo->setText("No satellite selected");
return;
}
for (const auto& sat : satelliteData) {
if (sat.id == id) {
QString info = QString(
"Satellite ID: %1\n"
"Speed: %2°/s\n"
"Current Angle: %3°\n"
"Position:\n"
"X: %4 m\n"
"Y: %5 m\n"
"Z: %6 m\n"
"Orbit Radius: %7 km\n"
"Time: %8"
)
.arg(sat.id)
.arg(sat.speed)
.arg(sat.angle, 0, 'f', 2)
.arg(sat.position.x(), 0, 'f', 2)
.arg(sat.position.y(), 0, 'f', 2)
.arg(sat.position.z(), 0, 'f', 2)
.arg(ORBIT_RADIUS / 1000.0, 0, 'f', 2)
.arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd HH:mm:ss"));
satelliteInfo->setText(info);
break;
}
}
});
// Таймер для обновления позиций спутников
QTimer* timer = new QTimer(&mainWindow);
// В таймере обновления позиций:
QObject::connect(timer, &QTimer::timeout, [=, &satelliteData]() mutable {
for(auto& sat : satelliteData) {
sat.angle += sat.speed * (16.0f / 1000.0f);
if(sat.angle >= 360.0f) {
sat.angle -= 360.0f;
}
float radians = qDegreesToRadians(sat.angle);
sat.position = QVector3D(
ORBIT_RADIUS * cos(radians),
0.0f,
ORBIT_RADIUS * sin(radians)
);
// Обновляем траектории
QVector<QVector3D> trajectory, futureTrajectory;
sat.calculateTrajectories(ORBIT_RADIUS, trajectory, futureTrajectory);
earthWidget->updateSatellitePosition(
sat.id,
sat.position,
trajectory,
futureTrajectory,
sat.angle
);
if (earthWidget->getSelectedSatelliteId() == sat.id) {
emit earthWidget->satelliteSelected(sat.id);
}
}
});
// При инициализации спутников:
for(auto& sat : satelliteData) {
float radians = qDegreesToRadians(sat.angle);
sat.position = QVector3D(
ORBIT_RADIUS * cos(radians),
0.0f,
ORBIT_RADIUS * sin(radians)
);
QVector<QVector3D> trajectory, futureTrajectory;
sat.calculateTrajectories(ORBIT_RADIUS, trajectory, futureTrajectory);
earthWidget->addSatellite(
sat.id,
sat.position,
QString("Satellite %1 (Speed: %2°/s)").arg(sat.id).arg(sat.speed)
);
}
// Запускаем таймер
timer->start(16);
mainWindow.resize(1024, 768);
mainWindow.show();
return a.exec();
}