我正在构建一个模拟,其中世界由许多正方形组成。还有一些被称为“太阳”的物体,它们照亮了方块,并在每一步都更新了它们的“接收强度”。
在此图像中,正方形中心之间的距离为32个单位,每个正方形的接收强度(或 R.I。)使用以下公式计算:
R.I。 = 100 /(光源和方形之间的距离)^ 2
用通用(和可怕的)编程语言编写,计算R.I.的函数可能如下所示:
(define (calc-RI sq-x sq-y sn-x sn-y)
(return (/ 100
(+ (square (- sq-x sn-x))
(square (- sq-y sn-y))
)
)
)
)
...并且,为了容纳多个太阳,每个太阳的R.I.将被单独计算并且为每个方格加在一起。这一切都很好,直到我觉得需要在这个模拟中引入一个翘曲机制:在世界边缘“移动”的对象将从另一个“重新进入”世界像游戏中的小行星一样 这不仅需要应用于模拟中的其他对象,还需要轻巧 那么,新函数应该用于计算每个方格的R.I.? (假设该函数采用一个正方形和一个太阳的 x 和 y 坐标,以及宽度和高度世界上的强大,在阳光的影响下,给定方格RI的回归是什么?)
答案 0 :(得分:0)
您可以通过想象网格被原始网格的副本包围来解决这个问题,每个包裹一个层。对于原始网格中的每个正方形,计算落在每个相应正方形上的光强度,并对结果求和。
在上图中,黑色网格代表世界,蓝色网格代表世界网格的副本。要在绿色方块上找到一个包裹的光强度,请将在每个蓝色方块计算的简单强度添加到为绿色方块计算的简单强度。要计算另一个包装,请添加另一层副本。
这是一些实现此功能的Lua代码。星形表示在表格中:
stars = { { x=x1, y=y1 }, { x=x2, y=y2 },... }
在此实现中,包含星形的正方形的强度为-1
。这可以改变,使得包含恒星的正方形像任何其他正方形一样累积强度。要使用这些功能,请定义stars
表,然后使用light_universe()
(此处网格为正方形),grid_size
,square_size
表调用stars
,以及wraps
期望的数量。将wraps
设置为零,nil
,或者只是省略此参数,以获得没有包装的简单强度计算。函数light_universe()
返回一个表,其中包含世界网格每个方格的强度。您可以使用show_intensities()
返回的表格和表格的light_universe()
调用grid_size
来查看结果。请注意,世界网格的左上角有坐标(1,1)。
calculate_intensity()
函数首先计算网格副本字段的field_size
。这是图中蓝色网格的大小,是grid_size
的奇数倍,例如,对于1个包裹,field_size
是3.接下来,当前{{1}的世界坐标转换为字段坐标star
和star_x
(相对于图中蓝色网格的坐标)。然后迭代对应于star_y
和x
的字段内的位置。这些是图表蓝色方块的位置。第一个位置位于场的左上角网格中,其场地坐标等于感兴趣的正方形的世界坐标。对于每个位置,计算强度并将其添加到运行总计中,该值在迭代完成时返回。
y
这是一个显示强度而没有换行的交互,对应于您问题中的示例。
-- Intensity calculation with wraps
-- wraps = nil or wraps = 0 for simple calculation
function calculate_intensity(star, x, y, grid_size, square_size, wraps)
wraps = wraps or 0
local field_size = grid_size * (2 * wraps + 1) -- odd number of grids
local star_x = star.x + wraps * grid_size -- cdts of star in field
local star_y = star.y + wraps * grid_size
local intensity = 0
-- x and y are cdts wrt world grid, but also wrt first grid in field
for field_y = y, field_size, grid_size do
for field_x = x, field_size, grid_size do
local dx = square_size * (star_x - field_x)
local dy = square_size * (star_y - field_y)
local dist_sq = dx * dx + dy * dy
intensity = intensity + 100 / dist_sq
end
end
return intensity
end
function light_universe(grid_size, square_size, stars, wraps)
wraps = wraps or 0
local grid_intensities = {}
for i, star in ipairs(stars) do
for y = 1, grid_size do
grid_intensities[y] = grid_intensities[y] or {}
for x = 1, grid_size do
if x == star.x and y == star.y then
grid_intensities[y][x] = -1
elseif grid_intensities[y][x] ~= -1 then
grid_intensities[y][x] = (grid_intensities[y][x] or 0) +
calculate_intensity(star, x, y, grid_size, square_size, wraps)
end
end
end
end
return grid_intensities
end
function show_intensities(grid, grid_size)
for y = 1, grid_size do
for x = 1, grid_size do
local intensity = grid[y][x]
local fmt
if intensity ~= -1 then
fmt = (string.format("%10.5f", intensity))
else
fmt = string.format("%-10s", " Star")
end
io.write(fmt)
end
print()
end
end
以下是一个包装的相同情况:
> stars = { { x=1, y=1 } }
> light_grid = light_universe(3, 32, stars, 0)
> show_intensities(light_grid, 3)
Star 0.09766 0.02441
0.09766 0.04883 0.01953
0.02441 0.01953 0.01221
有两个包装:
> light_grid = light_universe(3, 32, stars, 1)
> show_intensities(light_grid, 3)
Star 0.17054 0.16628
0.17054 0.12440 0.12023
0.16628 0.12023 0.11630
这是一个7X7网格,有两颗星,一个包裹:
> light_grid = light_universe(3, 32, stars, 2)
> show_intensities(light_grid, 3)
Star 0.20497 0.20347
0.20497 0.15960 0.15811
0.20347 0.15811 0.15664