Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CCC.doc
Скачиваний:
6
Добавлен:
09.08.2019
Размер:
146.43 Кб
Скачать

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

Сибирский государственный аэрокосмический университет

имени академика М. Ф. Решетнева

Кафедра безопасности информационных технологий (БИТ)

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

Невозмущённое движение

Выполнил ст. гр. КБ-81:

Билецкая Н.А.

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

Малухин Д.В.

Красноярск 2011

Содержание

Содержание 2

ЦЕЛЬ РАБОТЫ: Изучить орбитальное движения космических аппаратов (КА), отработать расчёт траекторий орбитального движения космических аппаратов на практике. 3

ЗАДАЧИ 3

ЗАКЛЮЧЕНИЕ 17

Цель работы: Изучить орбитальное движения космических аппаратов (ка), отработать расчёт траекторий орбитального движения космических аппаратов на практике. Задачи

В программе реализовывались следующие возможности:

  1. В области 3D-отображения:

  • Отображение осей координат (0X, 0Y, 0Z).

  • Создание модели планеты Земля с наложенной текстурой.

  • Создание орбиты КА посредством задания долготы восходящего узла, наклонения орбиты, аргумента перигея, эксцентриситета и фокального параметра орбиты.

  • Отображение проекции орбиты на поверхность Земли.

  • Моделирование движения КА по заданной орбите. Земля и КА вращаются в одном масштабе времени (По умолчанию масштаб времени 1:1).

  • Предусмотрена возможность ускорения течения времени и его остановку.

  • Отображение проекции КА на поверхность Земли.

  1. В области 2D-отображения:

  • Отображение проекции трассы КА на поверхность Земли, её движение.

  • Отображение проекции КА на поверхность Земли.

  1. Отображение текущих параметров КА:

  • Период обращения.

  • Широта, долгота.

  • Составляющие вектора скорости и абсолютная скорость.

  • Координаты и длина радиус-вектора.

ХОД РАБОТЫ

  1. В области 3d-отображения.

Для того чтобы нарисовать оси координат 0X, 0Y, 0Z используем оператор рисования точек в 3D - glVertex3f(_,_,_), предварительно указав параметр GL_LINES в объявлении gLBegin(_). Также с помощью оператора glNormal3f(_,_,_) задаём координаты для источника света, а с помощью оператора glMaterialfv(_,_,_) задаём характеристики поверхности:

glBegin(GL_LINES);

glNormal3f(7,7,7);

glMaterialfv(GL_FRONT,GL_AMBIENT,@Material[1]);

glMaterialfv(GL_FRONT,GL_DIFFUSE,@Material[1]);

glMaterialfv(GL_FRONT,GL_SPECULAR,@Material[4]);

glVertex3f(0,0,0);

glVertex3f(3,0,0);

glMaterialfv(GL_FRONT,GL_AMBIENT,@Material[2]);

glMaterialfv(GL_FRONT,GL_DIFFUSE,@Material[2]);

glMaterialfv(GL_FRONT,GL_SPECULAR,@Material[4]);

glVertex3f(0,0,0);

glVertex3f(0,3,0);

glMaterialfv(GL_FRONT,GL_AMBIENT,@Material[3]);

glMaterialfv(GL_FRONT,GL_DIFFUSE,@Material[3]);

glMaterialfv(GL_FRONT,GL_SPECULAR,@Material[4]);

glVertex3f(0,0,0);

glVertex3f(0,0,3);

glEnd;

Создаем новый модуль Unit – OrbitUnit.

В нём создаём константу для радиуса, массивы для координат в пространстве и на плоскости, а также класс, в котором будут содержаться переменные эксцентриситет и фокальный параметр и функция GetPos, которая рассчитывает координаты точки от истинной аномалии согласно уравнению в полярных координатах, смысл котоого заключается в следующем:

Если принять фокус эллипса за полюс, а большую ось — за полярную ось, то его уравнение в полярных координатах   будет иметь вид

где e — эксцентриситет, а p — фокальный параметр. При положительном знаке перед e второй фокус эллипса будет находиться в точке   а при отрицательном — в точке   где фокальное расстояние 

е - эксцентриситет — числовая характеристика конического сечения, показывающая степень его отклонения от окружности.

р - фокальный параметр, .

Истинная аномалия - угол между большой полуосью и лучом из фокуса в положение.

function TOrbit.GetPos(uVal:real):TPoint3D;

var Rad:real;

Begin

Rad:=p/(1+e*cos(uVal));

Result[1]:=Rad*cos(uVal);

Result[2]:=Rad*sin(uVal);

Result[3]:=0;

End;

Создаём объект TОrbit с помощью вызова конструктора Orbit:=TOrbit.Create в модуле CreataForm. Затем мы создаём 2 скроллбара для изменения значений эксцентриситета и фокального параметра.

Для того чтобы нарисовать Землю, разобьём всю поверхность на треугольники. С помощью них будем накладывать текстуру, задавая координаты вершин треугольников.

с1 с3

с2 с4

Для того, чтобы совпадала лицевая сторона, обход должен быть в одну сторону, т.е. с1, с2, с3 => с2, с4, с3.

Чтобы преобразовывать координаты из 2D в 3D добавляем функцию Translate2Dto3D:

function TOrbit.Translate2Dto3D(Point2D:TPoint2D):TPoint3D;

begin

Result[1]:=EARTH_RAD*cos(Point2D[1]*2*pi)*cos((Point2D[2]-0.5)*pi);

Result[2]:=EARTH_RAD*sin(Point2D[1]*2*pi)*cos((Point2D[2]-0.5)*pi);

Result[3]:=EARTH_RAD*sin((Point2D[2]-0.5)*pi);

end;

Далее отрисовываем треугольники, предварительно задав переменные координат текстуры и координат в пространстве. Также для ощущения объёмности перед каждой точкой задаём нормали:

glMaterialfv(GL_FRONT,GL_AMBIENT,@Material[6]);

glMaterialfv(GL_FRONT,GL_DIFFUSE,@Material[6]);

glMaterialfv(GL_FRONT,GL_SPECULAR,@Material[4]);

glBegin(GL_Triangles);

for q1:= 0 to 99 do

for q2:=0 to 99 do begin

c1[1]:=q1/100;

c1[2]:=1-q2/100;

c2[1]:=q1/100;

c2[2]:=1-(q2+1)/100;

c3[1]:=(q1+1)/100;

c3[2]:=1-q2/100;

c4[1]:=(q1+1)/100;

c4[2]:=1-(1+q2)/100;

p1:=Orbit.Translate2DTo3d(c1);

p2:=Orbit.Translate2DTo3d(c2);

p3:=Orbit.Translate2DTo3d(c3);

p4:=Orbit.Translate2DTo3d(c4);

//1ый треугольник

glNormal3f(p1[1]/EARTH_Rad,p1[2]/Earth_Rad,p1[3]/Earth_Rad);

glTexCoord2f(c1[1],c1[2]);

glVertex3f(p1[1]/EARTH_Rad,p1[2]/Earth_Rad,p1[3]/Earth_Rad);

glNormal3f(p2[1]/EARTH_Rad,p2[2]/Earth_Rad,p2[3]/Earth_Rad);

glTexCoord2f(c2[1],c2[2]);

glVertex3f(p2[1]/EARTH_Rad,p2[2]/Earth_Rad,p2[3]/Earth_Rad);

glNormal3f(p3[1]/EARTH_Rad,p3[2]/Earth_Rad,p3[3]/Earth_Rad);

glTexCoord2f(c3[1],c3[2]);

glVertex3f(p3[1]/EARTH_Rad,p3[2]/Earth_Rad,p3[3]/Earth_Rad);

//2ой треугольник

glNormal3f(p2[1]/EARTH_Rad,p2[2]/Earth_Rad,p2[3]/Earth_Rad);

glTexCoord2f(c2[1],c2[2]);

glVertex3f(p2[1]/EARTH_Rad,p2[2]/Earth_Rad,p2[3]/Earth_Rad);

glNormal3f(p4[1]/EARTH_Rad,p4[2]/Earth_Rad,p4[3]/Earth_Rad);

glTexCoord2f(c4[1],c4[2]);

glVertex3f(p4[1]/EARTH_Rad,p4[2]/Earth_Rad,p4[3]/Earth_Rad);

glNormal3f(p3[1]/EARTH_Rad,p3[2]/Earth_Rad,p3[3]/Earth_Rad);

glTexCoord2f(c3[1],c3[2]);

glVertex3f(p3[1]/EARTH_Rad,p3[2]/Earth_Rad,p3[3]/Earth_Rad);

end;

glEnd;

Для отрисовки орбиты переходим в модуль рисования в пространстве. Делать это будем с помощью линий. Чтобы получать координаты точек нужно использовать значения истинной аномалии от 0 до 360 градусов:

glMaterialfv(GL_FRONT,GL_AMBIENT,@Material[1]);

glMaterialfv(GL_FRONT,GL_DIFFUSE,@Material[1]);

glMaterialfv(GL_FRONT,GL_SPECULAR,@Material[4]);

glNormal3f(1,1,1);//нормаль в точке с координатами 1 1 1

glBegin(gl_LINE_LOOP);

glVertex3f(0,0,0);

for q1:=0 to 360 do

begin

Cord:=Orbit.GetPos(pi*(q1/180));

glVertex3f(Cord[1]/EARTH_RAD,Cord[2]/EARTH_RAD,Cord[3]/EARTH_RAD);

end;

glEnd;

Для вращения орбиты по 3м направлениям нам необходимо вычислять координаты, зависящие от 3х углов: Q – долгота восходящего узла (угол между узлом восхождения и точкой восходящей орбиты),w – аргумент перегея (угол наклона прямой, на которой находится перегей относительно прямой долготы восходящего узла), ί – наклонение орбиты (угол, на который плоскость орбиты наклонена относительно плоскости эклиптики). Чтобы вычислять новые координаты необходимо старые координаты умножать на матрицу поворота, полученную в результате перемножения 3х матриц:

В модуле OrbitUnit добавляем эти переменные - Q, w и i. Для регулировки их значений добавляем на форму 3 скроллбара. Так же в модуле OrbitUnit добавляем процедуры RecountMatrix (считает матрицу поворота) и TranslatePos (преобразует координаты):

procedure TOrbit.RecountMatrix;

var M1,M2,M3,Hlp: array [1..3,1..3] of real;

q1,q2,q3: integer;

Begin

M1[1,1]:=cos(Q);

M1[2,1]:=-sin(Q);

M1[3,1]:=0;

M1[1,2]:=sin(Q);

M1[2,2]:=cos(Q);

M1[3,2]:=0;

M1[1,3]:=0;

M1[2,3]:=0;

M1[3,3]:=1;

M2[1,1]:=1;

M2[2,1]:=0;

M2[3,1]:=0;

M2[1,2]:=0;

M2[2,2]:=cos(i);

M2[3,2]:=sin(i);

M2[1,3]:=0;

M2[2,3]:=-sin(i);

M2[3,3]:=cos(i);

M3[1,1]:=cos(w);

M3[2,1]:=-sin(w);

M3[3,1]:=0;

M3[1,2]:=sin(w);

M3[2,2]:=cos(w);

M3[3,2]:=0;

M3[1,3]:=0;

M3[2,3]:=0;

M3[3,3]:=1;

for q1:=1 to 3 do

for q2:= 1 to 3 do

begin

Hlp[q1,q2]:=0;

for q3:= 1 to 3 do

Hlp[q1,q2]:=Hlp[q1,q2]+M1[q3,q2]*M2[q1,q3];

end;

for q1:=1 to 3 do

for q2:= 1 to 3 do

begin

TurnMatrix[q1,q2]:=0;

for q3:= 1 to 3 do

TurnMatrix[q1,q2]:=TurnMatrix[q1,q2]+Hlp[q3,q2]*M3[q1,q3];

end;

End;

procedure TOrbit.TranslatPos(var cord : TPoint3D);

var q1,q2: integer;

Hlp:TPoint3D;

Begin

for q1:= 1 to 3 do begin

Hlp[q1]:=0;

for q2 := 1 to 3 do

Hlp[q1]:=Hlp[q1]+Cord[q2]*TurnMatrix[q2,q1];

end;

for q1 := 1 to 3 do

Cord[q1]:=Hlp[q1];

End;

Для того, чтобы нарисовать проекцию орбиты на Землю, добавим после построения самой орбиты:

for q1:=0 to 360 do

Begin

Cord:=Orbit.GetPos(q1*pi/180);

a:=0.9*sqrt(sqr(Cord[1])+sqr(Cord[2])+sqr(Cord[3]));

glVertex3F(Cord[1]/a,Cord[2]/a,Cord[3]/a);

end;

Нам необходимо узнать истинную аномалию. Мы вычисляем её с помощью формул:

Данные формулы показывают зависимость истинной аномалии от эксцентрической.

Средняя аномалия — угловое расстояние от перицентра гипотетического тела движущегося с постоянной угловой скоростью, равной среднему движению.

Эксцентрическая аномалия (обозначается E) — параметр используемый для выражения переменной длины радиус-вектора. Средняя аномалия связана с эксцентрической уравнением Кеплера:

, где n – среднее движение.

Вычисляем точку пересечения графиков:

  1. Разбиваем интервал на 2 половины и вычисляем разность;

  2. Если Е-М<e-sin(E), то переходим вправо, а если наоборот, то переходим влево и снова повторяем шаг 1. Делаем это пока длина интервала не станет меньше, чем 1*10^(-10).

В методах класса добавляем функцию GetExAnomaly:

Function TOrbit.GetExAnomaly(BegAngle, EndAngle,LookingAnomaly:real):real;

Begin

while (LookingAnomaly<0) do

LookingAnomaly:=LookingAnomaly+2*pi;

while (LookingAnomaly>2*pi) do

LookingAnomaly:=LookingAnomaly-2*pi;

if(abs((BegAngle-E*sin(BegAngle))-LookingAnomaly)<ERROR_SIZE) then

GetExAnomaly:=BegAngle

else

begin

if(abs((EndAngle-E*sin(EndAngle))-LookingAnomaly)<ERROR_SIZE) then

GetExAnomaly:=EndAngle

else

begin

if((EndAngle+BegAngle)/2-e*sin((EndAngle+BegAngle)/2)<LookingAnomaly) then

GetExAnomaly:=GetExAnomaly((EndAngle+BegAngle)/2,EndAngle,LookingAnomaly) else

GetExAnomaly:=GetExAnomaly(BegAngle,(EndAngle+BegAngle)/2,LookingAnomaly);

end;

end;

end;

Добавляем ещё одну функцию, которая будет вычислять значение истинной аномалии по известному значению эксцентрической аномалии:

function TOrbit.GetU(EVal:real):real;

var u1,u2:real;

begin

U1:=ArcCos((cos(EVal)-e)/(1-e*cos(EVal)));

U2:=sin(EVal);

if(U2<0) then

GetU:=2*pi-u1 else

GetU:=U1;

end;

Моделируем вращение Земли и спутника. Зададем константу длительности звёздных суток, добавим таймер, который будет связан со скроллбаром, который будет задавать характеристику текущего времени – количество секунд, прошедших с начала запуска программы. Необходимо, чтобы в каждый момент времени Земля была повернута на определенный угол. CurrentTime=0 – «полночь».

function Torbit.GetEathAngle:real;

Begin

Result:=frac(CurrentTime/SEC_PER_DAY)*360;

end;

В код рисования Земли добавим переменную, отвечающую за угол поворота Земли и код, реализующий поворот:

Angle:=Orbit.GetEathAngle+180;

glRotate(Angle,0,0,1);

………………………...

glRotate(-Angle,0,0,1);

Для моделирования движения спутника нам понадобится знать период обращения спутника. Запишем в функцию RecountMatrix:

EARTH_MU = 3.98602E14;

..............................................

Period:=2*pi/sqrt(EARTH_MU/IntPower(p/(1-sqr(e)),3));

Добавим функцию поиска координат спутника по текущему времени:

function TOrbit.GetCurrentPos:TPoint3D;

var MVal:real;

begin

MVal:=frac(CurrentTime/Period)*2*pi;

Result:=GetPos(GetU(GetExAnomaly(0,2*pi,MVal)));

end;

Далее в модуле рисования в 3D добавим рисование радиус-вектора спутника:

glBegin(GL_LINES);

glVertex3f(0,0,0);

Cord:=Orbit.GetCurrentPos;

glVertex3f(Cord[1]/EARTH_RAD,Cord[2]/EARTH_RAD,Cord[3]/EARTH_RAD);

glEnd;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]