Changeset 93 for trunk/UTrack.pas


Ignore:
Timestamp:
Sep 26, 2022, 10:39:03 PM (20 months ago)
Author:
chronos
Message:
  • Added: Support for train carriages.
  • Added: City support implementation preparation.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UTrack.pas

    r91 r93  
    44
    55uses
    6   Classes, SysUtils, Math, Generics.Collections;
     6  Classes, SysUtils, Math, Generics.Collections, UGeometric;
    77
    88type
    99  TTrack = class;
     10  TTrackPoint = class;
    1011  TTrackPoints = class;
    1112  TTrackLink = class;
    1213  TTrackLinks = class;
     14
     15  { TTrackPosition }
     16
     17  TTrackPosition = record
     18    BaseTrackPoint: TTrackPoint;
     19    RelPos: Double;
     20    function GetVector: TVector;
     21    procedure Move(Distance: Double);
     22  end;
    1323
    1424  { TTrackPoint }
     
    93103implementation
    94104
    95 uses
    96   UGeometric;
    97 
    98105resourcestring
    99106  SAlreadyConnectedTrackPoint = 'Trying to connect already connected track point';
    100107  SAlreadyDisconnectedTrackPoint = 'Trying to disconnect not connected track point';
    101108  STrackPointNotFound = 'Track point %d not found';
     109
     110{ TTrackPosition }
     111
     112function TTrackPosition.GetVector: TVector;
     113var
     114  D: Integer;
     115  UpPoint: TTrackPoint;
     116begin
     117  Result.Position := Point(0, 0);
     118  if Assigned(BaseTrackPoint) then
     119  with BaseTrackPoint do begin
     120    UpPoint := BaseTrackPoint.GetNeighUp;
     121    if Assigned(UpPoint) then begin
     122      D := Distance(UpPoint.Position, Position);
     123      if D > 0 then begin
     124        Result.Direction := SubPoint(UpPoint.Position, Position);
     125        Result.Position := Point(Trunc(Position.X + Result.Direction.X * RelPos / D),
     126          Trunc(Position.Y + Result.Direction.Y * RelPos / D));
     127      end;
     128    end;
     129  end;
     130end;
     131
     132procedure TTrackPosition.Move(Distance: Double);
     133var
     134  Direction: Integer;
     135begin
     136  Direction := Sign(Distance);
     137  Distance := Abs(Distance);
     138  while Distance > 0 do begin
     139    if Direction > 0 then begin
     140      if RelPos + Distance < BaseTrackPoint.GetDistance then begin
     141        RelPos := RelPos + Distance;
     142        Distance := 0;
     143      end else begin
     144        if Assigned(BaseTrackPoint.GetNeighUp) then begin
     145          Distance := Distance - (BaseTrackPoint.GetDistance - RelPos);
     146          BaseTrackPoint := BaseTrackPoint.GetNeighUp;
     147          RelPos := 0;
     148        end else
     149          // Reverse direction at the end of track
     150          Direction := -Direction;
     151      end;
     152    end else
     153    if Direction < 0 then begin
     154      if RelPos - Distance >= 0 then begin
     155        RelPos := RelPos - Distance;
     156        Distance := 0;
     157      end else begin
     158        if Assigned(BaseTrackPoint.GetNeighDown) then begin
     159          Distance := Distance - RelPos;
     160          BaseTrackPoint := BaseTrackPoint.GetNeighDown;
     161          RelPos := BaseTrackPoint.GetDistance;
     162        end else
     163        // Reverse direction at the end of track
     164        Direction := -Direction;
     165      end;
     166    end;
     167  end;
     168end;
    102169
    103170{ TTrackLinks }
     
    349416begin
    350417  Index := Track.Points.IndexOf(Self);
    351   Result := Distance(Track.Points[Index + 1].Position, Track.Points[Index].Position);
     418  if Index + 1 < Track.Points.Count then begin
     419    Result := Distance(Track.Points[Index + 1].Position, Track.Points[Index].Position);
     420  end else Result := 0;
    352421end;
    353422
Note: See TracChangeset for help on using the changeset viewer.