12internal sealed class IsometricAxialCoordinates : ISceneLayerCoordinates
15 private static void WH(SceneLayer m, out
int W, out
int H, out
float halfW, out
float halfH)
29 public Point GetAnchorPixelAtSceneLayerCoordinates(SceneLayer sceneLayer, PointF gp)
31 WH(sceneLayer, out
int W, out _, out
float halfW, out
float halfH);
36 float px = -originX + gp.X *
W + gp.Y * halfW;
37 float py = -originY + gp.Y * halfH;
39 return new Point((
int)Math.Floor(px), (
int)Math.Floor(py));
48 public PointF GetSceneLayerCoordinatesAtPixel(SceneLayer sceneLayer, PointF pixelPt)
50 WH(sceneLayer, out
int W, out _, out
float halfW, out
float halfH);
55 float gyF = (pixelPt.Y + originY) / halfH;
56 float gxF = (pixelPt.X + originX - gyF * halfW) /
W;
58 return new PointF(gxF, gyF);
68 public List<SceneLayerTile> GetSceneLayerTilesInPixelRange(SceneLayer sceneLayer, Rectangle worldPixelRange,
bool includeOverhang)
70 var result =
new List<SceneLayerTile>();
71 WH(sceneLayer, out _, out _, out _, out _);
72 var candidateRange = TileBounds.GetTransformedTileCandidateRange(sceneLayer, worldPixelRange, includeOverhang);
75 var ul = GetSceneLayerCoordinatesAtPixel(sceneLayer,
new PointF(candidateRange.Left, candidateRange.Top));
76 var ur = GetSceneLayerCoordinatesAtPixel(sceneLayer,
new PointF(candidateRange.Right, candidateRange.Top));
77 var ll = GetSceneLayerCoordinatesAtPixel(sceneLayer,
new PointF(candidateRange.Left, candidateRange.Bottom));
78 var lr = GetSceneLayerCoordinatesAtPixel(sceneLayer,
new PointF(candidateRange.Right, candidateRange.Bottom));
80 int minX = (int)System.Math.Floor(System.Math.Min(System.Math.Min(ul.X, ur.X), System.Math.Min(ll.X, lr.X))) - 2;
81 int maxX = (int)System.Math.Ceiling(System.Math.Max(System.Math.Max(ul.X, ur.X), System.Math.Max(ll.X, lr.X))) + 2;
82 int minY = (int)System.Math.Floor(System.Math.Min(System.Math.Min(ul.Y, ur.Y), System.Math.Min(ll.Y, lr.Y))) - 2;
83 int maxY = (int)System.Math.Ceiling(System.Math.Max(System.Math.Max(ul.Y, ur.Y), System.Math.Max(ll.Y, lr.Y))) + 2;
89 int xStart = System.Math.Max(minX, 0);
90 int xEnd = System.Math.Min(maxX, cols - 1);
91 int yStart = System.Math.Max(minY, 0);
92 int yEnd = System.Math.Min(maxY, rows - 1);
93 if (xStart > xEnd || yStart > yEnd)
return result;
95 for (
int y = yStart; y <= yEnd; y++)
97 for (
int x = xStart; x <= xEnd; x++)
99 var gp = sceneLayer[x, y];
100 if (gp ==
null)
continue;
102 var r = GetPixelRangeForTile(gp, includeOverhang);
103 if (r.IntersectsWith(worldPixelRange)) result.Add(gp);
115 public Rectangle GetPixelRangeForTile(Tile tile,
bool includeOverhang)
117 WH(tile.SceneLayer, out
int W, out
int H, out
float halfW, out _);
120 var top = GetAnchorPixelAtSceneLayerCoordinates(tile.SceneLayer, tile.SceneLayerCoordinates);
123 var rect =
new Rectangle(top.X - (
int)halfW, top.Y,
W, H);
124 return TileBounds.ApplyTileGeometry(rect, tile, includeOverhang);
133 public Rectangle GetPixelRangeForTileList(List<Tile> tileList,
bool includeOverhang)
136 foreach (var t
in tileList)
138 var r = GetPixelRangeForTile(t, includeOverhang);
139 ret = ret.IsEmpty ? r :
Rectangle.Union(ret, r);
150 public SceneLayerTile GetAdjacentSceneLayerTile(SceneLayerTile gp,
CardinalDirections dir)
156 CardinalDirections.N => m.ResolveWrappedTile(x, y - 1),
157 CardinalDirections.S => m.ResolveWrappedTile(x, y + 1),
158 CardinalDirections.E => m.ResolveWrappedTile(x + 1, y),
159 CardinalDirections.W => m.ResolveWrappedTile(x - 1, y),
160 CardinalDirections.NE => m.ResolveWrappedTile(x + 1, y - 1),
161 CardinalDirections.NW => m.ResolveWrappedTile(x - 1, y - 1),
162 CardinalDirections.SE => m.ResolveWrappedTile(x + 1, y + 1),
163 CardinalDirections.SW => m.ResolveWrappedTile(x - 1, y + 1),
174 public Point[] GetPolygonPts(Tile tile,
bool includeOverhang)
176 WH(tile.SceneLayer, out
int W, out
int H, out _, out _);
177 var top = GetAnchorPixelAtSceneLayerCoordinates(tile.SceneLayer, tile.SceneLayerCoordinates);
178 var oh = includeOverhang ? tile.Overhang :
Spacing.None;
183 new Point(top.X, top.Y - oh.Top),
184 new Point(top.X +
W/2 + oh.Right, top.Y + H/2),
185 new Point(top.X, top.Y + H + oh.Bottom),
186 new Point(top.X -
W/2 - oh.Left, top.Y + H/2)
197 public PointF FindEquivalentSceneLayerCoordinates(PointF valColRow,
int xUpperBound,
int yUpperBound)
200 float modX = valColRow.X % (xUpperBound + 1);
201 float modY = valColRow.Y % (yUpperBound + 1);
202 if (modX < 0) modX += xUpperBound + 1;
203 if (modY < 0) modY += yUpperBound + 1;
204 return new PointF(modX, modY);
Point GridCoordinatesAbs
Gets the absolute grid coordinates of this tile within its parent scene layer as integer values.
override SceneLayer SceneLayer
Gets the parent scene layer that contains this tile.
Point OriginPx
Gets or sets the world-space pixel origin of this layer's (0,0) tile position.
int GridRowCount
Gets the number of rows (tiles high) in this layer's grid.
int TileHeight
Gets or sets the height of each tile in this layer, measured in pixels.
int GridColumnCount
Gets the number of columns (tiles wide) in this layer's grid.
int TileWidth
Gets or sets the width of each tile in this layer, measured in pixels.
CardinalDirections
Represents the eight cardinal and intercardinal directions of the compass.
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
record struct Spacing([property:JsonProperty("left")] int Left, [property:JsonProperty("top")] int Top, [property:JsonProperty("right")] int Right, [property:JsonProperty("bottom")] int Bottom)
Represents dimensions in pixels when spacing Tilesheets.