Math 网格中的矩形-我需要边缘案例方面的帮助
我试图解决的问题如下:Math 网格中的矩形-我需要边缘案例方面的帮助,math,language-agnostic,lua,Math,Language Agnostic,Lua,我试图解决的问题如下: In a 2-D space, Given a grid size and a rectangle, calculate the grid cells occupied (partially or totally) by the rectangle. “网格大小”的意思是“16x16网格”或“32x32网格”。所有栅格均以坐标原点(0,0)为中心 矩形由4个浮点数定义:左侧、顶部、宽度和高度 此操作的结果始终为矩形。我想返回左上角单元格的坐标(即0,0),然后返回重角向
In a 2-D space, Given a grid size and a rectangle, calculate the grid cells
occupied (partially or totally) by the rectangle.
“网格大小”的意思是“16x16网格”或“32x32网格”。所有栅格均以坐标原点(0,0)为中心
矩形由4个浮点数定义:左侧、顶部、宽度和高度
此操作的结果始终为矩形。我想返回左上角单元格的坐标(即0,0),然后返回重角向右和向下占据的单元格数量(有点像宽度和高度,但对于单元格)
到目前为止,我已经能够编写出一个基本有效的算法。它首先要做的是计算网格中单个点所在的单元坐标。然后,给定矩形,我计算它的左上角和右下角在网格上的位置,然后它是一个简单的减法:
-- given a world coordinate, return the coordinates of the cell that would contain it
local function _toGrid(wx, wy)
return math.floor(wx / __cellSize), math.floor(wy / __cellSize)
end
-- given a box in world coordinates, return a box in grid coordinates that contains it
-- returns the x,y coordinates of the top-left cell, the number of cells to the right and the number of cells down.
local function _toGridBox(l, t, w, h)
local gl,gt = _toGrid(l, t) -- top left grid corner
local gr,gb = _toGrid(l+w, t+h) -- bottom-right grid corner
return gl, gt, gr-gl+1, gb-gt+1 -- return top,left,cells to the right, cells to bottom
end
注:
- 源代码是Lua,但我接受任何编程语言的解决方案,只要它们是可理解的
- y坐标“增加时下降”;许多屏幕系统就是这样工作的。我不认为这对这个问题有什么意义,但请不要对此感到困惑)
为10,高度为20,gr
将为0,而gt
1,因此\u toGrid
将返回0,0,1,2(0,0单元格上有一行两列)
当矩形从内部“接触”(而不是交叉)一个单元格的下方或右侧时,就会出现问题。在这种情况下,\u toGrid
返回的单元格比我希望的多“一个”
例如,如果我将上一个矩形向左移动6个像素(因此它位于10,0),它将“接触”其包含网格的左侧边界,从0到16。然后gr
将为1,返回的数据将为0,0,2,2
如果可能的话,我想避免这种情况。对于一个从左边到16英寸的矩形,我希望它保持在第一个网格单元上。我希望它一旦超过16就开始“占据下一个单元格”——例如,当它达到16.00000001时
另外,请注意,这仅适用于右侧和底部。左边和上面的工作,因为我希望他们。例如,左坐标为16的矩形应显示在“右侧的第二个单元格”上,而不是第一个单元格上
我确信解决方案并不复杂,但我已经思考了一段时间,似乎没有找到它。任何帮助都将不胜感激。对于底部和右侧,您需要使用ceil
而不是floor
。我不知道任何Lua,所以这在语法上可能不正确,但您可能希望遵循以下几点:
local function _toGridBox(l, t, w, h)
local gl = math.floor(l / _cellSize)
local gt = math.floor(t / _cellSize)
local gr = math.ceil((l+w) / _cellSize)
local gb = math.ceil((t+h) / _cellSize)
return gl, gt, gr-gl, gb-gt -- return top,left,cells to the right, cells to bottom
end
从本质上讲,您的问题在于函数\u toGrid
对于您的目的来说是错误的抽象,因为它总是使用地板。显然,您将自己锁定在使用该抽象中,这使您很难找到正确的答案。对于底部和右侧,您需要使用ceil
而不是floor
。我不知道任何Lua,所以这在语法上可能不正确,但您可能希望遵循以下几点:
local function _toGridBox(l, t, w, h)
local gl = math.floor(l / _cellSize)
local gt = math.floor(t / _cellSize)
local gr = math.ceil((l+w) / _cellSize)
local gb = math.ceil((t+h) / _cellSize)
return gl, gt, gr-gl, gb-gt -- return top,left,cells to the right, cells to bottom
end
从本质上讲,您的问题在于函数\u toGrid
对于您的目的来说是错误的抽象,因为它总是使用地板。显然,你将自己锁定在使用这种抽象概念上,这使得你很难找到正确的答案。为什么这个问题上有四种不同的语言标签?@Nicolas-“我接受任何编程语言的解决方案”对,但这并不能解释为什么你只调用了其他三种语言。我们有“任何语言”问题的标签;它被称为“语言不可知论”
@nicolasbolas,这很公平。我已经重新标记了这个问题(顺便说一句,你可以自己做)为什么否决票?这是我见过的写得最好的问题之一……为什么这个问题上有四个不同的语言标签?@Nicolas-“我接受任何编程语言的解决方案”对,但这并不能解释为什么你只调用了其他三种语言。我们有“任何语言”问题的标签;它被称为“语言不可知论”
@nicolasbolas,这很公平。我已经重新标记了这个问题(顺便说一句,你可以自己做)为什么否决票?这是我看过的最好的书面问题之一,所以…嗨,谢谢你的回答。你说得对,我被“精神禁锢”了。我尝试过你的解决方案(做了一些小改动,我希望你不介意我编辑一下你的答案),它似乎工作得很好。今晚我会做更多的测试,如果我看不到更多的问题,我会接受你的答案。@kikito没有关于编辑的问题,相反,这是我的想法。很高兴它有帮助!在我的主程序上尝试了一下,似乎成功了。再次感谢!嗨,谢谢你的回答。你说得对,我被“精神禁锢”了。我尝试过你的解决方案(做了一些小改动,我希望你不介意我编辑一下你的答案),它似乎工作得很好。今晚我会做更多的测试,如果我看不到更多的问题,我会接受你的答案。@kikito没有关于编辑的问题,相反,这是我的想法。很高兴它有帮助!在我的主程序上尝试了一下,似乎成功了。再次感谢!