Changeset 27 for trunk


Ignore:
Timestamp:
Apr 12, 2015, 1:11:27 PM (10 years ago)
Author:
chronos
Message:
  • Modified: Train position is now relative to nearest down point. Thanks to that trains is not repositioned if line is connected or disconnected to other stations.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/UEngine.pas

    r26 r27  
    6464    Line: TMetroLine;
    6565    LineStation: TLineStation;
    66     Point: TPoint;
    67     PointShift: TPoint;
    68     DesignedPoint: TPoint;
     66    Position: TPoint;
     67    PositionShift: TPoint;
     68    PositionDesigned: TPoint;
    6969    Pending: Boolean;
    7070    function GetDown: TTrackPoint;
    7171    function GetUp: TTrackPoint;
     72    function GetNeighDown: TTrackPoint;
     73    function GetNeighUp: TTrackPoint;
     74    // Move to TTrackLink later
     75    function GetDistance: Integer;
    7276  end;
    7377
     
    118122    TrackPoints: TTrackPoints;
    119123    procedure ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation);
    120     procedure DisconnectStation(LineStation: TLineStation);
     124    procedure DisconnectStation(ALineStation: TLineStation);
    121125    procedure RouteTrack(TP1, TP2: TTrackPoint);
    122     procedure RemoteTrackBetween(TP1, TP2: TTrackPoint);
     126    procedure RemoveTrackBetween(TP1, TP2: TTrackPoint);
    123127    function GetTrackLength: Integer;
    124     function GetStationTrackPos(LineStation: TLineStation): Integer;
    125128    constructor Create;
    126129    destructor Destroy; override;
     
    141144  private
    142145    LastPosDelta: Integer;
     146    LastTrainMoveTime: TDateTime;
     147    StationStopTime: TDateTime;
    143148  public
    144149    Passengers: TMetroPassengers;
    145150    Line: TMetroLine;
    146     TrackPos: Integer;
    147     //Angle: Double;
     151    BaseTrackPoint: TTrackPoint;
     152    RelPos: Double;
    148153    Direction: Integer;
    149154    InStation: Boolean;
    150     StationStopTime: TDateTime;
    151     LastTrainMoveTime: TDateTime;
    152155    TargetStation: TLineStation;
     156    function GetTargetStationDistance: Integer;
    153157    function GetPosition: TPoint;
    154158    function GetAngle: Double;
     
    185189  TView = class
    186190    Size: TPoint;
     191    Zoom: Double;
    187192  end;
    188193
     
    332337function TTrackPoint.GetDown: TTrackPoint;
    333338var
     339  I: Integer;
     340begin
     341  I := Line.TrackPoints.IndexOf(Self) - 1;
     342  while (I >= 0) and not Assigned(TTrackPoint(Line.TrackPoints[I]).LineStation) do
     343    Dec(I);
     344  if I >= 0 then Result := TTrackPoint(Line.TrackPoints[I])
     345    else Result := nil;
     346end;
     347
     348function TTrackPoint.GetUp: TTrackPoint;
     349var
     350  I: Integer;
     351begin
     352  I := Line.TrackPoints.IndexOf(Self) + 1;
     353  while (I < Line.TrackPoints.Count) and not Assigned(TTrackPoint(Line.TrackPoints[I]).LineStation) do
     354    Inc(I);
     355  if I < Line.TrackPoints.Count then Result := TTrackPoint(Line.TrackPoints[I])
     356    else Result := nil;
     357end;
     358
     359function TTrackPoint.GetNeighDown: TTrackPoint;
     360var
    334361  NewIndex: Integer;
    335362begin
    336   NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) - 1;
    337   if NewIndex >= 0 then Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint
     363  NewIndex := Line.TrackPoints.IndexOf(Self) - 1;
     364  if NewIndex >= 0 then Result := TTrackPoint(Line.TrackPoints[NewIndex])
    338365    else Result := nil;
    339366end;
    340367
    341 function TTrackPoint.GetUp: TTrackPoint;
     368function TTrackPoint.GetNeighUp: TTrackPoint;
    342369var
    343370  NewIndex: Integer;
    344371begin
    345   NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) + 1;
    346   if NewIndex < LineStation.Line.LineStations.Count then
    347     Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint
     372  NewIndex := Line.TrackPoints.IndexOf(Self) + 1;
     373  if NewIndex < Line.TrackPoints.Count then Result := TTrackPoint(Line.TrackPoints[NewIndex])
    348374    else Result := nil;
     375end;
     376
     377function TTrackPoint.GetDistance: Integer;
     378var
     379  Index: Integer;
     380begin
     381  Index := Line.TrackPoints.IndexOf(Self);
     382  Result := Distance(TTrackPoint(Line.TrackPoints[Index + 1]).Position,
     383    TTrackPoint(Line.TrackPoints[Index]).Position);
    349384end;
    350385
     
    478513    end;
    479514
    480     Angle := arctan2((TTrackPoint(TrackPoints[2]).Point.Y - TTrackPoint(TrackPoints[1]).Point.Y),
    481       (TTrackPoint(TrackPoints[2]).Point.X - TTrackPoint(TrackPoints[1]).Point.X));
    482     EndPoint := Point(Round(TTrackPoint(TrackPoints[1]).Point.X - EndStationLength * Cos(Angle)),
    483       Round(TTrackPoint(TrackPoints[1]).Point.Y - EndStationLength * Sin(Angle)));
    484     TTrackPoint(TrackPoints.First).Point := EndPoint;
    485     TTrackPoint(TrackPoints.First).DesignedPoint := EndPoint;
    486 
    487     Angle := arctan2((TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.Y),
    488       (TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.X));
    489     EndPoint := Point(Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X + EndStationLength * Cos(Angle)),
    490       Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y + EndStationLength * Sin(Angle)));
    491     TTrackPoint(TrackPoints.Last).Point := EndPoint;
    492     TTrackPoint(TrackPoints.Last).DesignedPoint := EndPoint;
     515    Angle := arctan2((TTrackPoint(TrackPoints[2]).Position.Y - TTrackPoint(TrackPoints[1]).Position.Y),
     516      (TTrackPoint(TrackPoints[2]).Position.X - TTrackPoint(TrackPoints[1]).Position.X));
     517    EndPoint := Point(Round(TTrackPoint(TrackPoints[1]).Position.X - EndStationLength * Cos(Angle)),
     518      Round(TTrackPoint(TrackPoints[1]).Position.Y - EndStationLength * Sin(Angle)));
     519    TTrackPoint(TrackPoints.First).Position := EndPoint;
     520    TTrackPoint(TrackPoints.First).PositionDesigned := EndPoint;
     521
     522    Angle := arctan2((TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Position.Y - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Position.Y),
     523      (TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Position.X - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Position.X));
     524    EndPoint := Point(Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Position.X + EndStationLength * Cos(Angle)),
     525      Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Position.Y + EndStationLength * Sin(Angle)));
     526    TTrackPoint(TrackPoints.Last).Position := EndPoint;
     527    TTrackPoint(TrackPoints.Last).PositionDesigned := EndPoint;
    493528  end;
    494529end;
     
    516551  NewTrackPoint := TTrackPoint.Create;
    517552  NewTrackPoint.LineStation := NewLineStation;
    518   NewTrackPoint.Point := Station.Position;
    519   NewTrackPoint.DesignedPoint := NewTrackPoint.Point;
     553  NewTrackPoint.Position := Station.Position;
     554  NewTrackPoint.PositionDesigned := NewTrackPoint.Position;
    520555  NewTrackPoint.Line := TrackPoints.Line;
    521556  Index := 0;
     
    536571      Train.Line := Self;
    537572      Train.TargetStation := TLineStation(LineStations[0]);
     573      Train.BaseTrackPoint := TTrackPoint(TrackPoints.First);
    538574      Trains.Add(Train);
    539575    end;
     
    544580end;
    545581
    546 procedure TMetroLine.DisconnectStation(LineStation: TLineStation);
    547 var
    548   I: Integer;
     582procedure TMetroLine.DisconnectStation(ALineStation: TLineStation);
     583var
     584  I: Integer;
     585  J: Integer;
    549586  Index: Integer;
    550 begin
     587  TP1, TP2: TTrackPoint;
     588  IsOnTrack: Boolean;
     589begin
     590  // Determine track point range to be removed
     591  TP1 := ALineStation.TrackPoint.GetDown;
     592  if not Assigned(TP1) then TP1 := TTrackPoint(TrackPoints.First);
     593  TP2 := ALineStation.TrackPoint.GetUp;
     594  if not Assigned(TP2) then TP2 := TTrackPoint(TrackPoints.Last);
     595
     596  // Remove track points from trains
     597  for I := 0 to Trains.Count - 1 do
     598  with TMetroTrain(Trains[I]) do begin
     599    IsOnTrack := False;
     600    for J := TrackPoints.IndexOf(TP1) to TrackPoints.IndexOf(TP2) do
     601    if TTrackPoint(TrackPoints[J]) = BaseTrackPoint then begin
     602      IsOnTrack := True;
     603      Break;
     604    end;
     605    if IsOnTrack then begin
     606      if Assigned(BaseTrackPoint) and Assigned(BaseTrackPoint.GetUp) and (BaseTrackPoint.GetUp <> ALineStation.TrackPoint) then
     607        BaseTrackPoint := BaseTrackPoint.GetUp
     608      else
     609      if Assigned(BaseTrackPoint) and Assigned(BaseTrackPoint.GetDown) and (BaseTrackPoint.GetDown <> ALineStation.TrackPoint) then
     610        BaseTrackPoint := BaseTrackPoint.GetDown
     611      else BaseTrackPoint := nil;
     612    end;
     613  end;
     614
    551615  // Delete old trackpoints
    552 
    553   Index := TrackPoints.IndexOf(LineStation.TrackPoint) - 1;
     616  Index := TrackPoints.IndexOf(ALineStation.TrackPoint) - 1;
    554617  while (Index >= 0) and (not Assigned(TTrackPoint(TrackPoints[Index]).LineStation)) do begin
    555618    TrackPoints.Delete(Index);
     
    561624    TrackPoints.Delete(Index);
    562625
    563   LineStation.MapStation.Lines.Remove(Self);
    564   Index := LineStations.IndexOf(LineStation);
    565 
    566   // Remove station from trains
     626  if ((Index - 1) >= 0) and (Index < TrackPoints.Count) then
     627    RouteTrack(TTrackPoint(TrackPoints[Index - 1]), TTrackPoint(TrackPoints[Index]));
     628
     629  ALineStation.MapStation.Lines.Remove(Self);
     630  Index := LineStations.IndexOf(ALineStation);
     631
    567632  for I := 0 to Trains.Count - 1 do
    568   with TMetroTrain(Trains[I]) do
    569   if TargetStation = LineStation then
    570     TargetStation := TLineStation(LineStations[(Index + 1) mod LineStations.Count]);
     633  with TMetroTrain(Trains[I]) do begin
     634    if TargetStation = ALineStation then
     635      TargetStation := TLineStation(LineStations[(Index + 1) mod LineStations.Count]);
     636  end;
    571637
    572638  LineStations.Delete(Index);
    573639
    574   // Remove trains if less then two stations
     640  // Remove all trains if less then two stations
    575641  if LineStations.Count < 2 then
    576642  for I := Trains.Count - 1 downto 0 do begin
     
    590656  Index1, Index2: Integer;
    591657begin
    592   RemoteTrackBetween(TP1, TP2);
     658  RemoveTrackBetween(TP1, TP2);
    593659  Index1 := TrackPoints.IndexOf(TP1);
    594660  Index2 := TrackPoints.IndexOf(TP2);
    595   P1 := TTrackPoint(TrackPoints[Index1]).Point;
    596   P2 := TTrackPoint(TrackPoints[Index2]).Point;
     661  P1 := TTrackPoint(TrackPoints[Index1]).Position;
     662  P2 := TTrackPoint(TrackPoints[Index2]).Position;
    597663  NewTrackPoint := TTrackPoint.Create;
    598664  NewTrackPoint.Line := Self;
    599665  Delta := Point(P2.X - P1.X, P2.Y - P1.Y);
    600666  if Abs(Delta.X) > Abs(Delta.Y) then begin
    601     NewTrackPoint.Point := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y);
    602     NewTrackPoint.DesignedPoint := NewTrackPoint.Point;
     667    NewTrackPoint.Position := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y);
     668    NewTrackPoint.PositionDesigned := NewTrackPoint.Position;
    603669  end else begin
    604     NewTrackPoint.Point := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X));
    605     NewTrackPoint.DesignedPoint := NewTrackPoint.Point;
     670    NewTrackPoint.Position := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X));
     671    NewTrackPoint.PositionDesigned := NewTrackPoint.Position;
    606672  end;
    607673  TrackPoints.Insert(Index1 + 1, NewTrackPoint);
    608674end;
    609675
    610 procedure TMetroLine.RemoteTrackBetween(TP1, TP2: TTrackPoint);
     676procedure TMetroLine.RemoveTrackBetween(TP1, TP2: TTrackPoint);
    611677var
    612678  Index1, Index2: Integer;
     
    636702  for I := 0 to TrackPoints.Count - 1 do
    637703  if I > 0 then
    638     Result := Result + Distance(TTrackPoint(TrackPoints[I]).Point, TTrackPoint(TrackPoints[I - 1]).Point);
    639 end;
    640 
    641 function TMetroLine.GetStationTrackPos(LineStation: TLineStation): Integer;
    642 var
    643   I: Integer;
    644 begin
    645   Result := 0;
    646   for I := 0 to TrackPoints.Count - 1 do begin
    647     if I > 0 then
    648       Result := Result + Distance(TTrackPoint(TrackPoints[I]).Point, TTrackPoint(TrackPoints[I - 1]).Point);
    649     if TTrackPoint(TrackPoints[I]).LineStation = LineStation then Break;
    650   end;
     704    Result := Result + Distance(TTrackPoint(TrackPoints[I]).Position, TTrackPoint(TrackPoints[I - 1]).Position);
    651705end;
    652706
     
    678732{ TMetroTrain }
    679733
     734function TMetroTrain.GetTargetStationDistance: Integer;
     735var
     736  Current: Integer;
     737  Target: Integer;
     738  I: Integer;
     739begin
     740  Result := 0;
     741  if Assigned(BaseTrackPoint) and Assigned(TargetStation) then begin
     742  Current := Line.TrackPoints.IndexOf(BaseTrackPoint);
     743  Target := Line.TrackPoints.IndexOf(TargetStation.TrackPoint);
     744  if Current < Target then begin
     745    for I := Current to Target - 1 do
     746      Result := Result + TTrackPoint(Line.TrackPoints[I]).GetDistance;
     747    Result := Result - Trunc(RelPos);
     748  end else
     749  if Current > Target then begin
     750    for I := Current - 1 downto Target do
     751      Result := Result + TTrackPoint(Line.TrackPoints[I]).GetDistance;
     752    Result := Result + Trunc(RelPos);
     753  end else Result := Trunc(RelPos);
     754  end;
     755end;
     756
    680757function TMetroTrain.GetPosition: TPoint;
    681758var
    682   I: Integer;
    683   R: TPoint;
    684759  D: Integer;
    685   Sum: Integer;
     760  Delta: TPoint;
     761  UpPoint: TTrackPoint;
    686762begin
    687763  Result := Point(0, 0);
    688   if Assigned(Line) then
    689   with Line do begin
    690     Sum := 0;
    691     if TrackPoints.Count > 1 then
    692     for I := 1 to TrackPoints.Count - 1 do begin
    693       D := Distance(TTrackPoint(TrackPoints[I]).Point, TTrackPoint(TrackPoints[I - 1]).Point);
    694       if (Sum + D) > Self.TrackPos then begin
    695         R := Point(TTrackPoint(TrackPoints[I]).Point.X - TTrackPoint(TrackPoints[I - 1]).Point.X,
    696           TTrackPoint(TrackPoints[I]).Point.Y - TTrackPoint(TrackPoints[I - 1]).Point.Y);
    697         Result := Point(Trunc(TTrackPoint(TrackPoints[I - 1]).Point.X + R.X * (TrackPos - Sum) / D),
    698           Trunc(TTrackPoint(TrackPoints[I - 1]).Point.Y + R.Y * (TrackPos - Sum) / D));
    699         Exit;
    700       end else Sum := Sum + D;
    701     end;
    702     if TrackPoints.Count > 0 then
    703       Result := TTrackPoint(TrackPoints.Last).Point;
     764  if Assigned(BaseTrackPoint) then
     765  with BaseTrackPoint do begin
     766    UpPoint := BaseTrackPoint.GetNeighUp;
     767    if Assigned(UpPoint) then begin
     768      D := Distance(UpPoint.Position, Position);
     769      if D > 0 then begin
     770        Delta := SubPoint(UpPoint.Position, Position);
     771        Result := Point(Trunc(Position.X + Delta.X * RelPos / D),
     772          Trunc(Position.Y + Delta.Y * RelPos / D));
     773      end;
     774    end;
    704775  end;
    705776end;
     
    707778function TMetroTrain.GetAngle: Double;
    708779var
    709   I: Integer;
    710   D: Integer;
    711   Sum: Integer;
     780  UpPoint: TTrackPoint;
    712781begin
    713782  Result := 0;
    714   if Assigned(Line) then
    715   with Line do begin
    716     Sum := 0;
    717     if TrackPoints.Count > 1 then
    718     for I := 1 to TrackPoints.Count - 1 do begin
    719       D := Distance(TTrackPoint(TrackPoints[I]).Point, TTrackPoint(TrackPoints[I - 1]).Point);
    720       if (Sum + D) > Self.TrackPos then begin
    721         Result := ArcTan2(TTrackPoint(TrackPoints[I]).Point.Y - TTrackPoint(TrackPoints[I - 1]).Point.Y,
    722           TTrackPoint(TrackPoints[I]).Point.X - TTrackPoint(TrackPoints[I - 1]).Point.X);
    723         Exit;
    724       end else Sum := Sum + D;
     783  if Assigned(BaseTrackPoint) then
     784  with BaseTrackPoint do begin
     785    UpPoint := BaseTrackPoint.GetNeighUp;
     786    if Assigned(UpPoint) then begin
     787      Result := ArcTan2(UpPoint.Position.Y - Position.Y,
     788        UpPoint.Position.X - Position.X);
    725789    end;
    726790  end;
     
    786850  TPAngleGroup := TTrackPointsAngleGroup.Create;
    787851  for I := 0 to Tracks.Count - 1 do begin
    788     Angle := ArcTan2(TTrack(Tracks[I]).PointDown.DesignedPoint.Y - Position.Y,
    789       TTrack(Tracks[I]).PointDown.DesignedPoint.X - Position.X);
     852    Angle := ArcTan2(TTrack(Tracks[I]).PointDown.PositionDesigned.Y - Position.Y,
     853      TTrack(Tracks[I]).PointDown.PositionDesigned.X - Position.X);
    790854    GroupItem := TPAngleGroup.SearchAngle(Angle);
    791855    if not Assigned(GroupItem) then begin
     
    807871        Shift.X := Trunc(MetroLineThickness * Cos(HAngle) * (J - (Tracks.Count - 1) / 2));
    808872        Shift.Y := Trunc(MetroLineThickness * Sin(HAngle) * (J - (Tracks.Count - 1) / 2));
    809         PointDown.PointShift := Shift;
    810         PointUp.PointShift := Shift;
     873        PointDown.PositionShift := Shift;
     874        PointUp.PositionShift := Shift;
    811875      end;
    812876  end;
     
    9411005  with TMetroLine(Lines[I]) do begin
    9421006    for T := 1 to TrackPoints.Count - 1 do begin
    943       D := PointToLineDistance(Pos, TTrackPoint(TrackPoints[T - 1]).Point, TTrackPoint(TrackPoints[T]).Point);
     1007      D := PointToLineDistance(Pos, TTrackPoint(TrackPoints[T - 1]).Position, TTrackPoint(TrackPoints[T]).Position);
    9441008      if (D < MinD) and (D < TrackClickDistance) then begin
    9451009        MinD := D;
     
    11321196  PosDelta: Integer;
    11331197  TargetStationIndex: Integer;
    1134   PosChange: Integer;
     1198  PosChange: Double;
    11351199begin
    11361200  // Move trains
     
    11471211            if Line.IsCircular then begin
    11481212              TargetStationIndex := Line.LineStations.Count - 2;
    1149               TrackPos := Line.GetStationTrackPos(TLineStation(Line.LineStations.Last));
     1213              BaseTrackPoint := TLineStation(Line.LineStations.Last).TrackPoint;
     1214              RelPos := 0;
    11501215            end else begin
    11511216              TargetStationIndex := 1;
    11521217              Direction := -Direction;
    11531218            end;
    1154           end else if TargetStationIndex >= Line.LineStations.Count then begin
     1219          end else
     1220          if TargetStationIndex >= Line.LineStations.Count then begin
    11551221            if Line.IsCircular then begin
    11561222              TargetStationIndex := 1;
    1157               TrackPos := 0;
     1223              BaseTrackPoint := TLineStation(Line.LineStations.First).TrackPoint;
     1224              RelPos := 0;
    11581225            end else begin
    11591226              TargetStationIndex := Line.LineStations.Count - 2;
     
    12021269          end;
    12031270
    1204           LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation));
     1271          LastPosDelta := Abs(GetTargetStationDistance);
    12051272          InStation := False;
    12061273          LastTrainMoveTime := Time;
    12071274        end;
    12081275      end else begin
    1209         PosChange := Trunc(Direction * TrainSpeed * (Time - LastTrainMoveTime));
    1210         TrackPos := TrackPos + PosChange;
     1276        PosChange := Direction + Trunc(Direction * TrainSpeed * (Time - LastTrainMoveTime));
     1277        RelPos := RelPos + PosChange;
    12111278        LastTrainMoveTime := Time;
    1212         if TrackPos < 0 then begin
    1213           if Line.IsCircular then TrackPos := Line.GetTrackLength
    1214             else TrackPos := 0;
    1215         end else
    1216         if TrackPos > Line.GetTrackLength then begin
    1217           if Line.IsCircular then TrackPos := 0
    1218             else TrackPos := Line.GetTrackLength;
     1279        if Assigned(BaseTrackPoint) then
     1280        while (Direction = -1) and (RelPos < 0) do begin
     1281          if BaseTrackPoint <> TLineStation(Line.LineStations.First).TrackPoint then begin
     1282            BaseTrackPoint := BaseTrackPoint.GetNeighDown;
     1283            if Assigned(BaseTrackPoint) then
     1284              RelPos := RelPos + BaseTrackPoint.GetDistance
     1285            else begin
     1286              BaseTrackPoint := TLineStation(Line.LineStations.First).TrackPoint;
     1287              RelPos := 0;
     1288            end;
     1289          end else
     1290          if Line.IsCircular then begin
     1291            BaseTrackPoint := TLineStation(Line.LineStations.Last).TrackPoint;
     1292            RelPos := RelPos + BaseTrackPoint.GetDistance;
     1293          end else begin
     1294            RelPos := 0;
     1295            Break;
     1296          end;
    12191297        end;
    1220         PosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation));
     1298        if Assigned(BaseTrackPoint) then
     1299        while (Direction = 1) and (RelPos > BaseTrackPoint.GetDistance) do begin
     1300          if BaseTrackPoint <> TLineStation(Line.LineStations.Last).TrackPoint then begin
     1301            RelPos := RelPos - BaseTrackPoint.GetDistance;
     1302            BaseTrackPoint := BaseTrackPoint.GetNeighUp;
     1303            if not Assigned(BaseTrackPoint) then begin
     1304              BaseTrackPoint := TLineStation(Line.LineStations.Last).TrackPoint;
     1305              RelPos := 0;
     1306            end;
     1307          end else
     1308          if Line.IsCircular then begin
     1309            RelPos := RelPos - BaseTrackPoint.GetDistance;
     1310            BaseTrackPoint := TLineStation(Line.LineStations.First).TrackPoint;
     1311          end else begin
     1312            RelPos := BaseTrackPoint.GetDistance;
     1313            Break;
     1314          end;
     1315        end;
     1316        PosDelta := Abs(GetTargetStationDistance);
    12211317        if PosDelta >= LastPosDelta then begin
    12221318          // We are getting far from station, stop at station
    1223           TrackPos := Line.GetStationTrackPos(TargetStation);
     1319          BaseTrackPoint := TargetStation.TrackPoint;
     1320          RelPos := 0;
    12241321          InStation := True;
    12251322          StationStopTime := Time;
     
    12531350  with TMetroLine(Lines[I]) do
    12541351    for J := 0 to TrackPoints.Count - 1 do
    1255     TTrackPoint(TrackPoints[J]).Point := TTrackPoint(TrackPoints[J]).DesignedPoint;
     1352    TTrackPoint(TrackPoints[J]).Position := TTrackPoint(TrackPoints[J]).PositionDesigned;
    12561353
    12571354  // Calculate new position shifts
     
    12631360  with TMetroLine(Lines[L]) do begin
    12641361    if TrackPoints.Count > 0 then
    1265       TTrackPoint(TrackPoints[0]).Point := AddPoint(TTrackPoint(TrackPoints[0]).DesignedPoint,
    1266         TTrackPoint(TrackPoints[0]).PointShift);
     1362      TTrackPoint(TrackPoints[0]).Position := AddPoint(TTrackPoint(TrackPoints[0]).PositionDesigned,
     1363        TTrackPoint(TrackPoints[0]).PositionShift);
    12671364    for I := 1 to TrackPoints.Count - 1 do
    12681365    with TTrackPoint(TrackPoints[I]) do begin
    1269       Link1 := SubPoint(AddPoint(TTrackPoint(TrackPoints[I]).DesignedPoint, TTrackPoint(TrackPoints[I]).PointShift),
    1270         AddPoint(TTrackPoint(TrackPoints[I - 1]).DesignedPoint, TTrackPoint(TrackPoints[I - 1]).PointShift));
     1366      Link1 := SubPoint(AddPoint(TTrackPoint(TrackPoints[I]).PositionDesigned, TTrackPoint(TrackPoints[I]).PositionShift),
     1367        AddPoint(TTrackPoint(TrackPoints[I - 1]).PositionDesigned, TTrackPoint(TrackPoints[I - 1]).PositionShift));
    12711368      if (I + 1) < TrackPoints.Count then
    1272         Link2 := SubPoint(AddPoint(TTrackPoint(TrackPoints[I + 1]).DesignedPoint, TTrackPoint(TrackPoints[I + 1]).PointShift),
    1273           AddPoint(TTrackPoint(TrackPoints[I]).DesignedPoint, TTrackPoint(TrackPoints[I]).PointShift))
     1369        Link2 := SubPoint(AddPoint(TTrackPoint(TrackPoints[I + 1]).PositionDesigned, TTrackPoint(TrackPoints[I + 1]).PositionShift),
     1370          AddPoint(TTrackPoint(TrackPoints[I]).PositionDesigned, TTrackPoint(TrackPoints[I]).PositionShift))
    12741371        else Link2 := Link1;
    12751372
    12761373      if ArcTanPoint(Link1) = ArcTanPoint(Link2) then begin
    12771374        // Parallel lines
    1278         TTrackPoint(TrackPoints[I]).Point := AddPoint(TTrackPoint(TrackPoints[I]).DesignedPoint,
    1279           TTrackPoint(TrackPoints[I]).PointShift);
     1375        TTrackPoint(TrackPoints[I]).Position := AddPoint(TTrackPoint(TrackPoints[I]).PositionDesigned,
     1376          TTrackPoint(TrackPoints[I]).PositionShift);
    12801377      end else begin
    12811378        // Intersected lines
    1282         NewPoint := LineIntersect(AddPoint(TTrackPoint(TrackPoints[I - 1]).DesignedPoint, TTrackPoint(TrackPoints[I - 1]).PointShift),
    1283           AddPoint(TTrackPoint(TrackPoints[I]).DesignedPoint, TTrackPoint(TrackPoints[I]).PointShift),
    1284           AddPoint(TTrackPoint(TrackPoints[I]).DesignedPoint, TTrackPoint(TrackPoints[I]).PointShift),
    1285           AddPoint(TTrackPoint(TrackPoints[I + 1]).DesignedPoint, TTrackPoint(TrackPoints[I + 1]).PointShift));
    1286         TTrackPoint(TrackPoints[I]).Point := NewPoint;
     1379        NewPoint := LineIntersect(AddPoint(TTrackPoint(TrackPoints[I - 1]).PositionDesigned, TTrackPoint(TrackPoints[I - 1]).PositionShift),
     1380          AddPoint(TTrackPoint(TrackPoints[I]).PositionDesigned, TTrackPoint(TrackPoints[I]).PositionShift),
     1381          AddPoint(TTrackPoint(TrackPoints[I]).PositionDesigned, TTrackPoint(TrackPoints[I]).PositionShift),
     1382          AddPoint(TTrackPoint(TrackPoints[I + 1]).PositionDesigned, TTrackPoint(TrackPoints[I + 1]).PositionShift));
     1383        TTrackPoint(TrackPoints[I]).Position := NewPoint;
    12871384      end;
    12881385    end;
     
    16761773    Canvas.Pen.Style := psSolid;
    16771774    Canvas.Pen.Width := MetroLineThickness;
    1678     if TrackPoints.Count > 0 then Canvas.MoveTo(TTrackPoint(TrackPoints[0]).Point);
     1775    if TrackPoints.Count > 0 then Canvas.MoveTo(TTrackPoint(TrackPoints[0]).Position);
    16791776    for S := 1 to TrackPoints.Count - 1 do begin
    1680       Canvas.LineTo(TTrackPoint(TrackPoints[S]).Point);
     1777      Canvas.LineTo(TTrackPoint(TrackPoints[S]).Position);
    16811778{      if (S = TrackPoints.Count - 1) then begin
    16821779        Canvas.Pen.EndCap := pecSquare;
    1683         Angle := arctan2((TTrackPoint(TrackPoints[S]).Point.Y - TTrackPoint(TrackPoints[S - 1]).Point.Y),
    1684           (TTrackPoint(TrackPoints[S]).Point.X - TTrackPoint(TrackPoints[S - 1]).Point.X));
    1685         EndPoint := Point(Round(TTrackPoint(TrackPoints[S]).Point.X + EndStationLength * Cos(Angle)),
    1686           Round(TTrackPoint(TrackPoints[S]).Point.Y + EndStationLength * Sin(Angle)));
     1780        Angle := arctan2((TTrackPoint(TrackPoints[S]).Position.Y - TTrackPoint(TrackPoints[S - 1]).Position.Y),
     1781          (TTrackPoint(TrackPoints[S]).Position.X - TTrackPoint(TrackPoints[S - 1]).Position.X));
     1782        EndPoint := Point(Round(TTrackPoint(TrackPoints[S]).Position.X + EndStationLength * Cos(Angle)),
     1783          Round(TTrackPoint(TrackPoints[S]).Position.Y + EndStationLength * Sin(Angle)));
    16871784        Canvas.LineTo(EndPoint);
    16881785        Canvas.MoveTo(Point(Round(EndPoint.X + Cos(Angle + Pi / 2) * EndStationLength / 3),
     
    16961793    if (TrackPoints.Count > 1) then begin
    16971794      Canvas.Pen.EndCap := pecSquare;
    1698       Angle := arctan2((TTrackPoint(TrackPoints[1]).Point.Y - TTrackPoint(TrackPoints[0]).Point.Y),
    1699         (TTrackPoint(TrackPoints[1]).Point.X - TTrackPoint(TrackPoints[0]).Point.X));
    1700       Canvas.MoveTo(TTrackPoint(TrackPoints[0]).Point);
    1701       EndPoint := Point(Round(TTrackPoint(TrackPoints[0]).Point.X - EndStationLength * Cos(Angle)),
    1702         Round(TTrackPoint(TrackPoints[0]).Point.Y - EndStationLength * Sin(Angle)));
     1795      Angle := arctan2((TTrackPoint(TrackPoints[1]).Position.Y - TTrackPoint(TrackPoints[0]).Position.Y),
     1796        (TTrackPoint(TrackPoints[1]).Position.X - TTrackPoint(TrackPoints[0]).Position.X));
     1797      Canvas.MoveTo(TTrackPoint(TrackPoints[0]).Position);
     1798      EndPoint := Point(Round(TTrackPoint(TrackPoints[0]).Position.X - EndStationLength * Cos(Angle)),
     1799        Round(TTrackPoint(TrackPoints[0]).Position.Y - EndStationLength * Sin(Angle)));
    17031800      Canvas.LineTo(EndPoint);
    17041801      Canvas.MoveTo(Point(Round(EndPoint.X - Cos(Angle + Pi / 2) * EndStationLength / 3),
     
    17131810  if Assigned(TrackStationDown) and Assigned(TrackStationDown.LineStation) then begin
    17141811    Canvas.Pen.Color := TrackStationDown.Line.Color;
    1715     Canvas.MoveTo(TrackStationDown.LineStation.TrackPoint.Point);
     1812    Canvas.MoveTo(TrackStationDown.LineStation.TrackPoint.Position);
    17161813    DrawLine(Canvas, LastMousePos);
    17171814  end;
    17181815  if Assigned(TrackStationUp) and Assigned(TrackStationUp.LineStation) then begin
    17191816    Canvas.Pen.Color := TrackStationUp.Line.Color;
    1720     Canvas.MoveTo(TrackStationUp.LineStation.TrackPoint.Point);
     1817    Canvas.MoveTo(TrackStationUp.LineStation.TrackPoint.Position);
    17211818    DrawLine(Canvas, LastMousePos);
    17221819  end;
  • trunk/UGeometric.pas

    r25 r27  
    2727function Distance(P1, P2: TPoint): Integer;
    2828begin
    29   Result := Trunc(Sqrt(Sqr(P2.x - P1.X) + Sqr(P2.Y - P1.Y)));
     29  Result := Trunc(Sqrt(Sqr(P2.X - P1.X) + Sqr(P2.Y - P1.Y)));
    3030end;
    3131
     
    122122function ArcTanPoint(Point: TPoint): Float;
    123123begin
    124   Result := ArcTan(Point.Y / Point.X);
     124  Result := ArcTan(Point.X / Point.Y);
    125125end;
    126126
Note: See TracChangeset for help on using the changeset viewer.