publicstaticclassScanLine { publicstaticvoidGetCoveredGrid(MapGrid mapGrid, Polygon polygon, List<int> grids) { var vertices = polygon.vertices; var n = vertices.Count; var minPoint = new Vector2(float.MaxValue, float.MaxValue); var maxPoint = new Vector2(float.MinValue, float.MinValue); for (var i = 0; i < n; i++) { var point = vertices[i]; minPoint.x = Mathf.Min(minPoint.x, point.x); minPoint.y = Mathf.Min(minPoint.y, point.y); maxPoint.x = Mathf.Max(maxPoint.x, point.x); maxPoint.y = Mathf.Max(maxPoint.y, point.y); }
var relaMinPoint = minPoint - mapGrid.min; var relaMaxPoint = maxPoint - mapGrid.min; var minCol = Mathf.Max(Utilities.FloorToInt(relaMinPoint.x * mapGrid.GridSizeInv), 0); // 闭区间 var minRow = Mathf.Max(Utilities.FloorToInt(relaMinPoint.y * mapGrid.GridSizeInv), 0); // 闭区间 var maxCol = Mathf.Min(Utilities.CeilToInt(relaMaxPoint.x * mapGrid.GridSizeInv), mapGrid.Col); // 开区间 var maxRow = Mathf.Min(Utilities.CeilToInt(relaMaxPoint.y * mapGrid.GridSizeInv), mapGrid.Row); // 开区间
privatestaticreadonly List<float> Temp = new(16); privatestaticvoidCore(MapGrid mapGrid, List<Vector2> vertices, int minX, int minY, int maxX, int maxY, List<int> grids) { for (var y = minY; y < maxY; y++) { var worldY = mapGrid.min.y + (y + 0.5f) * mapGrid.gridSize; Intersect(vertices, worldY); Temp.Sort(); var m = Temp.Count; for (var i = 0; i + 1 < m; i += 2) { var lc = Mathf.Max(Utilities.FloorToInt((Temp[i] - mapGrid.min.x) * mapGrid.GridSizeInv + 0.5f), 0); var rc = Mathf.Min(Utilities.FloorToInt((Temp[i + 1] - mapGrid.min.x) * mapGrid.GridSizeInv - 0.5f), mapGrid.Col - 1); for (var j = lc; j <= rc; j++) { grids.Add(y * mapGrid.Col + j); } } } }
privatestaticvoidIntersect(List<Vector2> vertices, float worldY) { Temp.Clear(); var n = vertices.Count; for (int j = 0, i = n - 1; j < n; i = j++) { var pi = vertices[i]; var pj = vertices[j]; if ((pi.y > worldY) == (pj.y > worldY)) continue; var m = (worldY - pi.y) / (pj.y - pi.y); var hitX = pi.x + m * (pj.x - pi.x); Temp.Add(hitX); } } }