close Warning: Can't synchronize with repository "(default)" (No changeset 184 in the repository). Look in the Trac log for more information.

Changeset 170


Ignore:
Timestamp:
Nov 23, 2017, 5:02:49 PM (6 years ago)
Author:
chronos
Message:
  • Modified: UGeometry unit rewritten to use generics and define own TPoint and TRect types.
Location:
trunk
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Forms/UFormCharts.lfm

    r145 r170  
    99  OnClose = FormClose
    1010  OnShow = FormShow
    11   LCLVersion = '1.8.0.4'
     11  LCLVersion = '1.6.4.0'
    1212  object Chart1: TChart
    1313    Left = 8
     
    3535  object ComboBox1: TComboBox
    3636    Left = 24
    37     Height = 36
     37    Height = 28
    3838    Top = 8
    3939    Width = 392
    40     ItemHeight = 0
     40    ItemHeight = 20
    4141    ItemIndex = 0
    4242    Items.Strings = (
  • trunk/Forms/UFormMain.lfm

    r157 r170  
    55  Width = 775
    66  Caption = 'xTactics'
    7   ClientHeight = 587
     7  ClientHeight = 596
    88  ClientWidth = 775
    99  Menu = MainMenu1
     
    1313  OnKeyUp = FormKeyUp
    1414  OnShow = FormShow
    15   LCLVersion = '1.8.0.4'
     15  LCLVersion = '1.6.4.0'
    1616  WindowState = wsMaximized
    1717  object StatusBar1: TStatusBar
    1818    Left = 0
    19     Height = 30
    20     Top = 557
     19    Height = 28
     20    Top = 568
    2121    Width = 775
    2222    Panels = <   
     
    3434  object ToolBar1: TToolBar
    3535    Left = 0
    36     Height = 557
     36    Height = 568
    3737    Top = 0
    3838    Width = 32
     
    7272    object ToolButton6: TToolButton
    7373      Left = 1
    74       Top = 170
     74      Top = 194
    7575      Action = AZoomIn
    7676    end
    7777    object ToolButton7: TToolButton
    7878      Left = 1
    79       Top = 202
     79      Top = 226
    8080      Action = AZoomOut
    8181    end
    8282    object ToolButton8: TToolButton
    8383      Left = 1
    84       Top = 234
     84      Top = 258
    8585      Action = AZoomAll
    8686    end
    8787    object ToolButton9: TToolButton
    8888      Left = 1
     89      Height = 32
    8990      Top = 162
    9091      Width = 32
     
    9394    object ToolButton10: TToolButton
    9495      Left = 1
    95       Top = 266
     96      Height = 32
     97      Top = 290
    9698      Width = 32
    9799      Style = tbsSeparator
     
    99101    object ToolButton11: TToolButton
    100102      Left = 1
    101       Top = 274
     103      Top = 322
    102104      Action = Core.AGameLoad
    103105    end
    104106    object ToolButton12: TToolButton
    105107      Left = 1
    106       Top = 306
     108      Top = 354
    107109      Action = Core.AGameSave
    108110    end
    109111    object ToolButton13: TToolButton
    110112      Left = 1
    111       Top = 338
     113      Top = 386
    112114      Action = Core.AExit
    113115    end
     
    115117  object PaintBox1: TPaintBox
    116118    Left = 32
    117     Height = 557
     119    Height = 568
    118120    Top = 0
    119121    Width = 743
  • trunk/Forms/UFormMain.pas

    r158 r170  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
    9   UGame, LCLType, Menus, ActnList, ComCtrls, types, dateutils, XMLConf, DOM;
     9  UGame, LCLType, Menus, ActnList, ComCtrls, dateutils, XMLConf, DOM,
     10  UGeometry;
    1011
    1112const
     
    137138  if Assigned(Core.CurrentClient) then
    138139  with Core.CurrentClient do begin
    139     View.DestRect := Bounds(0, 0, PaintBox1.Width, PaintBox1.Height);
     140    View.DestRect := TRect.CreateBounds(TPoint.Create(0, 0), TPoint.Create(PaintBox1.Width, PaintBox1.Height));
    140141    if csOpaque in PaintBox1.ControlStyle then begin
    141142      TempBitmap.SetSize(PaintBox1.Width, PaintBox1.Height);
     
    166167  if Assigned(Core.CurrentClient) then
    167168  with Core.CurrentClient do
    168     View.DestRect := Bounds(0, 0, PaintBox1.Width, PaintBox1.Height);
     169    View.DestRect := TRect.CreateBounds(TPoint.Create(0, 0), TPoint.Create(PaintBox1.Width, PaintBox1.Height));
    169170  Redraw;
    170171end;
     
    252253  with Core, Game, CurrentClient, View do begin
    253254    MapRect := Map.CalculatePixelRect;
    254     Factor := FloatPoint((DestRect.Right - DestRect.Left) / (MapRect.Right - MapRect.Left),
    255       (DestRect.Bottom - DestRect.Top) / (MapRect.Bottom - MapRect.Top));
     255    Factor := FloatPoint(DestRect.Size.X / MapRect.Size.X,
     256      DestRect.Size.Y / MapRect.Size.Y);
    256257    if Factor.X < Factor.Y then NewZoom := Factor.X
    257258      else NewZoom := Factor.Y;
     
    342343  if Button = mbLeft then begin
    343344    if Assigned(Core.CurrentClient) then begin
    344       StartMousePoint := Point(X, Y);
    345       StartViewPoint := Core.CurrentClient.View.SourceRect.TopLeft;
     345      StartMousePoint := TPoint.Create(X, Y);
     346      StartViewPoint := Core.CurrentClient.View.SourceRect.P1;
    346347      MoveActive := True;
    347348    end;
     
    366367    (Abs(StartMousePoint.Y - Y) > Trunc(Screen.PixelsPerInch * MouseMinDiff)) then
    367368    with Core.Game.CurrentPlayer, Core.CurrentClient do begin
    368       View.SourceRect := Bounds(Trunc(StartViewPoint.X + (StartMousePoint.X - X) / View.Zoom),
    369         Trunc(StartViewPoint.Y + (StartMousePoint.Y - Y) / View.Zoom),
    370         View.SourceRect.Right - View.SourceRect.Left,
    371         View.SourceRect.Bottom - View.SourceRect.Top);
     369      View.SourceRect := TRect.CreateBounds(TPoint.Create(Trunc(StartViewPoint.X + (StartMousePoint.X - X) / View.Zoom),
     370        Trunc(StartViewPoint.Y + (StartMousePoint.Y - Y) / View.Zoom)),
     371        View.SourceRect.Size);
    372372      Redraw;
    373373    end;
     
    375375    OldCell := Core.CurrentClient.View.FocusedCell;
    376376    with Core.Game do
    377       Cell := Map.PosToCell(Core.CurrentClient.View.CanvasToCellPos(Point(X, Y)), Core.CurrentClient.View );
     377      Cell := Map.PosToCell(Core.CurrentClient.View.CanvasToCellPos(TPoint.Create(X, Y)), Core.CurrentClient.View );
    378378    if Assigned(Cell) then begin
    379379      Core.CurrentClient.View.FocusedCell := Cell;
     
    384384      StatusBar1.Panels[0].Text := '';
    385385    end;
    386     CellPos := Core.CurrentClient.View.CanvasToCellPos(Point(X, Y));
     386    CellPos := Core.CurrentClient.View.CanvasToCellPos(TPoint.Create(X, Y));
    387387    StatusBar1.Panels[2].Text := 'CellPos: ' + IntToStr(CellPos.X) + ', ' + IntToStr(CellPos.Y);
    388388    if Cell <> OldCell then Redraw;
     
    396396  (Abs(StartMousePoint.Y - Y) < Trunc(Screen.PixelsPerInch * MouseMinDiff)) then begin
    397397    if Core.Game.Running and (Core.Game.CurrentPlayer.Mode = pmHuman) then begin
    398       Core.CurrentClient.View.SelectCell(Point(X, Y), Core.Game.CurrentPlayer, Shift);
     398      Core.CurrentClient.View.SelectCell(TPoint.Create(X, Y), Core.Game.CurrentPlayer, Shift);
    399399      Redraw;
    400400    end;
  • trunk/Forms/UFormNew.pas

    r167 r170  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
    9   ComCtrls, Spin, ExtCtrls, ActnList, ExtDlgs, Menus, UGame;
     9  ComCtrls, Spin, ExtCtrls, ActnList, ExtDlgs, Menus, UGame, UGeometry;
    1010
    1111type
     
    363363  Game.CityEnabled := CheckBoxCity.Checked;
    364364  Game.CityPercentage := SpinEditCityPercent.Value;
    365   Game.Map.Size := Point(SpinEditMapSizeX.Value, SpinEditMapSizeY.Value);
     365  Game.Map.Size := TPoint.Create(SpinEditMapSizeX.Value, SpinEditMapSizeY.Value);
    366366  Game.GrowAmount := TGrowAmount(RadioGroupGrowAmount.ItemIndex);
    367367  Game.GrowCells := TGrowCells(RadioGroupGrowCells.ItemIndex);
  • trunk/Languages/xtactics.cs.po

    r166 r170  
    181181msgid "Help"
    182182msgstr "Nápověda"
     183
     184#: tformmain.menuitem19.caption
     185msgctxt "tformmain.menuitem19.caption"
     186msgid "-"
     187msgstr ""
     188
     189#: tformmain.menuitem5.caption
     190msgctxt "tformmain.menuitem5.caption"
     191msgid "-"
     192msgstr ""
    183193
    184194#: tformmain.menuitem8.caption
  • trunk/Languages/xtactics.po

    r166 r170  
    167167msgctxt "tformmain.menuitem16.caption"
    168168msgid "Help"
     169msgstr ""
     170
     171#: tformmain.menuitem19.caption
     172msgctxt "TFORMMAIN.MENUITEM19.CAPTION"
     173msgid "-"
     174msgstr ""
     175
     176#: tformmain.menuitem5.caption
     177msgctxt "tformmain.menuitem5.caption"
     178msgid "-"
    169179msgstr ""
    170180
  • trunk/Packages/Common/Common.lpk

    r164 r170  
    1717    <License Value="GNU/GPL"/>
    1818    <Version Minor="7"/>
    19     <Files Count="21">
     19    <Files Count="22">
    2020      <Item1>
    2121        <Filename Value="StopWatch.pas"/>
     
    110110        <UnitName Value="UGeometry"/>
    111111      </Item21>
     112      <Item22>
     113        <Filename Value="UGeometryClasses.pas"/>
     114        <UnitName Value="UGeometryClasses"/>
     115      </Item22>
    112116    </Files>
    113117    <i18n>
  • trunk/Packages/Common/Common.pas

    r164 r170  
    1111  UMemory, UResetableThread, UPool, ULastOpenedList, URegistry,
    1212  UJobProgressView, UXMLUtils, UApplicationInfo, USyncCounter, UListViewSort,
    13   UPersistentForm, UFindFile, UScaleDPI, UGeometry, LazarusPackageIntf;
     13  UPersistentForm, UFindFile, UScaleDPI, UGeometry, UGeometryClasses,
     14  LazarusPackageIntf;
    1415
    1516implementation
  • trunk/Packages/Common/UGeometry.pas

    r169 r170  
    99
    1010type
    11   TPointArray = array of TPoint;
    12 
    13   { TLine }
    14 
    15   TLine = record
     11  { TGPoint }
     12
     13  TGPoint<T> = record
     14  public
     15    X: T;
     16    Y: T;
     17    constructor Create(const X, Y: T);
     18    procedure Rotate(Base: TGPoint<T>; Angle: Double);
     19    class operator Add(const A, B: TGPoint<T>): TGPoint<T>;
     20    class operator Subtract(const A, B: TGPoint<T>): TGPoint<T>;
     21    class operator GreaterThan(const A, B: TGPoint<T>): Boolean;
     22    class operator LessThan(const A, B: TGPoint<T>): Boolean;
     23    class operator Equal(const A, B: TGPoint<T>): Boolean;
     24    function Min(const A, B: TGPoint<T>): TGPoint<T>;
     25    function Max(const A, B: TGPoint<T>): TGPoint<T>;
     26  end;
     27
     28  { TGPoint3D }
     29
     30  TGPoint3D<T> = record
     31  public
     32    X: T;
     33    Y: T;
     34    Z: T;
     35    constructor Create(const X, Y, Z: T);
     36  end;
     37
     38  { TGRect }
     39
     40  TGRect<T> = record
     41  private
     42    function GetEmpty: Boolean;
     43    function GetSize: T;
     44    procedure SetSize(AValue: T);
     45  public
     46    P1: T;
     47    P2: T;
     48    function IsPointInside(const P: T): Boolean;
     49    function Center: T;
     50    procedure SetEmpty;
     51    class operator Equal(const A, B: TGRect<T>): Boolean;
     52    constructor Create(const P1, P2: T);
     53    constructor CreateBounds(const Origin, Size: T);
     54    property Size: T read GetSize write SetSize;
     55    property Empty: Boolean read GetEmpty;
     56  end;
     57
     58  { TGLine }
     59
     60  TGLine<T> = record
    1661  private
    1762    function GetDistance: Double;
    1863    procedure SetDistance(AValue: Double);
    1964  public
    20     P1: TPoint;
    21     P2: TPoint;
    22     function Create(const P1, P2: TPoint): TLine;
    23     function GetMiddle: TPoint;
     65    P1: T;
     66    P2: T;
     67    constructor Create(const P1, P2: T);
     68    function GetMiddle: T;
    2469    function GetAngle: Double;
    25     function GetSize: TPoint;
    26     function ToRect: TRect;
     70    function GetSize: T;
     71    function ToRect: TGRect<T>;
    2772    function DotProduct: Double;
     73    class function LineIntersect(const LineA, LineB: TGLine<T>; out Intersection: T): Boolean; static;
    2874    procedure Rotate(const Angle: Double);
    29     class operator Equal(const A, B: TLine): Boolean;
     75    class operator Equal(const A, B: TGLine<T>): Boolean;
    3076    property Distance: Double read GetDistance write SetDistance;
    3177  end;
    3278
    33   { TPolygon }
    34 
    35   TPolygon = record
     79  { TGPolygon }
     80
     81  TGPolygon<T> = record
    3682  private
    37     function GetPoint(const Index: Integer): TPoint; inline;
    38     procedure SetPoint(const Index: Integer; const AValue: TPoint); inline;
     83    function GetPoint(const Index: Integer): T; inline;
     84    procedure SetPoint(const Index: Integer; const AValue: T); inline;
    3985  public
     86    type
     87      TPointArray = array of T;
     88    var
    4089    Points: TPointArray;
    41     function IsPointInside(const P: TPoint): Boolean;
    42     function Create(const Points: TPointArray): TPolygon; overload;
    43     function Create(const Rect: TRect): TPolygon; overload;
    44     function GetRect: TRect;
    45     procedure AddPoint(const P: TPoint);
     90    function IsPointInside(const P: T): Boolean;
     91    constructor Create(const Points: TPointArray); overload;
     92    constructor Create(const Rect: TGRect<T>); overload;
     93    function GetRect: TGRect<T>;
     94    procedure AddPoint(const P: T);
    4695    procedure Clear;
    47     procedure CutLine(const Vector: TLine; const PointInside: TPoint);
    48     property Items[Index: Integer]: TPoint read GetPoint write SetPoint; default;
    49   end;
    50 
    51 function Distance(const P1, P2: TPoint): Integer;
    52 function Dot(const P1, P2: TPoint): Double;
    53 function AddPoint(const P1, P2: TPoint): TPoint;
    54 function SubPoint(const P1, P2: TPoint): TPoint;
    55 function PointToLineDistance(const P, V, W: TPoint): Integer;
    56 function ComparePoint(const P1, P2: TPoint): Boolean;
    57 function RotatePoint(const Center, P: TPoint; Angle: Double): TPoint;
    58 function RotatePoints(const Center: TPoint; P: TPointArray; Angle: Double): TPointArray;
    59 function LineIntersect(const LineA, LineB: TLine; out Intersection: TPoint): Boolean;
    60 function ArcTan2Point(const Point: TPoint): Float;
    61 function ArcTanPoint(const Point: TPoint): Float;
    62 function RectEquals(const A, B: TRect): Boolean;
    63 function RectEnlarge(const Rect: TRect; Value: Integer): TRect;
    64 function ShiftRect(const ARect: TRect; Delta: TPoint): TRect;
    65 function PointsToRect(const P1, P2: TPoint): TRect;
    66 function PointInRect(const P: TPoint; aRect: TRect): Boolean;
    67 function HalfDistancePoint(const P1, P2: TPoint): TPoint;
    68 function NormalizeAngle(const Angle: Double): Double;
    69 function SubAngle(A1, A2: Double): Double;
     96    procedure CutLine(const Vector: TGLine<T>; const PointInside: T);
     97    property Items[Index: Integer]: T read GetPoint write SetPoint; default;
     98  end;
     99
     100  // Integer
     101  TPoint = TGPoint<Integer>;
     102  TPoint3D = TGPoint3D<Integer>;
     103  TLine = TGLine<TPoint>;
     104  TRect = TGRect<TPoint>;
     105  TPolygon = TGPolygon<TPoint>;
     106
     107  // FLoating
     108  TPointF = TGPoint<Single>;
     109  TPoint3DF = TGPoint3D<Single>;
     110  TRectF = TGRect<TPointF>;
     111  TLineF = TGLine<TPointF>;
     112  TPolygonF = TGPolygon<TPointF>;
     113
     114function Divide(Divident, Divisor: Integer): Integer; overload;
     115function Divide(Divident, Divisor: Double): Double; overload;
     116function TypedRound(Value: Double): Integer; overload;
     117function TypedRound(Value: Double): Double; overload;
     118function StdPointToPoint(Value: Classes.TPoint): TPoint;
     119function PointToStdPoint(Value: TPoint): Classes.TPoint;
    70120
    71121
    72122implementation
    73123
    74 function Distance(const P1, P2: TPoint): Integer;
    75 begin
    76   Result := Trunc(Sqrt(Sqr(P2.X - P1.X) + Sqr(P2.Y - P1.Y)));
    77 end;
    78 
    79 function Dot(const P1, P2: TPoint): Double;
    80 begin
    81   Result := P1.X * P2.X + P1.Y * P2.Y;
    82 end;
    83 
    84 function AddPoint(const P1, P2: TPoint): TPoint;
    85 begin
    86   Result.X := P1.X + P2.X;
    87   Result.Y := P1.Y + P2.Y;
    88 end;
    89 
    90 function SubPoint(const P1, P2: TPoint): TPoint;
    91 begin
    92   Result.X := P1.X - P2.X;
    93   Result.Y := P1.Y - P2.Y;
    94 end;
    95 
    96 function PointToLineDistance(const P, V, W: TPoint): Integer;
    97 var
    98   l2, t: Double;
    99   tt: TPoint;
    100 begin
    101   // Return minimum distance between line segment vw and point p
    102   L2 := Distance(V, W); // i.e. |w-v|^2 -  avoid a sqrt
    103   L2 := Power(l2, 2);
    104   if L2 = 0 then begin
    105     Result := Distance(P, V);   // v == w case
    106     Exit;
    107   end;
    108   // Consider the line extending the segment, parameterized as v + t (w - v).
    109   // We find projection of point p onto the line.
    110   // It falls where t = [(p-v) . (w-v)] / |w-v|^2
    111   T := Dot(SubPoint(P, V), SubPoint(W, V)) / L2;
    112   if T < 0 then begin
    113     Result := Distance(P, V);       // Beyond the 'v' end of the segment
    114     exit;
    115   end
    116   else if T > 1 then begin
    117     Result := Distance(P, W);  // Beyond the 'w' end of the segment
    118     Exit;
    119   end;
    120   TT.X := Trunc(V.X + T * (W.X - V.X));
    121   TT.Y := Trunc(V.Y + T * (W.Y - V.Y));
    122   Result := Distance(P, TT);
    123 end;
    124 
    125 function ComparePoint(const P1, P2: TPoint): Boolean;
    126 begin
    127   Result := (P1.X = P2.X) and (P1.Y = P2.Y);
    128 end;
    129 
    130 function RotatePoint(const Center, P: TPoint; Angle: Double): TPoint;
    131 var
    132   D: TPoint;
    133 begin
    134   D := Point(P.X - Center.X, P.Y - Center.Y);
    135   Result := Point(Center.X + Round(D.X * Cos(Angle) - D.Y * Sin(Angle)),
    136     Center.Y + Round(D.X * Sin(Angle) + D.Y * Cos(Angle)));
    137 end;
    138 
    139 function RotatePoints(const Center: TPoint; P: TPointArray; Angle: Double): TPointArray;
    140 var
    141   I: Integer;
    142 begin
    143   SetLength(Result, Length(P));
    144   for I := 0 to High(P) do
    145     Result[I] := RotatePoint(Center, P[I], Angle);
    146 end;
    147 
    148 function LineIntersect(const LineA, LineB: TLine; out Intersection: TPoint): Boolean;
    149 Var
    150   LDetLineA, LDetLineB, LDetDivInv: Double;
    151   LDiffLA, LDiffLB: TPoint;
    152   D: Integer;
    153 begin
    154   if ComparePoint(LineA.P1, LineA.P2) or ComparePoint(LineB.P1, LineB.P2) then begin
    155     Result := False;
    156     Exit;
    157   end;
    158   LDetLineA := LineA.P1.X * LineA.P2.Y - LineA.P1.Y * LineA.P2.X;
    159   LDetLineB := LineB.P1.X * LineB.P2.Y - LineB.P1.Y * LineB.P2.X;
    160 
    161   LDiffLA := SubPoint(LineA.P1, LineA.P2);
    162   LDiffLB := SubPoint(LineB.P1, LineB.P2);
    163 
    164   D := (LDiffLA.X * LDiffLB.Y) - (LDiffLA.Y * LDiffLB.X);
    165   if D = 0 then begin
    166     // Parallel lines without intersection
    167     Result := False;
    168     Exit;
    169   end;
    170   LDetDivInv := 1 / D;
    171 
    172   Intersection.X := Round(((LDetLineA * LDiffLB.X) - (LDiffLA.X * LDetLineB)) * LDetDivInv);
    173   Intersection.Y := Round(((LDetLineA * LDiffLB.Y) - (LDiffLA.Y * LDetLineB)) * LDetDivInv);
    174   Result := True;
    175 end;
    176 
    177 function ArcTan2Point(const Point: TPoint): Float;
    178 begin
    179   Result := ArcTan2(Point.Y, Point.X);
    180 end;
    181 
    182 function ArcTanPoint(const Point: TPoint): Float;
    183 begin
    184   if Point.Y = 0 then Result := Infinity
    185     else Result := ArcTan(Point.X / Point.Y);
    186 end;
    187 
    188 function RectEquals(const A, B: TRect): Boolean;
    189 begin
    190   Result := (A.Left = B.Left) and (A.Top = B.Top) and
    191     (A.Right = B.Right) and (A.Bottom = B.Bottom);
    192 end;
    193 
    194 function RectEnlarge(const Rect: TRect; Value: Integer): TRect;
    195 begin
    196   Result.Left := Rect.Left - Value;
    197   Result.Right := Rect.Right + Value;
    198   Result.Top := Rect.Top - Value;
    199   Result.Bottom := Rect.Bottom + Value;
    200 end;
    201 
    202 function ShiftRect(const ARect: TRect; Delta: TPoint): TRect;
    203 begin
    204   Result := Rect(ARect.Left + Delta.X, ARect.Top + Delta.Y,
    205     ARect.Right + Delta.X, ARect.Bottom + Delta.Y);
    206 end;
    207 
    208 function PointsToRect(const P1, P2: TPoint): TRect;
    209 begin
    210   if P1.X < P2.X then Result.Left := P1.X else Result.Left := P2.X;
    211   if P1.Y < P2.Y then Result.Top := P1.Y else Result.Top := P2.Y;
    212   if P1.X > P2.X then Result.Right := P1.X else Result.Right := P2.X;
    213   if P1.Y > P2.Y then Result.Bottom := P1.Y else Result.Bottom := P2.Y;
    214 end;
    215 
    216 function PointInRect(const P: TPoint; aRect: TRect): Boolean;
    217 begin
    218   Result := (P.X >= aRect.Left) and (P.X <= aRect.Right) and
    219     (P.Y >= aRect.Top) and (P.Y <= aRect.Bottom);
    220 end;
    221 
    222 function HalfDistancePoint(const P1, P2: TPoint): TPoint;
    223 begin
    224   Result := Point(P1.X + (P2.X - P1.X) div 2, P1.Y + (P2.Y - P1.Y) div 2)
    225 end;
    226 
    227 function NormalizeAngle(const Angle: Double): Double;
    228 begin
    229   if Angle < 0 then Result := Angle + (Trunc(Angle / (2 * Pi)) + 1) * (2 * Pi)
    230   else if Angle > 2 * Pi then Result := Angle - Trunc(Angle / (2 * Pi)) * (2 * Pi)
    231   else Result := Angle;
    232 end;
    233 
    234 function SubAngle(A1, A2: Double): Double;
    235 begin
    236   A1 := NormalizeAngle(A1);
    237   A2 := NormalizeAngle(A2);
    238   if A1 < A2 then Result := A1 + 2 * Pi - A2
    239     else Result := A1 - A2;
     124function Divide(Divident, Divisor: Integer): Integer;
     125begin
     126  Result := Divident div Divisor;
     127end;
     128
     129function Divide(Divident, Divisor: Double): Double;
     130begin
     131  Result := Divident / Divisor;
     132end;
     133
     134function TypedRound(Value: Double): Integer;
     135begin
     136  Result := Round(Value);
     137end;
     138
     139function TypedRound(Value: Double): Double;
     140begin
     141  Result := Value;
     142end;
     143
     144function StdPointToPoint(Value: Classes.TPoint): TPoint;
     145begin
     146  Result.X := Value.X;
     147  Result.Y := Value.Y;
     148end;
     149
     150function PointToStdPoint(Value: TPoint): Classes.TPoint;
     151begin
     152  Result.X := Value.X;
     153  Result.Y := Value.Y;
    240154end;
    241155
    242156{ TPolygon }
    243157
    244 function TPolygon.GetPoint(const Index: Integer): TPoint;
     158function TGPolygon<T>.GetPoint(const Index: Integer): T;
    245159begin
    246160  Result := Points[Index];
    247161end;
    248162
    249 procedure TPolygon.SetPoint(const Index: Integer; const AValue: TPoint);
     163procedure TGPolygon<T>.SetPoint(const Index: Integer; const AValue: T);
    250164begin
    251165  Points[Index] := AValue;
    252166end;
    253167
    254 function TPolygon.IsPointInside(const P: TPoint): Boolean;
     168function TGPolygon<T>.IsPointInside(const P: T): Boolean;
    255169var
    256170  I, J: Integer;
     
    292206
    293207
    294 function TPolygon.Create(const Points: TPointArray): TPolygon;
     208constructor TGPolygon<T>.Create(const Points: TPointArray);
    295209var
    296210  I: Integer;
    297211begin
    298   SetLength(Result.Points, Length(Points));
     212  SetLength(Self.Points, Length(Points));
    299213  for I := 0 to Length(Points) - 1 do
    300     Result.Points[I] := Points[I];
    301 end;
    302 
    303 function TPolygon.Create(const Rect: TRect): TPolygon;
    304 begin
    305   SetLength(Result.Points, 4);
    306   Result.Points[0] := Point(Rect.Left, Rect.Top);
    307   Result.Points[1] := Point(Rect.Right, Rect.Top);
    308   Result.Points[2] := Point(Rect.Right, Rect.Bottom);
    309   Result.Points[3] := Point(Rect.Left, Rect.Bottom);
    310 end;
    311 
    312 function TPolygon.GetRect: TRect;
     214    Self.Points[I] := Points[I];
     215end;
     216
     217constructor TGPolygon<T>.Create(const Rect: TGRect<T>);
     218begin
     219  SetLength(Self.Points, 4);
     220  Self.Points[0] := Rect.P1;
     221  Self.Points[1] := T.Create(Rect.P2.X, Rect.P1.Y);
     222  Self.Points[2] := Rect.P1;
     223  Self.Points[3] := T.Create(Rect.P1.X, Rect.P2.Y);
     224end;
     225
     226function TGPolygon<T>.GetRect: TGRect<T>;
    313227var
    314228  I: Integer;
    315 begin
    316   Result := Rect(High(Integer), High(Integer),
    317     Low(Integer), Low(Integer));
    318   for I := 0 to Length(Points) - 1 do
    319   with Points[I] do begin
    320     if X > Result.Right then
    321       Result.Right := X;
    322     if X < Result.Left then
    323       Result.Left := X;
    324     if Y > Result.Bottom then
    325       Result.Bottom := Y;
    326     if Y < Result.Top then
    327       Result.Top := Y;
    328   end;
    329 end;
    330 
    331 procedure TPolygon.AddPoint(const P: TPoint);
     229  P1: TGPoint<T>;
     230begin
     231  if Length(Points) = 0 then
     232    Result.Empty
     233  else begin
     234    Result := TGRect<T>.Create(Points[0], Points[0]);
     235    for I := 1 to Length(Points) - 1 do
     236    with Points[I] do begin
     237      Result.P1 := Points[I].Min(Result.P1, Points[I]);
     238      Result.P2 := Points[I].Max(Result.P2, Points[I]);
     239    end;
     240  end;
     241end;
     242
     243procedure TGPolygon<T>.AddPoint(const P: T);
    332244begin
    333245  SetLength(Points, Length(Points) + 1);
     
    335247end;
    336248
    337 procedure TPolygon.Clear;
     249procedure TGPolygon<T>.Clear;
    338250begin
    339251  SetLength(Points, 0);
    340252end;
    341253
    342 procedure TPolygon.CutLine(const Vector: TLine; const PointInside: TPoint);
     254procedure TGPolygon<T>.CutLine(const Vector: TGLine<T>; const PointInside: T);
    343255var
    344256  I: Integer;
    345257  PointsChecked: Integer;
    346   L1, L2: TLine;
    347   Intersection: TPoint;
    348   NewPoly: TPolygon;
     258  L1, L2: TGLine<T>;
     259  Intersection: T;
     260  NewPoly: TGPolygon<T>;
    349261  NewPolygonStarted: Boolean;
    350262  Success: Boolean;
     
    359271  if Length(Points) > 0 then
    360272  while True do begin
    361     L2 := TLine.Create(Points[I], Points[(I + 1) mod Length(Points)]);
    362     if LineIntersect(L1, L2, Intersection) then
    363     if PointInRect(Intersection, L2.ToRect) then begin
     273    L2 := TGLine<T>.Create(Points[I], Points[(I + 1) mod Length(Points)]);
     274    if TGLine<T>.LineIntersect(L1, L2, Intersection) then
     275    if L2.ToRect.IsPointInside(Intersection) then begin
    364276      if not NewPolygonStarted then begin
    365277        // Crossing line, start new polygon
     
    391303{ TLine }
    392304
    393 function TLine.GetDistance: Double;
     305function TGLine<T>.GetDistance: Double;
    394306begin
    395307  Result := Sqrt(Sqr(P2.X - P1.X) + Sqr(P2.Y - P1.Y));
    396308end;
    397309
    398 procedure TLine.SetDistance(AValue: Double);
     310procedure TGLine<T>.SetDistance(AValue: Double);
    399311var
    400312  Angle: Double;
    401313begin
    402314  Angle := GetAngle;
    403   P2 := Point(Round(P1.X + Cos(Angle) * AValue),
     315  P2 := T.Create(Round(P1.X + Cos(Angle) * AValue),
    404316    Round(P1.Y + Sin(Angle) * AValue));
    405317end;
    406318
    407 function TLine.Create(const P1, P2: TPoint): TLine;
     319constructor TGLine<T>.Create(const P1, P2: T);
     320begin
     321  Self.P1 := P1;
     322  Self.P2 := P2;
     323end;
     324
     325function TGLine<T>.GetMiddle: T;
     326begin
     327  Result := T.Create(P1.X + Divide((P2.X - P1.X), 2), P1.Y + Divide((P2.Y - P1.Y), 2));
     328end;
     329
     330function TGLine<T>.GetAngle: Double;
     331begin
     332  Result := ArcTan2(P2.Y - P1.Y, P2.X - P1.X);
     333end;
     334
     335function TGLine<T>.GetSize: T;
     336begin
     337  Result := P2 - P1;
     338end;
     339
     340function TGLine<T>.ToRect: TGRect<T>;
    408341begin
    409342  Result.P1 := P1;
     
    411344end;
    412345
    413 function TLine.GetMiddle: TPoint;
    414 begin
    415   Result := Point(P1.X + (P2.X - P1.X) div 2, P1.Y + (P2.Y - P1.Y) div 2);
    416 end;
    417 
    418 function TLine.GetAngle: Double;
    419 begin
    420   Result := ArcTan2(P2.Y - P1.Y, P2.X - P1.X);
    421 end;
    422 
    423 function TLine.GetSize: TPoint;
    424 begin
    425   Result := Point(P2.X - P1.X, P2.Y - P1.Y);
    426 end;
    427 
    428 function TLine.ToRect: TRect;
    429 begin
    430   if P1.X < P2.X then Result.Left := P1.X else Result.Left := P2.X;
    431   if P1.Y < P2.Y then Result.Top := P1.Y else Result.Top := P2.Y;
    432   if P1.X > P2.X then Result.Right := P1.X else Result.Right := P2.X;
    433   if P1.Y > P2.Y then Result.Bottom := P1.Y else Result.Bottom := P2.Y;
    434 end;
    435 
    436 function TLine.DotProduct: Double;
     346function TGLine<T>.DotProduct: Double;
    437347begin
    438348  Result := P1.X * P2.X + P1.Y * P2.Y;
    439349end;
    440350
    441 procedure TLine.Rotate(const Angle: Double);
    442 begin
    443   P2 := RotatePoint(P1, P2, Angle);
    444 end;
    445 
    446 class operator TLine.Equal(const A, B: TLine): Boolean;
    447 begin
    448   Result := ComparePoint(A.P1, B.P1) and ComparePoint(A.P2, B.P2);
     351procedure TGLine<T>.Rotate(const Angle: Double);
     352begin
     353  P2.Rotate(P1, Angle);
     354end;
     355
     356class operator TGLine<T>.Equal(const A, B: TGLine<T>): Boolean;
     357begin
     358  Result := (A.P1 = B.P1) and (A.P2 = B.P2);
     359end;
     360
     361{ TGPoint3D }
     362
     363constructor TGPoint3D<T>.Create(const X, Y, Z: T);
     364begin
     365  Self.X := X;
     366  Self.Y := Y;
     367  Self.Z := Z;
     368end;
     369
     370{ TGPoint }
     371
     372constructor TGPoint<T>.Create(const X, Y: T);
     373begin
     374  Self.X := X;
     375  Self.Y := Y;
     376end;
     377
     378class operator TGPoint<T>.Equal(const A, B: TGPoint<T>): Boolean;
     379begin
     380  Result := (A.X = B.X) and (A.Y = B.Y);
     381end;
     382
     383class operator TGPoint<T>.Add(const A, B: TGPoint<T>): TGPoint<T>;
     384begin
     385  Result.X := A.X + B.X;
     386  Result.Y := A.Y + B.Y;
     387end;
     388
     389class operator TGPoint<T>.Subtract(const A, B: TGPoint<T>): TGPoint<T>;
     390begin
     391  Result.X := A.X - B.X;
     392  Result.Y := A.Y - B.Y;
     393end;
     394
     395class operator TGPoint<T>.GreaterThan(const A, B: TGPoint<T>): Boolean;
     396begin
     397  Result := (B.X > A.X) and (B.Y > A.Y);
     398end;
     399
     400class operator TGPoint<T>.LessThan(const A, B: TGPoint<T>): Boolean;
     401begin
     402  Result := (B.X < A.X) and (B.Y < A.Y);
     403end;
     404
     405{ TGLine }
     406
     407class function TGLine<T>.LineIntersect(const LineA, LineB: TGLine<T>; out
     408  Intersection: T): Boolean;
     409Var
     410  LDetLineA, LDetLineB, LDetDivInv: Double;
     411  LDiffLA, LDiffLB: T;
     412  D: Double;
     413begin
     414  if (LineA.P1 = LineA.P2) or (LineB.P1 = LineB.P2) then begin
     415    Result := False;
     416    Exit;
     417  end;
     418  LDetLineA := LineA.P1.X * LineA.P2.Y - LineA.P1.Y * LineA.P2.X;
     419  LDetLineB := LineB.P1.X * LineB.P2.Y - LineB.P1.Y * LineB.P2.X;
     420
     421  LDiffLA := LineA.P1 - LineA.P2;
     422  LDiffLB := LineB.P1 - LineB.P2;
     423
     424  D := (LDiffLA.X * LDiffLB.Y) - (LDiffLA.Y * LDiffLB.X);
     425  if D = 0 then begin
     426    // Parallel lines without intersection
     427    Result := False;
     428    Exit;
     429  end;
     430  LDetDivInv := 1 / D;
     431
     432  Intersection.X := TypedRound(((LDetLineA * LDiffLB.X) - (LDiffLA.X * LDetLineB)) * LDetDivInv);
     433  Intersection.Y := TypedRound(((LDetLineA * LDiffLB.Y) - (LDiffLA.Y * LDetLineB)) * LDetDivInv);
     434  Result := True;
     435end;
     436
     437procedure TGPoint<T>.Rotate(Base: TGPoint<T>; Angle: Double);
     438var
     439  D: TGPoint<T>;
     440begin
     441  D := TGPoint<T>.Create(X - Base.X, Y - Base.Y);
     442  //X := Base.X + TypedRound(D.X * Cos(Angle) - D.Y * Sin(Angle));
     443  //Y := Base.Y + TypedRound(D.X * Sin(Angle) + D.Y * Cos(Angle));
     444end;
     445
     446function TGPoint<T>.Min(const A, B: TGPoint<T>): TGPoint<T>;
     447begin
     448  if A.X < B.X then Result.X := A.X else Result.X := B.X;
     449  if A.Y < B.Y then Result.Y := A.Y else Result.Y := B.Y;
     450end;
     451
     452function TGPoint<T>.Max(const A, B: TGPoint<T>): TGPoint<T>;
     453begin
     454  if A.X > B.X then Result.X := A.X else Result.X := B.X;
     455  if A.Y > B.Y then Result.Y := A.Y else Result.Y := B.Y;
     456end;
     457
     458{ TGRect }
     459
     460function TGRect<T>.IsPointInside(const P: T): Boolean;
     461begin
     462  Result := (P > P1) and (P < P2);
     463end;
     464
     465function TGRect<T>.GetEmpty: Boolean;
     466begin
     467  Result := P1 = P2;
     468end;
     469
     470procedure TGRect<T>.SetEmpty;
     471begin
     472  P2 := P1;
     473end;
     474
     475function TGRect<T>.Center: T;
     476begin
     477  Result.X := Divide(P2.X - P1.X, 2);
     478  Result.Y := Divide(P2.Y - P1.Y, 2);
     479end;
     480
     481function TGRect<T>.GetSize: T;
     482begin
     483  Result := P2 - P1;
     484end;
     485
     486procedure TGRect<T>.SetSize(AValue: T);
     487begin
     488  P2 := P1 + AValue;
     489end;
     490
     491constructor TGRect<T>.Create(const P1, P2: T);
     492begin
     493  Self.P1 := P1;
     494  Self.P2 := P2;
     495end;
     496
     497constructor TGRect<T>.CreateBounds(const Origin, Size: T);
     498begin
     499  Self.P1 := Origin;
     500  Self.P2 := Origin + Size;
     501end;
     502
     503class operator TGRect<T>.Equal(const A, B: TGRect<T>): Boolean;
     504begin
     505  Result := (A.P1 = B.P1) and (A.P2 = B.P2);
    449506end;
    450507
  • trunk/UCore.lrt

    r134 r170  
    1515TCORE.AABOUT.CAPTION=About
    1616TCORE.AHELP.CAPTION=Help
    17 TCORE.ASHOWCHARTS.CAPTION=Show charts
     17TCORE.ASHOWCHARTS.CAPTION=Charts
     18TCORE.ASHOWUNITMOVES.CAPTION=Unit moves
  • trunk/UCore.pas

    r166 r170  
    88  Classes, SysUtils, XMLConf, FileUtil, ActnList, Controls, Dialogs, Forms,
    99  UGame, UApplicationInfo, UPersistentForm, UScaleDPI, UCoolTranslator,
    10   URegistry, ULastOpenedList, Registry, Menus;
     10  URegistry, ULastOpenedList, Registry, Menus, UGeometry;
    1111
    1212type
     
    419419  LastOpenedList1.AddItem(FileName);
    420420  with Core.CurrentClient do
    421     View.DestRect := Bounds(0, 0, FormMain.PaintBox1.Width, FormMain.PaintBox1.Height);
     421    View.DestRect := TRect.CreateBounds(TPoint.Create(0, 0),
     422      TPoint.Create(FormMain.PaintBox1.Width, FormMain.PaintBox1.Height));
    422423  FormMain.AZoomAll.Execute;
    423424  FormMain.Redraw;
  • trunk/UGame.pas

    r168 r170  
    161161  TCanvasEx = class(TCanvas)
    162162    class procedure TextOutEx(Canvas: TCanvas; X,Y: Integer; const Text: string; MovePen: Boolean = True);
    163     class procedure PolygonEx(Canvas: TCanvas; const Points: array of TPoint; Winding: Boolean);
     163    class procedure PolygonEx(Canvas: TCanvas; const Points: array of Classes.TPoint; Winding: Boolean);
    164164  end;
    165165
     
    957957    with CellLink do begin
    958958      if Length(Points) >= 2 then begin
    959         MoveTo(View.CellToCanvasPos(Points[0]));
     959        MoveTo(PointToStdPoint(View.CellToCanvasPos(Points[0])));
    960960        for I := 1 to Length(Points) - 1 do
    961           LineTo(View.CellToCanvasPos(Points[I]));
     961          LineTo(PointToStdPoint(View.CellToCanvasPos(Points[I])));
    962962      end;
    963963    end;
     
    999999      for NeighCell in Cell.MapCell.Neighbors do begin
    10001000        Pen.Color := clYellow;
    1001         MoveTo(View.CellToCanvasPos(Cell.MapCell.PosPx));
    1002         LineTo(View.CellToCanvasPos(NeighCell.PosPx));
     1001        MoveTo(PointToStdPoint(View.CellToCanvasPos(Cell.MapCell.PosPx)));
     1002        LineTo(PointToStdPoint(View.CellToCanvasPos(NeighCell.PosPx)));
    10031003      end;
    10041004
     
    10221022      Angle := ArcTan((PosTo.Y - PosFrom.Y) / (PosTo.X - PosFrom.X));
    10231023      if Sign(PosTo.X - PosFrom.X) = -1 then Angle := Angle + Pi;
    1024       ArrowCenter := View.CellToCanvasPos(Point(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 2),
     1024      ArrowCenter := View.CellToCanvasPos(TPoint.Create(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 2),
    10251025        Trunc(PosFrom.Y + (PosTo.Y - PosFrom.Y) / 2)));
    10261026      Player.Game.Map.DrawArrow(Canvas, View, ArrowCenter,
     
    10511051end;
    10521052
    1053 class procedure TCanvasEx.PolygonEx(Canvas: TCanvas; const Points: array of TPoint; Winding: Boolean);
     1053class procedure TCanvasEx.PolygonEx(Canvas: TCanvas; const Points: array of Classes.TPoint; Winding: Boolean);
    10541054begin
    10551055  //Changing;
     
    13491349  for Cell in Cells do begin
    13501350    for NeighborCell in Cell.Neighbors do
    1351       NeighborCell.Angle := ArcTan2Point(Point(
    1352         NeighborCell.PosPx.X - Cell.PosPx.X,
    1353         NeighborCell.PosPx.Y - Cell.PosPx.Y));
     1351      NeighborCell.Angle := TLine.Create(Cell.PosPx, NeighborCell.PosPx).GetAngle;
    13541352
    13551353    Cell.Neighbors.Sort(CompareCellAngle);
     
    13751373      Rect := PixelRect;
    13761374      with Image.Picture.Bitmap do begin
    1377         Pos := Point(Trunc(Coord.X / (Rect.Right - Rect.Left) * Width),
    1378           Trunc(Coord.Y / (Rect.Bottom - Rect.Top) * Height));
     1375        Pos := TPoint.Create(Trunc(Coord.X / Rect.Size.X * Width),
     1376          Trunc(Coord.Y / Rect.Size.Y * Height));
    13791377        Color := Canvas.Pixels[Pos.X, Pos.Y];
    13801378      end;
     
    13831381    msRounded: begin
    13841382      Rect := PixelRect;
    1385       Center := Point(Rect.Left + (Rect.Right - Rect.Left) div 2,
    1386         Rect.Top + (Rect.Bottom - Rect.Top) div 2);
    1387       Result := Sqr(Coord.X - Center.X) / Sqr((Rect.Right - Rect.Left) div 2) +
    1388         Sqr(Coord.Y - Center.Y) / Sqr((Rect.Bottom - Rect.Top) div 2) > 1;
     1383      Center := Rect.Center;
     1384      Result := Sqr(Coord.X - Center.X) / Sqr(Rect.Size.X div 2) +
     1385        Sqr(Coord.Y - Center.Y) / Sqr(Rect.Size.Y div 2) > 1;
    13891386    end
    13901387    else Result := False;
     
    13951392  Angle: Double; Text: string);
    13961393var
    1397   Points: array of TPoint;
     1394  Points: array of Classes.TPoint;
    13981395  FPoints: array of TFloatPoint;
    13991396  I: Integer;
     
    14041401  SetLength(Points, 8);
    14051402  SetLength(FPoints, 8);
    1406   ArrowSize := Point(Trunc(DefaultCellSize.X / 3 * View.Zoom),
     1403  ArrowSize := TPoint.Create(Trunc(DefaultCellSize.X / 3 * View.Zoom),
    14071404    Trunc(DefaultCellSize.Y / 3 * View.Zoom));
    14081405  FPoints[0] := FloatPoint(+0.5 * ArrowSize.X, +0 * ArrowSize.Y);
     
    14801477  Node2: TDOMNode;
    14811478begin
    1482   Size := Point(ReadInteger(Node, 'SizeX', 0), ReadInteger(Node, 'SizeY', 0));
     1479  Size := TPoint.Create(ReadInteger(Node, 'SizeX', 0), ReadInteger(Node, 'SizeY', 0));
    14831480  DefaultCellSize.X := ReadInteger(Node, 'DefaultCellSizeX', 1);
    14841481  DefaultCellSize.Y := ReadInteger(Node, 'DefaultCellSizeY', 1);
     
    15651562  I: Integer;
    15661563  TextPos: TPoint;
    1567   Points: array of TPoint;
     1564  Points: array of Classes.TPoint;
    15681565  TextSize: TSize;
    15691566begin
     
    15901587    SetLength(Points, Length(Cell.Polygon.Points));
    15911588    for I := 0 to Length(Points) - 1 do
    1592       Points[I] := View.CellToCanvasPos(Cell.Polygon.Points[I]);
     1589      Points[I] := PointToStdPoint(View.CellToCanvasPos(Cell.Polygon.Points[I]));
    15931590    Brush.Style := bsSolid;
    15941591    //Polygon(Points, False, 0, Length(Points));
     
    16401637    NewCell := TCell.Create;
    16411638    NewCell.Map := Self;
    1642     NewCell.PosPx := Point(X * DefaultCellSize.X, Y * DefaultCellSize.Y);
     1639    NewCell.PosPx := TPoint.Create(X * DefaultCellSize.X, Y * DefaultCellSize.Y);
    16431640    NewCell.Id := GetNewCellId;
    16441641    SetLength(NewCell.Polygon.Points, 1);
     
    17311728begin
    17321729  MaxPower := 99;
    1733   DefaultCellSize := Point(220, 220);
     1730  DefaultCellSize := TPoint.Create(220, 220);
    17341731  Cells := TCells.Create;
    17351732  Cells.Map := Self;
    1736   Size := Point(0, 0);
     1733  Size := TPoint.Create(0, 0);
    17371734  Image := TImage.Create(nil);
    17381735  CellLinks := TCellLinks.Create;
     
    17431740destructor TMap.Destroy;
    17441741begin
    1745   Size := Point(0, 0);
     1742  Size := TPoint.Create(0, 0);
    17461743  FreeAndNil(Areas);
    17471744  FreeAndNil(CellLinks);
     
    17561753  CellRect: TRect;
    17571754begin
    1758   Result := Rect(0, 0, 0, 0);
     1755  Result := TRect.Create(TPoint.Create(0, 0), TPoint.Create(0, 0));
    17591756  // This is generic algorithm to determine pixel size of entire map
    17601757  for I := 0 to Cells.Count - 1 do begin
     
    17621759    if I = 0 then Result := CellRect
    17631760      else begin
    1764         if CellRect.Right > Result.Right then Result.Right := CellRect.Right;
    1765         if CellRect.Bottom > Result.Bottom then Result.Bottom := CellRect.Bottom;
    1766         if CellRect.Left < Result.Left then Result.Left := CellRect.Left;
    1767         if CellRect.Top < Result.Top then  Result.Top := CellRect.Top;
     1761        Result.P1 := TPoint.Min(Result.P1, CellRect.P1);
     1762        Result.P2 := TPoint.Max(Result.P2, CellRect.P2);
    17681763      end;
    17691764  end;
     
    18401835    raise Exception.Create(SZeroZoomNotAlowed);
    18411836  FZoom := AValue;
    1842   SourceRect := Bounds(Trunc(SourceRect.Left + (SourceRect.Right - SourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),
    1843     Trunc(SourceRect.Top +  (SourceRect.Bottom - SourceRect.Top) div 2 - (DestRect.Bottom - DestRect.Top) / Zoom / 2),
    1844     Trunc((DestRect.Right - DestRect.Left) / Zoom),
    1845     Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
     1837  SourceRect := TRect.CreateBounds(TPoint.Create(Trunc(SourceRect.P1.X + SourceRect.Size.X div 2 - DestRect.Size.X / Zoom / 2),
     1838    Trunc(SourceRect.P1.Y +  SourceRect.Size.Y div 2 - DestRect.Size.Y / Zoom / 2)),
     1839    TPoint.Create(Trunc(DestRect.Size.X / Zoom),
     1840    Trunc(DestRect.Size.Y / Zoom)));
    18461841end;
    18471842
     
    18561851  Diff: TPoint;
    18571852begin
    1858   if RectEquals(FDestRect, AValue) then Exit;
    1859   Diff := Point(Trunc((DestRect.Right - DestRect.Left) / Zoom - (AValue.Right - AValue.Left) / Zoom) div 2,
    1860     Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2);
     1853  if FDestRect = AValue then Exit;
     1854  Diff := TPoint.Create(Trunc(DestRect.Size.X / Zoom - AValue.Size.X / Zoom) div 2,
     1855    Trunc(DestRect.Size.Y / Zoom - AValue.Size.Y / Zoom) div 2);
    18611856  FDestRect := AValue;
    1862   SourceRect := Bounds(SourceRect.Left + Diff.X, SourceRect.Top + Diff.Y,
    1863     Trunc((DestRect.Right - DestRect.Left) / Zoom),
    1864     Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
     1857  SourceRect := TRect.CreateBounds(TPoint.Create(SourceRect.P1.X + Diff.X, SourceRect.P1.Y + Diff.Y),
     1858    TPoint.Create(Trunc(DestRect.Size.X / Zoom),
     1859    Trunc(DestRect.Size.Y / Zoom)));
    18651860end;
    18661861
     
    19841979    Node2 := Node3.FirstChild;
    19851980    while Assigned(Node2) and (Node2.NodeName = 'Point') do begin
    1986       Polygon.AddPoint(Point(ReadInteger(Node2, 'X', 0), ReadInteger(Node2, 'Y', 0)));
     1981      Polygon.AddPoint(TPoint.Create(ReadInteger(Node2, 'X', 0), ReadInteger(Node2, 'Y', 0)));
    19871982      Node2 := Node2.NextSibling;
    19881983    end;
     
    20342029function TCell.IsVisible(View: TView): Boolean;
    20352030var
    2036   RectA, RectB: TRect;
    2037 begin
    2038   RectA := Polygon.GetRect;
    2039   RectB := View.SourceRect;
    2040   Result := ((RectA.Left < RectB.Right) and (RectA.Right > RectB.Left) and
    2041     (RectA.Top < RectB.Bottom) and (RectA.Bottom > RectB.Top));
     2031  RectPolygon, RectView: TRect;
     2032begin
     2033  RectPolygon := Polygon.GetRect;
     2034  RectView := View.SourceRect;
     2035  Result := (
     2036    (RectPolygon.P1.X < RectView.P2.X) and
     2037    (RectPolygon.P2.X > RectView.P1.X) and
     2038    (RectPolygon.P1.Y < RectView.P2.Y) and
     2039    (RectPolygon.P2.Y > RectView.P1.Y)
     2040  );
    20422041end;
    20432042
     
    21082107function TView.CanvasToCellPos(Pos: TPoint): TPoint;
    21092108begin
    2110   Result := Point(Trunc(Pos.X / Zoom + SourceRect.Left),
    2111     Trunc(Pos.Y / Zoom + SourceRect.Top));
     2109  Result := TPoint.Create(Trunc(Pos.X / Zoom + SourceRect.P1.X),
     2110    Trunc(Pos.Y / Zoom + SourceRect.P1.Y));
    21122111end;
    21132112
    21142113function TView.CellToCanvasPos(Pos: TPoint): TPoint;
    21152114begin
    2116   Result := Point(Trunc((Pos.X - SourceRect.Left) * Zoom),
    2117     Trunc((Pos.Y - SourceRect.Top) * Zoom));
     2115  Result := TPoint.Create(Trunc((Pos.X - SourceRect.P1.X) * Zoom),
     2116    Trunc((Pos.Y - SourceRect.P1.Y) * Zoom));
    21182117end;
    21192118
    21202119function TView.CanvasToCellRect(Pos: TRect): TRect;
    21212120begin
    2122   Result.TopLeft := CanvasToCellPos(Pos.TopLeft);
    2123   Result.BottomRight := CanvasToCellPos(Pos.BottomRight);
     2121  Result.P1 := CanvasToCellPos(Pos.P1);
     2122  Result.P2 := CanvasToCellPos(Pos.P2);
    21242123end;
    21252124
    21262125function TView.CellToCanvasRect(Pos: TRect): TRect;
    21272126begin
    2128   Result.TopLeft := CellToCanvasPos(Pos.TopLeft);
    2129   Result.BottomRight := CellToCanvasPos(Pos.BottomRight);
     2127  Result.P1 := CellToCanvasPos(Pos.P1);
     2128  Result.P2 := CellToCanvasPos(Pos.P2);
    21302129end;
    21312130
     
    25782577begin
    25792578  MapRect := Game.Map.PixelRect;
    2580   SourceRect := Bounds(MapRect.Left + (MapRect.Right - MapRect.Left) div 2 - (SourceRect.Right - SourceRect.Left) div 2,
    2581     MapRect.Top + (MapRect.Bottom - MapRect.Top) div 2 - (SourceRect.Bottom - SourceRect.Top) div 2,
    2582     SourceRect.Right - SourceRect.Left,
    2583     SourceRect.Bottom - SourceRect.Top);
     2579  SourceRect := TRect.CreateBounds(TPoint.Create(MapRect.P1.X + MapRect.Size.X div 2 - SourceRect.Size.X div 2,
     2580    MapRect.P1.Y + MapRect.Size.Y div 2 - SourceRect.Size.Y div 2),
     2581    TPoint.Create(SourceRect.Size.X,
     2582    SourceRect.Size.Y));
    25842583end;
    25852584
    25862585procedure TView.CenterPlayerCity(Player: TPlayer);
    25872586begin
    2588   SourceRect := Bounds(Player.StartCell.PosPx.X - (SourceRect.Right - SourceRect.Left) div 2,
    2589     Player.StartCell.PosPx.Y - (SourceRect.Bottom - SourceRect.Top) div 2,
    2590     SourceRect.Right - SourceRect.Left,
    2591     SourceRect.Bottom - SourceRect.Top);
     2587  SourceRect := TRect.CreateBounds(TPoint.Create(Player.StartCell.PosPx.X - SourceRect.Size.X div 2,
     2588    Player.StartCell.PosPx.Y - SourceRect.Size.Y div 2),
     2589    TPoint.Create(SourceRect.Size.X,
     2590    SourceRect.Size.Y));
    25922591end;
    25932592
     
    32473246  with Config do begin
    32483247    MapType := TMapType(GetValue(DOMString(Path + '/GridType'), Integer(mtHexagon)));
    3249     Map.Size := Point(GetValue(DOMString(Path + '/MapSizeX'), 10),
     3248    Map.Size := TPoint.Create(GetValue(DOMString(Path + '/MapSizeX'), 10),
    32503249      GetValue(DOMString(Path + '/MapSizeY'), 10));
    32513250    MapImageFileName := string(GetValue(DOMString(Path + '/MapImage'), DOMString(MapImageFileName)));
     
    35083507
    35093508  Map.Game := Self;
    3510   Map.Size := Point(3, 3);
     3509  Map.Size := TPoint.Create(3, 3);
    35113510end;
    35123511
     
    36013600    with CellLink do begin
    36023601      if Length(Points) >= 2 then begin
    3603         MoveTo(View.CellToCanvasPos(Points[0]));
     3602        MoveTo(PointToStdPoint(View.CellToCanvasPos(Points[0])));
    36043603        for I := 1 to Length(Points) - 1 do
    3605           LineTo(View.CellToCanvasPos(Points[I]));
     3604          LineTo(PointToStdPoint(View.CellToCanvasPos(Points[I])));
    36063605      end;
    36073606    end;
     
    36303629      Angle := ArcTan((PosTo.Y - PosFrom.Y) / (PosTo.X - PosFrom.X));
    36313630      if Sign(PosTo.X - PosFrom.X) = -1 then Angle := Angle + Pi;
    3632       ArrowCenter := View.CellToCanvasPos(Point(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 2),
     3631      ArrowCenter := View.CellToCanvasPos(TPoint.Create(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 2),
    36333632        Trunc(PosFrom.Y + (PosTo.Y - PosFrom.Y) / 2)));
    36343633      DrawArrow(Canvas, View, ArrowCenter,
  • trunk/UMap.pas

    r168 r170  
    66
    77uses
    8   Classes, SysUtils, UGame, XMLRead, XMLWrite, DOM, Contnrs, UGeometry;
     8  Classes, SysUtils, UGame, XMLRead, XMLWrite, DOM, Contnrs, UGeometryClasses,
     9  UGeometry;
    910
    1011type
     
    5354  TVoronoiMap = class(TMap)
    5455  private
    55     function GetTrianglePolygon(Pos: TPoint; Size: TPoint; Reverse: Boolean): TPointArray;
    5656  public
    5757    procedure Generate; override;
     
    6868  Shift := FloatPoint(0.5 * cos(30 / 180 * Pi), 0.5 * sin(30 / 180 * Pi));
    6969  SetLength(Result.Points, 6);
    70   Result.Points[0] := Point(Trunc(Pos.X + 0 * Size.X), Trunc(Pos.Y - 0.5 * Size.Y));
    71   Result.Points[1] := Point(Trunc(Pos.X + Shift.X * Size.X), Trunc(Pos.Y - Shift.Y * Size.Y));
    72   Result.Points[2] := Point(Trunc(Pos.X + Shift.X * Size.X), Trunc(Pos.Y + Shift.Y * Size.Y));
    73   Result.Points[3] := Point(Trunc(Pos.X + 0 * Size.X), Trunc(Pos.Y + 0.5 * Size.Y));
    74   Result.Points[4] := Point(Trunc(Pos.X - Shift.X * Size.X), Trunc(Pos.Y + Shift.Y * Size.Y));
    75   Result.Points[5] := Point(Trunc(Pos.X - Shift.X * Size.X), Trunc(Pos.Y - Shift.Y * Size.Y));
     70  Result.Points[0] := TPoint.Create(Trunc(Pos.X + 0 * Size.X), Trunc(Pos.Y - 0.5 * Size.Y));
     71  Result.Points[1] := TPoint.Create(Trunc(Pos.X + Shift.X * Size.X), Trunc(Pos.Y - Shift.Y * Size.Y));
     72  Result.Points[2] := TPoint.Create(Trunc(Pos.X + Shift.X * Size.X), Trunc(Pos.Y + Shift.Y * Size.Y));
     73  Result.Points[3] := TPoint.Create(Trunc(Pos.X + 0 * Size.X), Trunc(Pos.Y + 0.5 * Size.Y));
     74  Result.Points[4] := TPoint.Create(Trunc(Pos.X - Shift.X * Size.X), Trunc(Pos.Y + Shift.Y * Size.Y));
     75  Result.Points[5] := TPoint.Create(Trunc(Pos.X - Shift.X * Size.X), Trunc(Pos.Y - Shift.Y * Size.Y));
    7676end;
    7777
     
    139139  for Y := -1 to 1 do
    140140  for X := -1 to 1 do
    141   if IsValidIndex(Point(CellPos.X + X, CellPos.Y + Y)) and
    142   IsCellsPosNeighbor(CellPos, Point((CellPos.X + X), (CellPos.Y + Y))) then begin
     141  if IsValidIndex(TPoint.Create(CellPos.X + X, CellPos.Y + Y)) and
     142  IsCellsPosNeighbor(CellPos, TPoint.Create((CellPos.X + X), (CellPos.Y + Y))) then begin
    143143    Neighbours.Add(TCell(Cells[(CellPos.Y + Y) * Size.X + (CellPos.X + X)]));
    144144  end;
     
    165165      //Y := Y + 0.5;
    166166    end;
    167     NewCell.PosPx := Point(Trunc(PX * DefaultCellSize.X / HexCellMulX),
     167    NewCell.PosPx := TPoint.Create(Trunc(PX * DefaultCellSize.X / HexCellMulX),
    168168      Trunc(PY * DefaultCellSize.Y / HexCellMulY));
    169169    NewCell.Polygon := GetHexagonPolygon(NewCell.PosPx, DefaultCellSize);
     
    176176  for X := 0 to Size.X - 1 do
    177177  with TCell(Cells[Y * Size.X + X]) do begin
    178     GetCellPosNeighbors(Point(X, Y), Neighbors);
     178    GetCellPosNeighbors(TPoint.Create(X, Y), Neighbors);
    179179  end;
    180180
     
    198198    NewCell := TCell.Create;
    199199    NewCell.Map := Self;
    200     NewCell.PosPx := Point(Trunc(X * DefaultCellSize.X * SquareCellMulX),
     200    NewCell.PosPx := TPoint.Create(Trunc(X * DefaultCellSize.X * SquareCellMulX),
    201201      Trunc(Y * DefaultCellSize.Y * SquareCellMulY));
    202202    NewCell.Polygon := GetSquarePolygon(NewCell.PosPx, DefaultCellSize);
     
    209209  for X := 0 to Size.X - 1 do
    210210  with TCell(Cells[Y * Size.X + X]) do begin
    211     if IsValidIndex(Point(X + 1, Y + 0)) then
     211    if IsValidIndex(TPoint.Create(X + 1, Y + 0)) then
    212212      Neighbors.Add(TCell(Cells[(Y + 0) * Size.X + (X + 1)]));
    213     if IsValidIndex(Point(X + 0, Y + 1)) then
     213    if IsValidIndex(TPoint.Create(X + 0, Y + 1)) then
    214214      Neighbors.Add(TCell(Cells[(Y + 1) * Size.X + (X + 0)]));
    215     if IsValidIndex(Point(X - 1, Y + 0)) then
     215    if IsValidIndex(TPoint.Create(X - 1, Y + 0)) then
    216216      Neighbors.Add(TCell(Cells[(Y + 0) * Size.X + (X - 1)]));
    217     if IsValidIndex(Point(X + 0, Y - 1)) then
     217    if IsValidIndex(TPoint.Create(X + 0, Y - 1)) then
    218218      Neighbors.Add(TCell(Cells[(Y - 1) * Size.X + (X + 0)]));
    219219  end;
     
    231231begin
    232232  SetLength(Result.Points, 4);
    233   Result.Points[0] := Point(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y - Size.Y / 2));
    234   Result.Points[1] := Point(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y - Size.Y / 2));
    235   Result.Points[2] := Point(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y + Size.Y / 2));
    236   Result.Points[3] := Point(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y + Size.Y / 2));
     233  Result.Points[0] := TPoint.Create(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y - Size.Y / 2));
     234  Result.Points[1] := TPoint.Create(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y - Size.Y / 2));
     235  Result.Points[2] := TPoint.Create(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y + Size.Y / 2));
     236  Result.Points[3] := TPoint.Create(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y + Size.Y / 2));
    237237end;
    238238
    239239{ TVoronoiMap }
    240 
    241 function TVoronoiMap.GetTrianglePolygon(Pos: TPoint; Size: TPoint;
    242   Reverse: Boolean): TPointArray;
    243 begin
    244   SetLength(Result, 0);
    245 end;
    246240
    247241function CompareDistance(C1, C2: Pointer): Integer;
     
    309303    NewCell := TCell.Create;
    310304    NewCell.Map := Self;
    311     NewCell.PosPx := Point(Trunc(Random * Size.X * DefaultCellSize.X),
     305    NewCell.PosPx := TPoint.Create(Trunc(Random * Size.X * DefaultCellSize.X),
    312306      Trunc(Random * Size.Y * DefaultCellSize.Y));
    313307    SetLength(NewCell.Polygon.Points, 1);
     
    324318    NewCellDist.Cell1 := Cells[I1];
    325319    NewCellDist.Cell2 := Cells[I2];
    326     NewCellDist.Distance := Distance(NewCellDist.Cell1.PosPx, NewCellDist.Cell2.PosPx);
     320    NewCellDist.Distance := TLine.Create(NewCellDist.Cell1.PosPx, NewCellDist.Cell2.PosPx).Distance;
    327321    CellsDistance.Add(NewCellDist);
    328322  end;
     
    344338      L2 := TLine.Create(TCellsDistance(SelectedCells[J]).Cell1.PosPx,
    345339        TCellsDistance(SelectedCells[J]).Cell2.PosPx);
    346       if LineIntersect(L1, L2, Intersection) then begin
    347         if PointInRect(Intersection, L1.ToRect) and
    348         PointInRect(Intersection, L2.ToRect) then begin
     340      if TLine.LineIntersect(L1, L2, Intersection) then begin
     341        if L1.ToRect.IsPointInside(Intersection) and
     342        L2.ToRect.IsPointInside(Intersection) then begin
    349343          Intersected := True;
    350344          Break;
     
    423417    // Use whole map first for cell polygon
    424418    if Cell.Neighbors.Count > 0 then begin
    425       Polygon := TPolygon.Create(Rect(0, 0,
    426         Size.X * DefaultCellSize.X, Size.Y * DefaultCellSize.Y));
     419      Polygon := TPolygon.Create(TRect.Create(TPoint.Create(0, 0),
     420        TPoint.Create(Size.X * DefaultCellSize.X, Size.Y * DefaultCellSize.Y)));
    427421      for NeighborCell in Cell.Neighbors do begin
    428422        LinkLine := TLine.Create(Cell.PosPx, NeighborCell.PosPx);
     
    430424        MP := LinkLine.GetMiddle;
    431425        // Create half plane vector
    432         L1 := TLine.Create(MP, Point(MP.X + LinkLine.GetSize.X,
     426        L1 := TLine.Create(MP, TPoint.Create(MP.X + LinkLine.GetSize.X,
    433427          MP.Y + LinkLine.GetSize.Y));
    434428
     
    452446    else Rev := 1;
    453447  SetLength(Result.Points, 3);
    454   Result.Points[0] := Point(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y - (Size.Y * 0.8) / 2 * Rev));
    455   Result.Points[1] := Point(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y - (Size.Y * 0.8) / 2 * Rev));
    456   Result.Points[2] := Point(Trunc(Pos.X), Trunc(Pos.Y + (Size.Y * 1.2) / 2 * Rev));
     448  Result.Points[0] := TPoint.Create(Trunc(Pos.X - Size.X / 2), Trunc(Pos.Y - (Size.Y * 0.8) / 2 * Rev));
     449  Result.Points[1] := TPoint.Create(Trunc(Pos.X + Size.X / 2), Trunc(Pos.Y - (Size.Y * 0.8) / 2 * Rev));
     450  Result.Points[2] := TPoint.Create(Trunc(Pos.X), Trunc(Pos.Y + (Size.Y * 1.2) / 2 * Rev));
    457451end;
    458452
     
    481475    if Reverse then Rev := -1
    482476      else Rev := 1;
    483     NewCell.PosPx := Point(Trunc(X * DefaultCellSize.X * TriangleCellMulX),
     477    NewCell.PosPx := TPoint.Create(Trunc(X * DefaultCellSize.X * TriangleCellMulX),
    484478      Trunc((Y * DefaultCellSize.Y * TriangleCellMulY) - (0.1 * Rev * DefaultCellSize.Y)));
    485479    NewCell.Polygon := GetTrianglePolygon(NewCell.PosPx, DefaultCellSize, Reverse);
     
    494488    if Boolean(X mod 2) xor Boolean(Y mod 2) then Rev := -1
    495489      else Rev := 1;
    496     if IsValidIndex(Point(X + 1, Y + 0)) then
     490    if IsValidIndex(TPoint.Create(X + 1, Y + 0)) then
    497491      Neighbors.Add(TCell(Cells[(Y + 0) * Size.X + (X + 1)]));
    498     if IsValidIndex(Point(X + 0, Y - 1 * Rev)) then
     492    if IsValidIndex(TPoint.Create(X + 0, Y - 1 * Rev)) then
    499493      Neighbors.Add(TCell(Cells[(Y - 1 * Rev) * Size.X + (X + 0)]));
    500     if IsValidIndex(Point(X - 1, Y + 0)) then
     494    if IsValidIndex(TPoint.Create(X - 1, Y + 0)) then
    501495      Neighbors.Add(TCell(Cells[(Y + 0) * Size.X + (X - 1)]));
    502496  end;
  • trunk/xtactics.lpr

    r165 r170  
    1111  CoolTranslator, TemplateGenerics, UFormPlayer
    1212  { you can add units after this },
    13   SysUtils, UFormMain, UFormMove, UFormNew, UFormCharts, UFormUnitMoves;
     13  SysUtils, UFormMain, UFormMove, UFormNew, UFormCharts, UFormUnitMoves, UGeometryClasses;
    1414
    1515{$R *.res}
Note: See TracChangeset for help on using the changeset viewer.