Применение средств графического отображения для организации непрерывного движения поездов с непрерывным переключением светофора по кольцевой железной дороге, страница 4

 bool, tbool: boolean ;

begin

 bool:= false ;

 tbool:= false ;

{Перед каким светофором происходит добавление}

 fSvetofor:= OpredSvetofor(fa) ;

{Определение переменных для дальнейшей реализации}

afirst:= fa ;

 atp:= fa + aVTrain ;

 fa:= fa - aVTrain ;

 if atp > pi2 then

  atp:= atp - pi2 ;

 if fa < 0 then

  fa:= pi2 + fa ;

{Если происходит добавление первого светофора}

 if fSvetofor = nil then

 begin

  fNewSvetofor:= TSvetofor.Create(nil, nil, afirst, -1, main.Image1.Canvas, main.LBSvetofor; main.StatusBar1.Panels[2]) ;

{Заполнение у созданного светофора полей с предыдущем и следующем светофором}

  fNewSvetofor.NextSvetofor:= fNewSvetofor ;

  fNewSvetofor.BackSvetofor:= fNewSvetofor ;

{Запись адреса первого светофора по окружности(самый близкий к углу в нуль радиан)}

  FirstSvetofor:= fNewSvetofor ;

  bool:= true ;

 end

  else

{Определяется возможность добавление, потому  что может оказаться, что новый светофор будет находиться слишком близко к соседним}

{Если добавление нового светофора происходит на первом участке}

   if (((fSvetofor = FirstSvetofor) and (((fa < fSvetofor.aPosit) and ((fSvetofor.aPosit - fa) > aVMinSV_SV) and ((pi2 - fSvetofor.BackSvetofor.aPosit + fa) > aVMinSV_SV)) or

                                       ((fa > fSvetofor.aPosit) and ((pi2 - fa + fSvetofor.aPosit) > aVMinSV_SV) and ((fa - fSvetofor.BackSvetofor.aPosit) > aVMinSV_SV)))) or

{Если добавление нового светофора происходит не на первом участке}

      ((fSvetofor <> FirstSvetofor) and ((fSvetofor.aPosit - fa) > aVMinSV_SV) and ((fa - fSvetofor.BackSvetofor.aPosit) > aVMinSV_SV)))  then

   begin

    fNewSvetofor:= TSvetofor.Create(fSvetofor,fSvetofor.BackSvetofor,afirst, -1, main.Image1.Canvas, main.LBSvetofor; main.StatusBar1.Panels[2])) ;

    bool:= true ;

    fSvetofor.BackSvetofor.NextSvetofor:= fNewSvetofor ;

    fSvetofor.BackSvetofor:= fNewSvetofor ;

    {Нужно ли забрать поезд, стоящий перед светофором к себе}

    if fSvetofor.Train <> nil then

     if (fSvetofor <> FirstSvetofor) and (atp >= fSvetofor.Train.aPosit) then

     begin

      tbool:= true ;

      if (atp - fSvetofor.Train.aPosit) <= 2*aVTrain then

       fSvetofor.Train.PeremBool:= true ;

     end

      else

       if (fSvetofor = FirstSvetofor) and (((atp < fSvetofor.aPositPerem) and ((fSvetofor.Train.aPosit >= fSvetofor.aPositPerem) or (fSvetofor.Train.aPosit < atp))) or

                                           ((atp >= fSvetofor.aPositPerem) and (fSvetofor.Train.aPosit < atp) and (fSvetofor.Train.aPosit >= fSvetofor.aPositPerem))) then

       begin

        tbool:= true ;

       end ;

    {Забираем поезд на новый участок}

    if tbool then

    begin

if ((atp > fSvetofor.Train.aPosit) and ((atp - fSvetofor.Train.aPosit) <= 2*aVTrain)) or

           ((atp < fSvetofor.Train.aPosit) and ((atp + pi2 - fSvetofor.Train.aPosit) <= 2*aVTrain)) then

      fSvetofor.Train.PeremBool:= true ;

     fNewSvetofor.Train:= fSvetofor.Train ;

     fNewSvetofor.Train.Svetofor:= fNewSvetofor ;

     fSvetofor.Train:= nil ;

    end ;

    if (fSvetofor = FirstSvetofor) and (fa < FirstSvetofor.aPosit) then

     FirstSvetofor:= fNewSvetofor ;

   end ;

{Действия по добавлению нового светофора}

 if bool then

 begin

  inc(CountSvetofor) ;

{Визуальное изменение кол-во светофоров в StatusBar1}

  fNewSvetofor.Panel.Text:= ' Кол-во светофоров: ' + IntToStr(CountSvetofor) ;

  PereschetSvetofor ;

{Добавление в ListObjectSvetofor(класс TListBox) светофора}

  fNewSvetofor.ListBox.Items.Addobject(Светофор № ' + IntToStr(fNewSvetofor.Index), fNewSvetofor) ;

  result:= true ;

 end

  else

   result:= false ;

end ;

*  Добавлениепоезда:

Добавление поезда происходит в два этапа:

1.  Метод function AddTrainBool возвращает true, если возможно добавление поезда.

function AddTrainBool(fa: real): boolean ;

var

 fSvetofor: TSvetofor ;

 tbool: boolean ;

begin

 tbool:= true ;

{На какой участок добавляем поезд}

 fSvetofor:= OpredSvetofor(fa) ;

{Если на заднем участке есть поезд, то проверяется не пересек ли он начальный угол светофора(fSvetofor.BackSvetofor.aPositPerem)}

 if fSvetofor <> nil then

  if fSvetofor.BackSvetofor.Train <> nil then

   if fSvetofor.BackSvetofor.Train.PeremBool then

    tbool:= false ;

{Проверяется возможность добавления поезда}

 if fSvetofor <> nil then

 begin

  if (fSvetofor.Train = nil) and tbool then

   result:= true

   else

    result:= false ;

 end

  else

   result:= false ;  

end ;

2.  Метод procedure AddTrain добавляет поезд.

procedure AddTrain(fa: real; fSpeed: Byte ; fTrColor: TColor) ;

var

 i: integer ;

 fTrain, fNewTrain: TTrain ;

 fSvetofor: TSvetofor ;

begin

{На какой участок добавляем поезд}

 fSvetofor:= OpredSvetofor(fa) ;

{Если происходит добавление первого поезда}

 if FirstTrain = nil then

 begin

fNewTrain:= TTrain.Create(fSvetofor,nil,nil,fSpeed,fa,fTrColor, -1, main.Image1.Canvas, main.LBTrain, main.StatusBar1.Panels[3]);

{Задание ссылок следующего и предыдущего поезда в соответствующие для этого поля }

  fNewTrain.NextTrain:= fNewTrain ;

  fNewTrain.BackTrain:= fNewTrain ;

  FirstTrain:= fNewTrain ;

 end

  else

  begin

   fNewTrain:= TTrain.Create(fSvetofor,FirstTrain,FirstTrain.BackTrain,fSpeed,fa,fTrColor, -1, main.Image1.Canvas, main.LBTrain, main.StatusBar1.Panels[3]) ;

{Если происходит добавление второго по счету поезда}

   if CountTrain = 1 then

   begin