Файл: Модель солнечной системы.docx

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 09.01.2024

Просмотров: 247

Скачиваний: 15

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


// 1. Угол обзора в направлении OY

// 2. Соотношение X к Y (нужно для пропорций)

// 3. Последние две переменные отвечают за расстояние от зрителя до плоскостей
}

Нужно задать углы просмотра. Для удобства они будут равны 30 градусам:

// .f после числа делает его числом с плавающей запятой.

float mercury_angle = 30.0f; // стартовые углы

float satrun_ring_angle = 30.0f;

float venus_angle = 30.0f;

float earth_angle = 30.0f;

float moon_angle = 30.0f;

float earth_ring_angle = 30.0f;

float mars_angle = 30.0f;

float mars_ring_angle = 30.0f;

float mars_ring_angle2 = 30.0f;

float fobos_angle = 30.0f;

float fobos_angle2 = 30.0f;

float deimos_angle = 30.0f;

float deimos_angle2 = 30.0f;

float jupiter_angle = 30.0f;

float jupiter_angle1 = 30.0f;

float io_ring_angle = 30.0f;

float europa_ring_angle = 30.0f;

float ganimed_ring_angle = 30.0f;

float callisto_ring_angle = 30.0f;

float io_angle = 30.0f;

float europa_angle = 30.0f;

float europa_angle2 = 30.0f;

float satrun_angle = 30.0f;

float uranus_angle = 30.0f;

float uranus_ring_angle = 30.0f;

float neptune_angle = 30.0f;

float neptune_ring_angle = 30.0f;

float triton_angle = 30.0f;

Чтобы нарисовать 3д сцену нам нужна следующая функция(сама работа 2д):

void sceneDraw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очищает указанные буферы, а именно

// Очистка буфера цвета и Очистка буфера глубины. То что содержит данные о цвете пикселя может называться буфером цвета, а то что содержит данные

//о расстоянии пикселя до наблюдателя называется буфером глубины

glMatrixMode(GL_MODELVIEW); // Применяет последующие матричные операции к стеку матриц представления модели.

glLoadIdentity(); // заменяет текущую матрицу матрицей идентификаторов.

glTranslatef(0.0f, 0.0, -50.0f); // модифицируем текущую матрицу ( которая в данный момент единичная).

glScalef(0.4f, 0.4f, 0.4f); // меняет масштаб, приближает/отдаляет
// Строим орбиты планет

circleDraw(4.62); // Функция

circleDraw(9);

circleDraw(12.5);

circleDraw(18.8);

circleDraw(30);

circleDraw(39.5);

circleDraw(52);

circleDraw(63);
planetsDraw(); // Строим планеты
glutSwapBuffers(); //После отрисовки мы переставляем (заменяем) буфера
/*

Swap Buffers - обмен буферов. Используется при анимации.

Мы используем окно с двойной буферизацией, один буфер отображаемый, а другой - спрятанный.

В таком режиме инструкции OpenGL по рисованию изображений всегда применяются к спрятанному буферу.

Вызов функции glutSwapBuffers обменивает буфера, отображая окно целиком после того, как оно уже сформировано.

Эта технология не позволяет человеческому глазу видеть, как линия за линией формируется кадр.


*/
}

Теперь мы будем рисовать планеты, спутники и орбиты спутников при помощи этой функции:

void planetsDraw() {

Рассмотрим сначала построение планеты на примере Солнца:

//Sun

Sun Su;

glPushMatrix(); //для сохранения и восстановления текущих координат

/*

Сдвигает текущий стек матриц на единицу вниз, дублируя текущую матрицу.

То есть после вызова glPushMatrix матрица наверху стека идентична матрице под ним.

*/

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //устанавливает опции для отрисовки многоугольника.

/*

Второй параметр указывает, как будет рисоваться многоугольник.

GL_FILL(рисуем заполненный многоугольник).

Первый параметр указывает: к лицевой, тыльной или же к обеим сторонам применяется опция, заданная вторым параметром.

*/

glColor3f(0.9, 0.9, 0.0);

/*

Следующие строки кода используют команду glColor3f(r, g, b).

Три ее параметра указывают насыщенность цвета красной, синей и зеленой составляющей.

Каждый из них может принимать значение от 0.0f до 1.0f.

*/

glutSolidSphere(Su.getR(), 50, 50);

// Строит сферу с радиусом 2.5,

/*

slices Количество делений вокруг оси Z. (широта)

stacks Количество делений вдоль оси z. (долгота (см. глобус))

*/

glEnd(); // мы закончили рисовать приметив

glPopMatrix(); // извлекает текущий стек матриц, заменяя текущую матрицу той, что находится под ней в стеке.

Далее мы делаем аналогично, но с некоторыми добавлениями.

//Земля

Earth Ea;

glPushMatrix();

glRotatef(earth_angle, 0.0f, 0.0f, 1.0f);//отвечает за вращение планеты вокруг оси. Первый параметр-стартовый угол, затем координаты x, y, z вокруг которых происходит вращательное движение

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glColor3f(0.137255, 0.137255, 0.556863);

glTranslatef(Ea.getS(), 0.0, 0.0f);//задаются координаты x,y,z

glutSolidSphere(Ea.getR(), 50, 50);

glPopMatrix();

Так мы добавили здесь вращение и смещение планеты относительно Солнца.

//Луна

Moon Mo;

glPushMatrix();

glRotatef(moon_angle, 0.0f, 0.0f, 2.0f);

glTranslatef(Mo.getSSun(), 0.0, 0.0f); // отдаляем от Солнца

glRotatef(moon_angle, 0.0f, 0.0f, 2.0f);

glTranslatef(Mo.getS(), 0.0, 0.0f); // расстояние от Земли

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glColor3f(0.8f, 0.8f, 0.8f);

glutSolidSphere(Mo.getR(), 50, 50);



glPopMatrix();

Здесь мы должны еще отдалить наш спутник и от самой планеты, то есть в данном случае от Земли.

//Орбита Луны

glPushMatrix();

glRotatef(earth_ring_angle, 0.0f, 0.0f, 1.0f);

glTranslatef(12.4f, 0.0, 0.0f);

circleDraw(2); // зависимость от радиуса

glPopMatrix();

Здесь мы будем еще обращаться к функции circleDraw(float radius) для построения.

И так далее продолжаем действия с другими планетами, спутниками и орбитами этих спутников.

}

Теперь рассмотрим функцию построения окружности.

void circleDraw(float radius) { // Функция построения окружности с радиусом (радиус - вещественное число)
int cir_x = 0;

int cir_y = 0;

int min_angle = 0;

int max_angle = 360;

float theta;

int i;

float cir_x_itr;

float cir_y_itr;

float x;

float y;
glColor3f(1.0, 1.0, 1.0); // белый цвет

glPushMatrix();

glBegin(GL_LINE_LOOP);//здесь отрезок задается последней и первой вершиной, образуя замкнутую линию

for (i = min_angle; i <= max_angle; i++) { // цикл от 0 до 360 градусов
theta = 0.0174532925 * float(i); // 1 градус это 0.0174532925 радиан. Мы задаём i-ый итерационный угол, theta - угол в рад (мы перевели угол в градусах в угол в радианах ради косинуса и синуса)

cir_x_itr = radius * cosf(theta); // координаты для рисования i-ой итерационной точки по х и у

cir_y_itr = radius * sinf(theta);

x = cir_x + cir_x_itr; // x текущее положение x (то есть прошлое + прибавка нынешнего x)

y = cir_y + cir_y_itr;
glVertex3f(x, y, -30.0f); // Указывает вершины по координатам. Z = -30.0 для соблюдения масштаба

}

glEnd();

glPopMatrix();

}

Данная функция отвечает за движение:

void mercury_update(int value) {

mercury_angle += 2.0f; // 2 градуса в секунду - скорость планеты

if (mercury_angle > 360) {

mercury_angle -= 360;

}
Mercury Me;

glutPostRedisplay(); // помечает активное окно, которое должно быть перерисовано, для вызова основного цикла

glutTimerFunc(Me.getV(), mercury_update, 0);

/*

Эта функция устанавливает таймер.

Первый параметр millis задает время в миллисекундах, по истечении которых вызывается функция,

(вторая космическая скорость)

которая указана как второй параметр.

Третий параметр value указывает индентификатор таймера,

т.е. таймеров может быть одновременно запущено несколько.

*/

}

Посмотрим, как выстроить движение для Земли и ее спутника Луны:

void earth_update(int value) {

earth_angle += 2.0f;

if (earth_angle > 360) {

earth_angle -= 360;


}
Earth Ea;

glutPostRedisplay();

glutTimerFunc(Ea.getV(), earth_update, 0);

}
void moon_update(int value) {

moon_angle += 2.0f; // Скорость, с которой движется объект по орбите

if (moon_angle > 360) {

moon_angle -= 360;

}
Moon Mo;

glutPostRedisplay();

glutTimerFunc(Mo.getV(), moon_update, 0);

}

Движение самой орбиты:

void earth_update_ring(int value) {

earth_ring_angle += 2.0f;

if (earth_ring_angle > 360) {

earth_ring_angle -= 360;

}
glutPostRedisplay();

glutTimerFunc(15, earth_update_ring, 0);

}

int main(int argc, char** argv) {

// argc - количество параметров, передаваемых в функцию main

// argv[] - массив указателей на строки

// argc + argv нужны, чтоб заработал glutInit, когда он через командную строку обращается к своей библиотеке glut
//объявляем все наши классы, чтобы использовать их в таймерах

Mercury Me;

Venus Ve;

Earth Ea;

Moon Mo;

Mars Ma;

Fobos Fo;

Deimos De;

Saturn Sa;

Jupiter Ju;

Io Io;

Europa Eu;

Uranus Ur;

Neptune Ne;

Triton Tr;


/*

glutInit(int **argcp, char **argv);

argc - это указатель на еще не измененную переменную argc главной функции программы (main).

argv - это еще не измененная переменная argv главной функции.
glutInit позаботится об инициализации переменных состояния GLUT

и откроет сессию с системой управления окнами.

*/
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

/* Выбор режима окна:

Одиночный буфер и RGBA палитра */
glutInitWindowSize(1080, 720);

/* Установка размеров окна */
initGL(); // Очистка цвета
glutCreateWindow("2D Solar System"); // Создание окна

initRendering(); // Рендер с тестом глубины

glutDisplayFunc(sceneDraw); // Отрисовка сцены

glutReshapeFunc(handleResize);
Функция, которая выполняет периодичность выполнения, выполняемая функция, идентификатор таймера

glutTimerFunc(Me.getV(), mercury_update, 0);

glutTimerFunc(Ve.getV(), venus_update, 0);

glutTimerFunc(Ea.getV(), earth_update, 0);

glutTimerFunc(Ea.getV(), earth_update_ring, 0);

glutTimerFunc(Mo.getV(), moon_update, 0);

glutTimerFunc(Ma.getV(), mars_update, 0);

glutTimerFunc(Ma.getV(), mars_update_ring, 0);

glutTimerFunc(Ma.getV(), mars_update_ring2, 0);

glutTimerFunc(Fo.getV(), fobos_update, 0);

glutTimerFunc(De.getV(), deimos_update, 0);

glutTimerFunc(De.getV(), deimos_update2, 0);

glutTimerFunc(Ju.getV(), jupiter_update, 0);

glutTimerFunc(Io.getV(), io_update_ring, 0);

glutTimerFunc(Io.getV(), io_update, 0);

glutTimerFunc(Eu.getV(), europa_update_ring, 0);

glutTimerFunc(Eu.getV(), europa_update, 0);

glutTimerFunc(Eu.getV(), europa_update2, 0);

glutTimerFunc(Sa.getV(), saturn_update, 0);

glutTimerFunc(Sa.getV(), saturn_update_ring, 0);

glutTimerFunc(Ur.getV(), uranus_update, 0);

glutTimerFunc(Ne.getV(), neptune_update, 0);

glutTimerFunc(Ne.getV(), neptune_ring_update, 0);

glutTimerFunc(Tr.getV(), triton_update, 0);

glutMainLoop();//внутри функции бесконечного цикла будет происходить контроль за всеми событиями и вызовами функций

return 0;

}

Заключение


Таким образом, в ходе выполнения курсовой работы была смоделирована солнечная система, в которой Солнце и планеты со своими спутниками располагаются на своих астрономических местах и движутся в правильном соотношении.

Из поставленных задач и целей было выполнено:

  1. Построена астрономическая модель солнечной системы;

  2. Был изучен соответствующий материал и литература;

  3. Были изучены основные подходы объектно-ориентированного программирования на С++.

В ходе работы, был как негативный опыт, так и позитивный.

Негативный опыт работы заключается в:

  1. Увеличение объема программы из-за описания каждой планеты;

  2. Необходимость вручную устанавливать вручную библиотеку OpenGL.

Позитивный опыт работы заключается в:

  1. Уменьшении объема программы при помощи функций, применяемых многократно;

  2. Упрощение для понимания и корректировки данных для планет при помощи создания классов;

  3. Отсутствие потребности в больших объемах памяти.

Из практических навыков, которые были получены в процессе выполнения курсовой работы, можно отнести:

  1. Навык работы с классами и объектами;

  2. Навык работы с графической библиотекой OpenGL;

  3. Навык в построении фигур и их анимации.

Список литературы


1) Бьёрн Страуструп. Программирование: принципы и практика использования C++, исправленное изд.: Перевод с англ. — М.: “Вильямс”, 2011.

2) Герберт Шилдт. Полный справочник по C++, 4-е изд.: Перевод с англ. — М.: “Вильямс”, 2011.

3) Стивен Прата. Язык программирования С++. Лекции и упражнения, 6-е изд.: Перевод с англ. - М.: “Вильямс”, 2017.

4) Скотт Мейерс. Эффективный и современный C++: 42 рекомендации по использованию C++11 и C++14: Пер. с англ. — М.: “Вильямс”, 2016.

5) Гради Буч, Роберт А. Максимчук, Майкл У. Энгл, Бобби Дж. Янг, Джим Коналлен, Келли А. Хьюстон. Объектно-ориентированный анализ и проектирование с примерами приложений. — 3-е изд.: Перевод с англ. — М.: — “Вильямс», 2010.

6) Ю.М.Баяковский, А.В.Игнатенко, А.И.Фролов: Графическая библиотека OpenGL, МГУ , учебно-методическое пособие, 2003.

7) Васильев С. А. “OpenGL : компьютерная графика: учебное пособие”, 2012

8) “Основы OpenGL” книга Игоря Тарасова, учебное пособие

9) Компьютерная графика. Учебник и практикум, 2016. Боресков Алексей Викторович, Шикин Евгений Викторович

10) Никулин, Е. А. .