Бугреев ПЗ (1231492), страница 6
Текст из файла (страница 6)
Рисунок 2.22 – Объединение множеств направлений движения по стрелочному переводу
Поскольку теперь программа будет знать, как ориентирована стрелка в пространстве и какие возможные пути для движения существу-ют можно дополнить существующую модель элементами инфраст-руктуры. Например, теперь, оградив каждый стрелочный перевод изоли-рующими стыками, можно рядом с некоторыми из них, в соответствии с планом станции, установить светофор. При наличии светофора доста-точно просто определить участки приближения к ним и составить таб-лицу маршрутов передвижения по станции.
2.8 Реализация движения модели поезда по сплайну
Железнодорожный состав можно рассматривать как упорядочен-ный массив, который состоит из различных типов подвижных единиц. Подвижные единицы, в свою очередь, являются элементами массива, и могут быть как локомотивами, так и вагонами. Разница в моделях движе-ния этих элементов заключается в возможности или невозможности СА-мостоятельного ускорения, за счёт двигателя или его отсутствия. Равно-мерное движение по кривым участкам железнодорожного пути для локо-мотивов и вагонов одинаково. Принимая это условие, далее не будем разделять подвижные единицы по виду и конструктивному исполнению, и будем рассматривать алгоритмы, которые применимы к каждому их них.
Основой железнодорожного вагона является вагонная тележка. Она служит для опоры рамы вагона на колесные пары и отвечает за поворот вагона на кривых участках пути. Для реализации движения модели вагона по сплайнам необходимо, в первую очередь, реализо-вать движение вагонных тележек по кривым.
Так как для спрямления кривой применяется метод аппрок-симации векторами, то необходимо, что бы центры тележек двигались по полученным векторам. В программной среде разработки Borland Delphi 7 в качестве центров тележек используется компоненты Shape в виде окружности. Данные компоненты образуют одномерный массив Sh, состоящий из ста одного элемента. Движение компонентов осуществля-ется посредством изменения положения относительно осей X и Y по событию OnTimer компонента Timer6, которое возникает по истечению времени, указанного в свойствах данного компонента:
procedure TForm2.Timer6Timer(Sender: TObject);
begin
for ii:=0 to Kol do begin //1*
if (S[ii].L >0) then begin //2*
moveshapeto (ii,(strtoint(edit3.Text))); //3*
Sh[ii].Brush.Color:=clRed; //4*
if (Vec[(S[ii].NVec)].dx<0) then begin //5*
Sh[ii].Left:=Trunc(Vec[S[ii].NVec].X)- Sh[ii].width div 2-Trunc(S[ii].X);//6*
Sh[ii].top:=Trunc(Vec[S[ii].NVec].Y)- Sh[ii].width div 2-Trunc(S[ii].Y);
end;
if (Vec[(S[ii].NVec)].dx>=0) then begin //7*
Sh[ii].Left:=Trunc(Vec[S[ii].NVec].X)- Sh[ii].width div 2+Trunc(S[ii].X); //8*
Sh[ii].top:=Trunc(Vec[S[ii].NVec].Y)- Sh[ii].width div 2+Trunc(S[ii].Y);
end;
if (s[0].l <0) and (Vec[S[ii].NVec].Next=0) then begin //9*
timer6.Enabled:=false; //10*
end;
end;
end;
end;
//1*Для счетчика ii от 1 до kol (количество векторов),
//2*если длина вектора > 0, то…
//3*выполняем процедуру moveshapeto.
//4*Окрашиваем точку в красный цвет.
//5*Если начало вектора лежит левее его конца, то…
//6*смещаем точку в одну сторону.
//7* Если начало вектора лежит правее его конца, то…
//8* смещаем точку в противоположную сторону.
//9*Если первая точка достигла конца сплайна,то…
//10*останавливаем таймер.
procedure moveshapeto (Shp:integer;delta:real);
var dx,dy:real;
begin
dx:=delta*cos(Vec[S[Shp].NVec].f); //1*
dy:=delta*sin(Vec[S[Shp].NVec].f); //2*
S[Shp].L:=S[Shp].L-delta; //3*
S[Shp].X:=S[Shp].X+dx; //4*
S[Shp].Y:=S[Shp].Y+dy; //5*
end;
//1*Вычисление смещения точки по оси X.
//2*Вычисление смещения точки по оси Y.
//3*Уменьшение длины вектора на величину delta.
//4*Увеличение переменной S[Shp].X на величину dx.
//5*Увеличение переменной S[Shp].Y на величину dy.
Для того, что бы больше визуализировать движение поезда, необходимо, что бы вместе с тележками двигался и корпус вагона. Примитивно его можно представить в виде неизменяющегося во време-ни прямоугольника. Его необходимо жестко связать с точкой, которая будет представлять собой центр вагона. Она, в отличие от точек тележек, не будет постоянно двигаться по оси пути, в частности при повороте поезда на кривых участках. Подобное явление показано на рисунке 2.23, где светлыми точками являются центры вагонных тележек, темными точками являются центры вагонов, заштрихованными точками показаны опорные точки сплайна.
Рисунок 2.23 – Движение центров тележек (1, 3, 5) и центров
вагонов (2, 4) по сплайну
Для того, что бы реализовать в дальнейшем визуализацию движения в 3D, необходимо, что бы все данные о положении подвижных единиц хранились в некотором массиве, значение которого затем импор-тировались бы в базу данных. Для этого создадим массив записей: Vagon: array [0..100] of TVagon. Тип TVagon описывается, как :
TVagon = record Pos:TPoint; //1*
ygol:real; //2*
PerT,ZadT:TPoint; //3*
Vector:TDat; //4*
end;
//1*Координаты центра вагона.
//2*Угол поворота вагона.
//3*Координаты передней и задней вагонных тележек.
//4*Данные о векторе, на котором расположен вагон.
Занесение данных в массив Vagon, происходит во время движения модели по сплайну по событию OnTimer компонента Timer6.
If (ii>0) then begin
vagon[ii].PerT.X:=Sh[ii-1].left+Sh[ii].width div 2;
vagon[ii].PerT.Y:=Sh[ii-1].Top+Sh[ii].width div 2;
vagon[ii].ZadT.X:=Sh[ii].left+Sh[ii].width div 2;
vagon[ii].ZadT.Y:=Sh[ii].Top+Sh[ii].width div 2;
vagon[ii].Vector:=PromDat[S[ii].NVec];
a:=Vagon[ii].ZadT.X-Vagon[ii].PerT.X; b:=Vagon[ii].ZadT.Y-Vagon[ii].PerT.Y;
vagon[ii].Pos.X:=Vagon[ii].ZadT.X-trunc(a/2)-(Sh[ii].width div 2);
vagon[ii].Pos.Y:=Vagon[ii].ZadT.Y-trunc(b/2)-(Sh[ii].width div 2);
Sh[P+ii].Left:=Vagon[ii].Pos.X; Sh[P+ii].Top:=Vagon[ii].Pos.Y; //1*
if a>0 then
if (b>0) and (a>0) then Vagon[ii].ygol:=arctan(b/a);
if (b<0) and (a>0) then Vagon[ii].ygol:=-3.14-arctan(b/a)
else if b>0 then Vagon[ii].ygol:=1.57-arctan(a/b)
else if b<0 then Vagon[ii].ygol:=-1.57-arctan(a/b)
else if a=0 then
if b>0 then Vagon[ii].ygol:=1.57 else Vagon[ii].ygol:=-1.57
else if b=0 then
if a>0 then Vagon[ii].ygol:=3.14 else Vagon[ii].ygol:=0;
end;
//1*Осуществление движения центра вагона по сплайну.
Импорт данных из массива записей Vagon в таблицу VAGON базы данных происходит сразу же, после определения их в массив записей по генерации события OnTimer компонента Timer6.
DS3.Insert;
Ds3.FBN('PER_T_X').AsInteger:=Vagon[ii].PerT.X;
Ds3.FBN('PER_T_Y').AsInteger:=Vagon[ii].PerT.Y;
Ds3.FBN('ZAD_T_X').AsInteger:=Vagon[ii].ZadT.X;
Ds3.FBN('ZAD_T_Y').AsInteger:=Vagon[ii].ZadT.Y;
Ds3.FBN('VECTOR').AsInteger:=S[ii].Nvec;
Ds3.FBN('VAG_C_X').AsInteger:=Vagon[ii].Pos.X;
Ds3.FBN('VAG_C_Y').AsInteger:=Vagon[ii].Pos.Y;
Ds3.FBN('YGOL').AsFloat:=Vagon[ii].ygol;
Ds3.Post;
end;
Здесь в качестве связевого ключа между базой данных и массивом записей выступает компонент DS3(DataSet3). Сокращение FBN означает метод FieldByName компонента DataSet, который позволяет устанавливать указатель на поле в таблице базы данных, указывая непосредственно его имя.
Реализация движения корпуса вагона представляет собой изменение по отсчётам времени положение прямоугольника в соответствии с положением точки центра вагона, жестко закрепив их «центр к центру». Однако этого недостаточно, ввиду того, что в реаль-ности из-за жесткого соединения вагонных тележек с рамой вагона, корпус поворачивается вокруг своего центра на определенный угол. Поэтому задача движения корпуса вагона сводится к реализации его поворота вокруг своего центра в сочетании с изменением его положения. Координаты и углы наклона составных частей вагона показаны на рисунке 2.24.
Рисунок 2.24 – Координаты и углы наклона составных частей вагона
Угол поворота корпуса вагона можно получить путем вычитания углов наклона опорных векторов. В соответствии с рисунком 2.24 углами наклона опорных векторов являются: для передней тележки угол Vec[i+1].F, для задней тележки угол Vec[i].F. Тогда угол поворота корпуса вагона будет определяться разницей данных углов. Для плавности движения и упрощения расчетов в программе расчет углов поворота корпуса вагона производится исходя из угла наклона горизонтальной оси корпуса к оси X.
Для более наглядного представления в программе точки, обозна-чающие центры вагонных тележек, а так же точки, обозначающие места механизмов автосцепки и центры корпусов вагонов, заменены на изоб-ражения соответствующих элементов. Таким образом, движение модели приобретает более реальный вид.
Рисунок 2.25 – Замена расчетных точек на изображения
2.9 Применение методов обработки параллельных процессов
В рассматриваемом выше алгоритме движения поезда вычисле-ния координат всех точек, а так же вычисление всех углов производится в порядке очереди, т.е последовательно. Благодаря высокой частоте работы процессоров современных компьютеров расчет и перемещение подвижных единиц происходит с большой скоростью и для человечес-кого глаза создается эффект непрерывного движения.
Эта модель хорошо работает с небольшим количеством элементов, представляющих собой части подвижного состава. При значительном увеличении количества вагонов при движении значитель-но увеличивается количество расчетных точек, необходимых для реали-зации движения, вместе с тем возрастает и очередь их просчета. Это порождает высокую вычислительную нагрузку и влечет за собой исчезновение эффекта непрерывного движения подвижных единиц.
Решить данную проблему предлагается внедрением технологий параллельной обработки потоков данных. В качестве потока будет определяться набор точек и углов, для осуществления движения одного вагона. Взаимодействие процессора компьютера с потоками будет происходить через разделяемые участки оперативной памяти. Каждому из потоков будет назначаться своя часть памяти, а процессор будет обрабатывать данные участки одновременно. Это позволит организо-вать независимую от числа движущихся элементов непрерывность дви-жения каждого из них. Число же допустимых движущихся подвижных единиц будет определяться размером установленной в компьютере оперативной памяти.
2.10 Графические движки и их применение
2.10.1 Библиотеки GLScene и ODE
На сегодняшний день возможности вычислительных машин, по быстроте выполнения различных операций, на порядок выше возможностей человеческого мозга. Темпы увеличения этих возмож-ностей огромны. Нельзя не заметить, что с увеличением производи-тельности компьютеров возрастает и их графические возможности. Сей-час уже никого не удивишь разрешением мониторов 4к и просмотром фильмов снятых по технологии 3D. Воссозданные программным путем модели различных объектов реального мира вызывают восторг. Одним словом компьютерная графика все больше и больше стала походить на ту, что человек видит ежедневно вокруг себя.
Зная устройство и принцип работы современных графических процессоров, программист может визуализировать любой объект или процесс реальной жизни на экран монитора. Однако работать с машинным кодом, временными диаграммами тактов процессора довольно трудно и долго по времени. Поэтому большинство компьютер-ных программ, так или иначе работающих с графикой, создаются с помощью дополнительных программ, библиотек, движков и пр., значи-тельно экономя время программиста и помогая ему.
Что бы реализовать модель движения поезда в трехмерном пространстве в программной среде Borland Dephi 7 можно прибегнуть к использованию различных библиотек и движков. Главными задачами, в данном случае, являются: обеспечение контакта модели поезда с поверхностью, которая определяется верхним строением железно-дорожного пути (с учетом профиля); учет коллизионных процессов.
Железнодорожный путь в трехмерной визуализации представлен не только планом пути, но и профилем. Необходимо учитывать как уклоны пути, так и его изгибы, что бы модель поезда двигалась адекватно. Учёт коллизионных процессов необходим для обеспечения реалистичного поведения локомотивов и вагонов, при их сцепке, расце-пке, соударении.
Представленные задачи могут помочь решить такие программные интерфейсы как OpenGL, ODE и Direct3D.
OpenGL - спецификация, определяющая независимый от языка программирования платформонезависимый программный интерфейс для написания приложений, использующих двумерную и трёхмерную компьютерную графику. Данный интерфейс является спецификацией, т.е набором функций и их точное поведение. Значи-тельной особенностью библиотеки OpenGL является её простота и доступность. У данной библиотеки есть ядро, которое управляет обра-боткой неких треугольников (примитивов). Процедурная модель лежит в основе передачи данных, а в работе вызываются функции. OpenGL имеет состояние, связанное со значениями переменных, которые и указывают, какие параметры обработки должны работать в каждый мо-мент времени. Например, определяется, нужно ли сейчас рисовать текстуру или нет. И в соответствии с текущим состоянием совершается обработка переданных примитивов. В итоге получается простой код и достаточно эффективный механизм работы OpenGL.
GLScene - Графическая библиотека на базе OpenGL для Delphi. Данная библиотека бесплатна, с открытым исходным кодом. Библиотека непрерывно развивается, адаптируясь под современные технологии 3D графики.
GLScene является не просто оберткой OpenGL-функций для Delphi, обилие и разнообразие возможностей позволяет назвать ее полноценным 3D-движком. Помимо графических классов и компонентов, библиотека предоставляет средства для работы со звуком, вводом-выводом, игровой логикой, и даже физикой (используется физическая библиотека ODE)[4].
Высокоуровневая структура GLScene позволяет новичкам в мире программирования создавать игры, не зная ни одной OpenGL-команды. В то же время, профессионалам открываются все возможности для использования чистого OpenGL, где это необходимо, модифицирования исходных кодов под себя и создания профессиональных приложений.
Direct3D – компонент интерфейса программирования приложений. Direct3D обеспечивает функции для взаимодействия операционной системы и приложений с драйверами видеокарты. В отличии от библио-теки OpenGL имеет основу на модели COM. Модель COM предполагает не простые вызовы функций, а определенные действия, которые связаны непосредственно с архитектурой библиотеки Direct3D. Вызовы Direct3D используются внутри кода, который не отличается легким пони-манием. И причем, для того, чтобы нарисовать обычный треугольник, используется очень большой объем кода. Так же отличие заключается в закрытом доступе к исходному коду, тем самым определяя вектор развития библиотеки лишь программистами компании Microsoft.
ODE - Открытый динамический движок (Open Dynamics Engine, или ODE) это бесплатная библиотека промышленного качества, предназначенная для симуляции динамики составных жестких тел. Например, она хорошо подходит для транспортных средств и движущих-ся объектов в виртуальном пространстве. Она быстра, гибка и проста, имеет встроенное определение столкновений (коллизионный аппарат). Библиотека ODE разработана для интерактивной симуляции или симуляции в реальном времени. Хорошо подходит для симуляции пове-дения движущихся объектов в изменяемом окружении виртуальной реальности. Поскольку ODE быстра, проста в использовании и стабильна, пользователь имеет полную свободу в изменении структуры системы даже во время симуляции.
Учитывая все достоинства и недостатки представленных интерфейсов, а так же беря во внимания те задачи, которые необходимо с их помощью решить, можно сделать вывод: использовать библиотеку GLScene для создания реалистичного движения модели поезда, а для учета коллизий и сочленения составных частей подвижных единиц при-менять библиотеку ODE.















