Changeset 164
- Timestamp:
- Nov 21, 2017, 6:39:06 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/Common/Common.lpk
r91 r164 4 4 <PathDelim Value="\"/> 5 5 <Name Value="Common"/> 6 <Type Value="RunAndDesignTime"/> 6 7 <AddToProjectUsesSection Value="True"/> 7 8 <Author Value="Chronos (robie@centrum.cz)"/> … … 16 17 <License Value="GNU/GPL"/> 17 18 <Version Minor="7"/> 18 <Files Count="2 0">19 <Files Count="21"> 19 20 <Item1> 20 21 <Filename Value="StopWatch.pas"/> … … 105 106 <UnitName Value="UScaleDPI"/> 106 107 </Item20> 108 <Item21> 109 <Filename Value="UGeometry.pas"/> 110 <UnitName Value="UGeometry"/> 111 </Item21> 107 112 </Files> 108 113 <i18n> … … 110 115 <OutDir Value="Languages"/> 111 116 </i18n> 112 <Type Value="RunAndDesignTime"/>113 117 <RequiredPkgs Count="2"> 114 118 <Item1> -
trunk/Packages/Common/Common.pas
r91 r164 11 11 UMemory, UResetableThread, UPool, ULastOpenedList, URegistry, 12 12 UJobProgressView, UXMLUtils, UApplicationInfo, USyncCounter, UListViewSort, 13 UPersistentForm, UFindFile, UScaleDPI, LazarusPackageIntf;13 UPersistentForm, UFindFile, UScaleDPI, UGeometry, LazarusPackageIntf; 14 14 15 15 implementation -
trunk/UGame.pas
r162 r164 174 174 private 175 175 FSize: TPoint; 176 FUpdateCount: Integer; 176 177 function GetSize: TPoint; virtual; 177 178 procedure PaintCell(Canvas: TCanvas; Pos: TPoint; Text: string; View: TView; … … 213 214 procedure CreateLinks; 214 215 procedure Clear; 216 procedure BeginUpdate; 217 procedure EndUpdate; 215 218 constructor Create; virtual; 216 219 destructor Destroy; override; … … 982 985 CellText: string; 983 986 CellLink: TCellLink; 987 NeighCell: TCell; 984 988 begin 985 989 with Canvas, View do … … 1028 1032 Player.Game.Map.PaintCell(Canvas, Cell.MapCell.PosPx, '', View, Cell.MapCell); 1029 1033 end; 1034 1035 {// Draw links to neighbors 1036 for NeighCell in Cell.MapCell.Neighbors do begin 1037 Pen.Color := clYellow; 1038 MoveTo(View.CellToCanvasPos(Cell.MapCell.PosPx)); 1039 LineTo(View.CellToCanvasPos(NeighCell.PosPx)); 1040 end; 1041 } 1030 1042 end; 1031 1043 … … 1340 1352 if (FSize.X <> AValue.X) or (FSize.Y <> AValue.Y) then begin 1341 1353 FSize := AValue; 1342 Generate;1354 if FUpdateCount = 0 then Generate; 1343 1355 end; 1344 1356 end; … … 1434 1446 // I: Integer; 1435 1447 begin 1448 FUpdateCount := Source.FUpdateCount; 1436 1449 MaxPower := Source.MaxPower; 1437 1450 Game := Source.Game; … … 1713 1726 Cells.Clear; 1714 1727 FNewCellId := 1; 1728 end; 1729 1730 procedure TMap.BeginUpdate; 1731 begin 1732 Inc(FUpdateCount); 1733 end; 1734 1735 procedure TMap.EndUpdate; 1736 begin 1737 if FUpdateCount > 0 then Dec(FUpdateCount); 1738 if FUpdateCount = 0 then Generate; 1715 1739 end; 1716 1740 … … 3217 3241 begin 3218 3242 with Config do begin 3219 MapType := TMapType(GetValue(DOMString(Path + '/GridType'), Integer(mtHexagon))); 3243 try 3244 Map.BeginUpdate; 3245 MapType := TMapType(GetValue(DOMString(Path + '/GridType'), Integer(mtHexagon))); 3246 Map.Size := Point(GetValue(DOMString(Path + '/MapSizeX'), 10), 3247 GetValue(DOMString(Path + '/MapSizeY'), 10)); 3248 finally 3249 Map.EndUpdate; 3250 end; 3220 3251 MapImageFileName := string(GetValue(DOMString(Path + '/MapImage'), DOMString(MapImageFileName))); 3221 3252 SymetricMap := GetValue(DOMString(Path + '/SymetricMap'), False); … … 3223 3254 VoidEnabled := GetValue(DOMString(Path + '/VoidEnabled'), True); 3224 3255 VoidPercentage := GetValue(DOMString(Path + '/VoidPercentage'), 20); 3225 Map.Size := Point(GetValue(DOMString(Path + '/MapSizeX'), 10),3226 GetValue(DOMString(Path + '/MapSizeY'), 10));3227 3256 Value := GetValue(DOMString(Path + '/MapShape'), 0); 3228 3257 if (Value >= Integer(Low(TMapShape))) and (Value <= Integer(High(TMapShape))) then -
trunk/UMap.pas
r162 r164 6 6 7 7 uses 8 Classes, SysUtils, UGame, XMLRead, XMLWrite, DOM, Contnrs ;8 Classes, SysUtils, UGame, XMLRead, XMLWrite, DOM, Contnrs, UGeometry; 9 9 10 10 type … … 245 245 end; 246 246 247 function Distance(P1, P2: TPoint): Double;248 begin249 Result := Sqrt(Sqr(P2.X - P1.X) + Sqr(P2.Y - P1.Y));250 end;251 252 function SubPoint(const P1, P2: TPoint): TPoint;253 begin254 Result.X := P1.X - P2.X;255 Result.Y := P1.Y - P2.Y;256 end;257 258 function LineIntersect(LineAP1, LineAP2, LineBP1, LineBP2: TPoint): TPoint;259 Var260 LDetLineA, LDetLineB, LDetDivInv: Double;261 LDiffLA, LDiffLB: TPoint;262 begin263 LDetLineA := LineAP1.X * LineAP2.Y - LineAP1.Y * LineAP2.X;264 LDetLineB := LineBP1.X * LineBP2.Y - LineBP1.Y * LineBP2.X;265 266 LDiffLA := SubPoint(LineAP1, LineAP2);267 LDiffLB := SubPoint(LineBP1, LineBP2);268 269 LDetDivInv := 1 / ((LDiffLA.X * LDiffLB.Y) - (LDiffLA.Y * LDiffLB.X));270 271 Result.X := Trunc(((LDetLineA * LDiffLB.X) - (LDiffLA.X * LDetLineB)) * LDetDivInv);272 Result.Y := Trunc(((LDetLineA * LDiffLB.Y) - (LDiffLA.Y * LDetLineB)) * LDetDivInv);273 end;274 275 247 function CompareDistance(C1, C2: Pointer): Integer; 276 248 begin … … 280 252 end; 281 253 282 function PointInRect(aPoint: TPoint; aRect: TRect): Boolean; 283 begin 284 Result := (aPoint.X >= aRect.Left) and (aPoint.X < aRect.Right) and 285 (aPoint.Y >= aRect.Top) and(aPoint.Y < aRect.Bottom); 254 function CompareDistanceReverse(C1, C2: Pointer): Integer; 255 begin 256 if TCellsDistance(C1).Distance > TCellsDistance(C2).Distance then Result := -1 257 else if TCellsDistance(C1).Distance < TCellsDistance(C2).Distance then Result := 1 258 else Result := 0; 286 259 end; 287 260 … … 293 266 CellsDistance: TObjectList; // TObjectList<TCellsDistance> 294 267 NewCellDist: TCellsDistance; 268 SelectedCells: TObjectList; // TObjectList<TCellsDistance> 295 269 I, J: Integer; 296 270 Intersected: Boolean; 297 271 Intersection: TPoint; 272 CellDistance: TCellsDistance; 273 R1, R2: TRect; 274 Cell: TCell; 275 CellsAngle: TObjectList; // TObjecTList<TCellsDistance> 276 CellAngle: TCellsDistance; 277 NextCellAngle: TCellsDistance; 278 L1, L2: TLine; 279 MP: TPoint; 280 LinkLine: TLine; 281 Polygon: TPolygon; 298 282 begin 299 283 Clear; … … 313 297 end; 314 298 315 {// Calculate distance between all cells299 // Calculate distance between all cells 316 300 CellsDistance := TObjectList.Create; 317 301 for I1 := 1 to Cells.Count - 1 do … … 323 307 CellsDistance.Add(NewCellDist); 324 308 end; 325 CellsDistance.Sort(CompareDistance );309 CellsDistance.Sort(CompareDistanceReverse); 326 310 327 311 // Keep shortest non-intersected cell pairs 328 I := 0; 329 while I < CellsDistance.Count do begin 330 Intersected := True; 331 for J := 0 to CellsDistance.Count - 1 do 332 Intersection := LineIntersect(TCellsDistance(CellsDistance[I]).Cell1.PosPx, 333 TCellsDistance(CellsDistance[I]).Cell2.PosPx, 334 TCellsDistance(CellsDistance[J]).Cell1.PosPx, 335 TCellsDistance(CellsDistance[J]).Cell1.PosPx); 336 if PointInRect(Intersection, Rect(TCellsDistance(CellsDistance[I]).Cell1.PosPx.X, 337 TCellsDistance(CellsDistance[I]).Cell1.PosPx.Y, 338 then begin 339 Intersected := False; 340 Break; 312 SelectedCells := TObjectList.Create; 313 SelectedCells.OwnsObjects := False; 314 I := CellsDistance.Count - 1; 315 while I >= 0 do begin 316 Intersected := False; 317 for J := 0 to SelectedCells.Count - 1 do 318 if (TCellsDistance(SelectedCells[J]).Cell1 <> TCellsDistance(CellsDistance[I]).Cell1) 319 and (TCellsDistance(SelectedCells[J]).Cell2 <> TCellsDistance(CellsDistance[I]).Cell2) 320 and (TCellsDistance(SelectedCells[J]).Cell1 <> TCellsDistance(CellsDistance[I]).Cell2) 321 and (TCellsDistance(SelectedCells[J]).Cell2 <> TCellsDistance(CellsDistance[I]).Cell1) then begin 322 L1 := TLine.Create(TCellsDistance(CellsDistance[I]).Cell1.PosPx, 323 TCellsDistance(CellsDistance[I]).Cell2.PosPx); 324 L2 := TLine.Create(TCellsDistance(SelectedCells[J]).Cell1.PosPx, 325 TCellsDistance(SelectedCells[J]).Cell2.PosPx); 326 if LineIntersect(L1, L2, Intersection) then begin 327 R1 := PointsToRect(TCellsDistance(CellsDistance[I]).Cell1.PosPx, 328 TCellsDistance(CellsDistance[I]).Cell2.PosPx); 329 R2 := PointsToRect(TCellsDistance(SelectedCells[J]).Cell1.PosPx, 330 TCellsDistance(SelectedCells[J]).Cell2.PosPx); 331 if PointInRect(Intersection, R1) and PointInRect(Intersection, R2) then begin 332 Intersected := True; 333 Break; 334 end; 341 335 end; 342 if Intersected then begin 343 CellsDistance.Delete(I); 344 end else Inc(I); 345 end; 336 end; 337 if not Intersected then SelectedCells.Add(CellsDistance[I]); 338 Dec(I); 339 end; 340 341 // Add cell neighbors 342 for I := 0 to SelectedCells.Count - 1 do begin 343 CellDistance := TCellsDistance(SelectedCells[I]); 344 CellDistance.Cell1.Neighbors.Add(CellDistance.Cell2); 345 CellDistance.Cell2.Neighbors.Add(CellDistance.Cell1); 346 end; 347 348 FreeAndNil(SelectedCells); 346 349 FreeAndNil(CellsDistance); 347 } 350 351 // Compute polygon around cells with sequence sorted by link angle 352 for Cell in Cells do begin 353 CellsAngle := TObjectList.Create; 354 for I := 0 to Cell.Neighbors.Count - 1 do begin 355 CellAngle := TCellsDistance.Create; 356 CellAngle.Cell1 := Cell; 357 CellAngle.Cell2 := TCell(Cell.Neighbors[I]); 358 CellAngle.Distance := ArcTan2Point(Point( 359 CellAngle.Cell2.PosPx.X - CellAngle.Cell1.PosPx.X, 360 CellAngle.Cell2.PosPx.Y - CellAngle.Cell1.PosPx.Y)); 361 CellsAngle.Add(CellAngle); 362 end; 363 CellsAngle.Sort(CompareDistance); 364 365 // Use whole map first for cell polygon 366 if CellsAngle.Count > 0 then begin 367 Polygon := TPolygon.Create(Rect(0, 0, 368 Size.X * DefaultCellSize.X, Size.Y * DefaultCellSize.Y)); 369 for I := 0 to CellsAngle.Count - 1 do begin 370 CellAngle := TCellsDistance(CellsAngle[I]); 371 LinkLine := TLine.Create(CellAngle.Cell1.PosPx, 372 CellAngle.Cell2.PosPx); 373 MP := LinkLine.GetMiddle; 374 // Create half plane vector 375 L1 := TLine.Create(MP, Point(MP.X + LinkLine.GetSize.X, MP.Y + LinkLine.GetSize.Y)); 376 377 Polygon.CutLine(L1, Cell.PosPx); 378 end; 379 Cell.Polygon := Polygon.Points; 380 end else SetLength(Cell.Polygon, 0); 381 382 FreeAndNil(CellsAngle); 383 end; 384 348 385 FPixelRect := CalculatePixelRect; 349 386 end;
Note:
See TracChangeset
for help on using the changeset viewer.