Changeset 13 for trunk


Ignore:
Timestamp:
Mar 27, 2015, 12:49:17 PM (9 years ago)
Author:
chronos
Message:
  • Added: Rotate train and their passengers according track.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/UEngine.pas

    r12 r13  
    8282    Line: TMetroLine;
    8383    TrackPos: Integer;
     84    //Angle: Double;
    8485    Direction: Integer;
    8586    InStation: Boolean;
     
    8788    TargetStationIndex: Integer;
    8889    function GetPosition: TPoint;
     90    function GetAngle: Double;
    8991    constructor Create;
    9092    destructor Destroy; override;
     
    142144    procedure DrawLine(Canvas: TCanvas; Pos: TPoint);
    143145    procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TStationShape;
    144       Size: Integer);
     146      Size: Integer; Angle: Double);
    145147    procedure DrawClock(Canvas: TCanvas);
     148    procedure DrawTrains(Canvas: TCanvas);
    146149    procedure ComputeShapeDistance;
    147150    procedure ComputeShapeDistanceStation(Station: TMetroStation;
     
    420423  Sum: Integer;
    421424begin
     425  Result := Point(0, 0);
    422426  if Assigned(Line) then
    423427  with Line do begin
     
    434438      end else Sum := Sum + D;
    435439    end;
    436     Result := TrackPoints[High(TrackPoints)].Point;
    437   end else Result := Point(0, 0);
     440    if Length(TrackPoints) > 0 then
     441      Result := TrackPoints[High(TrackPoints)].Point;
     442  end;
     443end;
     444
     445function TMetroTrain.GetAngle: Double;
     446var
     447  I: Integer;
     448  D: Integer;
     449  Sum: Integer;
     450begin
     451  Result := 0;
     452  if Assigned(Line) then
     453  with Line do begin
     454    Sum := 0;
     455    if Length(TrackPoints) > 1 then
     456    for I := 1 to High(TrackPoints) do begin
     457      D := Distance(TrackPoints[I].Point, TrackPoints[I - 1].Point);
     458      if (Sum + D) > Self.TrackPos then begin
     459        Result := ArcTan2(TrackPoints[I].Point.Y - TrackPoints[I - 1].Point.Y,
     460          TrackPoints[I].Point.X - TrackPoints[I - 1].Point.X);
     461        Exit;
     462      end else Sum := Sum + D;
     463    end;
     464  end;
    438465end;
    439466
     
    588615
    589616procedure TEngine.DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TStationShape;
    590   Size: Integer);
     617  Size: Integer; Angle: Double);
    591618var
    592619  Points: array of TPoint;
    593620  I: Integer;
    594   Angle: Double;
     621  Angle2: Double;
    595622begin
    596623  case Shape of
    597     ssSquare: Canvas.Rectangle(
    598       Position.X - Size div 2, Position.Y - Size div 2,
    599       Position.X + Size div 2, Position.Y + Size div 2);
     624    ssSquare: begin
     625      SetLength(Points, 4);
     626      Points[0] := Point(Position.X - Size div 2, Position.Y - Size div 2);
     627      Points[1] := Point(Position.X + Size div 2, Position.Y - Size div 2);
     628      Points[2] := Point(Position.X + Size div 2, Position.Y + Size div 2);
     629      Points[3] := Point(Position.X - Size div 2, Position.Y + Size div 2);
     630      Points := RotatePoints(Position, Points, Angle);
     631      Canvas.Polygon(Points);
     632    end;
    600633    ssCircle: Canvas.Ellipse(
    601634      Position.X - Size div 2, Position.Y - Size div 2,
     
    606639      Points[1] := Point(Position.X + Size div 2, Position.Y + Size div 2);
    607640      Points[2] := Point(Position.X - Size div 2, Position.Y + Size div 2);
     641      Points := RotatePoints(Position, Points, Angle);
    608642      Canvas.Polygon(Points);
    609643    end;
     
    611645      SetLength(Points, 10);
    612646      for I := 0 to 9 do begin
    613         Angle := I / 10 * 2 * Pi - Pi / 2;
     647        Angle2 := I / 10 * 2 * Pi - Pi / 2;
    614648        if (I mod 2) = 0 then
    615         Points[I] := Point(Round(Position.X + Cos(Angle) * Size / 2),
    616           Round(Position.Y + Sin(Angle) * Size / 2))
     649        Points[I] := Point(Round(Position.X + Cos(Angle2) * Size / 2),
     650          Round(Position.Y + Sin(Angle2) * Size / 2))
    617651        else
    618         Points[I] := Point(Round(Position.X + Cos(Angle) * Size / 5),
    619           Round(Position.Y + Sin(Angle) * Size / 5));
     652        Points[I] := Point(Round(Position.X + Cos(Angle2) * Size / 5),
     653          Round(Position.Y + Sin(Angle2) * Size / 5));
    620654      end;
     655      Points := RotatePoints(Position, Points, Angle);
    621656      Canvas.Polygon(Points);
    622657    end;
     
    635670      Points[10] := Point(Position.X - Size div 6, Position.Y - Size div 2);
    636671      Points[11] := Point(Position.X + Size div 6, Position.Y - Size div 2);
     672      Points := RotatePoints(Position, Points, Angle);
    637673      Canvas.Polygon(Points);
    638674    end;
     
    640676      SetLength(Points, 5);
    641677      for I := 0 to 4 do begin
    642         Angle := I / 5 * 2 * Pi - Pi / 2;
    643         Points[I] := Point(Round(Position.X + Cos(Angle) * Size / 2),
    644           Round(Position.Y + Sin(Angle) * Size / 2));
     678        Angle2 := I / 5 * 2 * Pi - Pi / 2;
     679        Points[I] := Point(Round(Position.X + Cos(Angle2) * Size / 2),
     680          Round(Position.Y + Sin(Angle2) * Size / 2));
    645681      end;
     682      Points := RotatePoints(Position, Points, Angle);
    646683      Canvas.Polygon(Points);
    647684    end;
     
    652689      Points[2] := Point(Position.X, Position.Y + Size div 2);
    653690      Points[3] := Point(Position.X - Size div 2, Position.Y);
     691      Points := RotatePoints(Position, Points, Angle);
    654692      Canvas.Polygon(Points);
    655693    end;
     
    763801end;
    764802
     803procedure TEngine.DrawTrains(Canvas: TCanvas);
     804var
     805  I: Integer;
     806  P: Integer;
     807  Pos: TPoint;
     808  Points: array of TPoint;
     809  Angle: Double;
     810  ShapePos: TPoint;
     811begin
     812    // Draw trains
     813  for I := 0 to Trains.Count - 1 do
     814  with TMetroTrain(Trains[I]) do begin
     815    if Assigned(Line) then begin
     816      Canvas.Brush.Color := Line.Color;
     817      Canvas.Brush.Style := bsSolid;
     818      Canvas.Pen.Style := psClear;
     819      Pos := GetPosition;
     820      Angle := GetAngle;
     821
     822      SetLength(Points, 4);
     823      Points[0] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y - TrainSize div 3), Angle);
     824      Points[1] := RotatePoint(Pos, Point(Pos.X + TrainSize div 2, Pos.Y - TrainSize div 3), Angle);
     825      Points[2] := RotatePoint(Pos, Point(Pos.X + TrainSize div 2, Pos.Y + TrainSize div 3), Angle);
     826      Points[3] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y + TrainSize div 3), Angle);
     827      Canvas.Polygon(Points);
     828      Canvas.Brush.Color := clWhite;
     829      for P := 0 to Passengers.Count - 1 do
     830      with TMetroPassenger(Passengers[P]) do begin
     831        ShapePos := Point(Pos.X - Trunc(TrainSize div 3 * 1) + (P mod 3) * TrainSize div 3,
     832          Pos.Y - Trunc(TrainSize div 6 * 1) + (P div 3) * TrainSize div 3);
     833        ShapePos := RotatePoint(Pos, ShapePos, Angle);
     834        DrawShape(Canvas, ShapePos, Shape, TrainSize div 3, Angle + Pi / 2);
     835      end;
     836    end;
     837  end;
     838
     839end;
     840
    765841procedure TEngine.Tick;
    766842const
     
    11251201  end;
    11261202
    1127   // Draw trains
    1128   for I := 0 to Trains.Count - 1 do
    1129   with TMetroTrain(Trains[I]) do begin
    1130     if Assigned(Line) then begin
    1131       Canvas.Brush.Color := Line.Color;
    1132       Canvas.Brush.Style := bsSolid;
    1133       Canvas.Pen.Style := psClear;
    1134       Pos := GetPosition;
    1135       Canvas.Rectangle(Pos.X - TrainSize div 2, Pos.Y - TrainSize div 2,
    1136         Pos.X + TrainSize div 2, Pos.Y + TrainSize div 2);
    1137       Canvas.Brush.Color := clWhite;
    1138       for P := 0 to Passengers.Count - 1 do
    1139       with TMetroPassenger(Passengers[P]) do begin
    1140         DrawShape(Canvas, Point(Pos.X - Trunc(TrainSize div 3 * 1) + (P mod 3) * TrainSize div 3,
    1141           Pos.Y - Trunc(TrainSize div 3 * 1) + (P div 3) * TrainSize div 3), Shape, TrainSize div 3);
    1142       end;
    1143     end;
    1144   end;
     1203  DrawTrains(Canvas);
    11451204
    11461205  // Draw stations
     
    11521211      Canvas.Brush.Style := bsClear;
    11531212      Canvas.Pen.Color := SelectedLine.Color;
    1154       DrawShape(Canvas, Position, Shape, StationSize + Canvas.Pen.Width + 6);
     1213      DrawShape(Canvas, Position, Shape, StationSize + Canvas.Pen.Width + 6, 0);
    11551214    end;
    11561215    Canvas.Brush.Color := clWhite;
    11571216    Canvas.Brush.Style := bsSolid;
    11581217    Canvas.Pen.Color := clBlack;
    1159     DrawShape(Canvas, Position, Shape, StationSize);
     1218    DrawShape(Canvas, Position, Shape, StationSize, 0);
    11601219
    11611220    // Draw passengers
     
    11651224    with TMetroPassenger(Passengers[P]) do begin
    11661225      DrawShape(Canvas, Point(Position.X + StationSize + P * (PassengerSize + 2), Position.Y - StationSize div 2),
    1167         Shape, PassengerSize);
     1226        Shape, PassengerSize, 0);
    11681227    end;
    11691228
  • trunk/UGeometric.pas

    r4 r13  
    88  Classes, SysUtils, Math;
    99
     10type
     11  TPointArray = array of TPoint;
     12
    1013function Distance(P1, P2: TPoint): Integer;
    1114function Dot(const P1, P2: TPoint): Double;
     
    1316function PointToLineDistance(const P, V, W: TPoint): Integer;
    1417function ComparePoint(P1, P2: TPoint): Boolean;
     18function RotatePoint(Center, P: TPoint; Angle: Double): TPoint;
     19function RotatePoints(Center: TPoint; P: TPointArray; Angle: Double): TPointArray;
    1520
    1621implementation
     
    6772end;
    6873
     74function RotatePoint(Center, P: TPoint; Angle: Double): TPoint;
     75begin
     76  P := Point(P.X - Center.X, P.Y - Center.Y);
     77  Result := Point(Center.X + Round(P.X * Cos(Angle) - P.Y * Sin(Angle)),
     78    Center.Y + Round(P.X * Sin(Angle) + P.Y * Cos(Angle)));
     79end;
     80
     81function RotatePoints(Center: TPoint; P: TPointArray; Angle: Double): TPointArray;
     82var
     83  I: Integer;
     84begin
     85  SetLength(Result, Length(P));
     86  for I := 0 to High(P) do
     87    Result[I] := RotatePoint(Center, P[I], Angle);
     88end;
     89
    6990
    7091end.
Note: See TracChangeset for help on using the changeset viewer.