Algorithm 超覆盖DDA算法

Algorithm 超覆盖DDA算法,algorithm,Algorithm,我正试图弄明白如何制作一个超级覆盖DDA算法。或者换句话说,DDA算法将覆盖一条线穿过的所有网格点。见下图 这张图片是我画的,可能不是100%准确,但它显示了总体思路。我还要注意的是,图像下半部分的示例没有整数的开始和结束坐标,这是必要的 如果你需要知道,我打算用它来进行视线光线投射 我能够实现典型的DDA算法,但我的问题是,如何修改它以覆盖所有点 谢谢 我目前在Lua中实现的DDA算法 function dline(x0,y0, x1,y1) -- floating point input

我正试图弄明白如何制作一个超级覆盖DDA算法。或者换句话说,DDA算法将覆盖一条线穿过的所有网格点。见下图

这张图片是我画的,可能不是100%准确,但它显示了总体思路。我还要注意的是,图像下半部分的示例没有整数的开始和结束坐标,这是必要的

如果你需要知道,我打算用它来进行视线光线投射

我能够实现典型的DDA算法,但我的问题是,如何修改它以覆盖所有点

谢谢

我目前在Lua中实现的DDA算法

function dline(x0,y0, x1,y1) -- floating point input
  local dx = x1-x0
  local dy = y1-y0

  local s = math.max(math.abs(dx),math.abs(dy))

  dx = dx/s
  dy = dy/s

  local x = x0
  local y = y0
  local i = 0
  return function() -- iterator intended for a for loop
    if i <= s then
      local rx,ry = x,y
      x = x+dx
      y = y+dy
      i = i+1
      return rx,ry
    end
  end
end
函数数据线(x0,y0,x1,y1)——浮点输入
局部dx=x1-x0
局部dy=y1-y0
局部s=math.max(math.abs(dx),math.abs(dy))
dx=dx/s
dy=dy/s
局部x=x0
局部y=y0
局部i=0
返回函数()--用于for循环的迭代器

如果我你可以在与普通dda算法相同的时间复杂度下,只需在相邻的方块上添加一些检查。

你可以在与普通dda算法相同的时间复杂度下,只需在相邻的方块上添加一些检查。

对不起,我不经常问问题,主要是因为我不是那么好。但我会告诉你我擅长什么!解决我自己的问题!:D

需要注意的是,我问题中的图像显示了与对角线相交的直线。如果直线精确地通过一个点,则此算法不会,但经过一些思考后,我不希望与对角线相交

感谢我找到的文章

这是新的实现

function line(x0,y0, x1,y1)
  local vx,vy = x1-x0, y1-y0           -- get the differences
  local dx = math.sqrt(1 + (vy/vx)^2)  -- length of vector <1, slope>
  local dy = math.sqrt(1 + (vx/vy)^2)  -- length of vector <1/slope, 1>

  local ix,iy = math.floor(x0), math.floor(y0) -- initialize starting positions
  local sx,ex -- sx is the increment direction
              -- ex is the distance from x0 to ix
  if vx < 0 then
    sx = -1
    ex = (x0-ix) * dx
  else
    sx = 1
    ex = (ix + 1-x0) * dx -- subtract from 1 instead of 0
                          -- to make up for flooring ix
  end

  local sy,ey
  if vy < 0 then
    sy = -1
    ey = (y0-iy) * dy
  else
    sy = 1
    ey = (iy + 1-y0) * dy
  end

  local done = false
  local len  = math.sqrt(vx^2 + vy^2)
  return function()
    if math.min(ex,ey) <= len then
      local rx,ry = ix,iy
      if ex < ey then
        ex = ex + dx
        ix = ix + sx
      else
        ey = ey + dy
        iy = iy + sy
      end
      return rx,ry
    elseif not done then -- return the final two coordinates
      done = true
      return ix,iy
    end
  end
end
功能行(x0,y0,x1,y1)
局部vx,vy=x1-x0,y1-y0——获得差值
局部dx=math.sqrt(1+(vy/vx)^2)——向量长度
局部dy=math.sqrt(1+(vx/vy)^2)——向量的长度
局部ix,iy=数学楼层(x0),数学楼层(y0)——初始化起始位置
局部sx,ex--sx是增量方向
--ex是从x0到ix的距离
如果vx<0,则
sx=-1
ex=(x0 ix)*dx
其他的
sx=1
ex=(ix+1-x0)*dx——从1中减去0
--弥补
结束
本地的sy,ey
如果vy<0,则
sy=-1
ey=(y0-iy)*dy
其他的
sy=1
ey=(iy+1-y0)*dy
结束
本地完成=错误
局部len=math.sqrt(vx^2+vy^2)
返回函数()

如果math.min(ex,ey)对不起,我不经常问问题,主要是因为我不太好。但我会告诉你我擅长什么!解决我自己的问题!:D

需要注意的是,我问题中的图像显示了与对角线相交的直线。如果直线精确地通过一个点,则此算法不会,但经过一些思考后,我不希望与对角线相交

感谢我找到的文章

这是新的实现

function line(x0,y0, x1,y1)
  local vx,vy = x1-x0, y1-y0           -- get the differences
  local dx = math.sqrt(1 + (vy/vx)^2)  -- length of vector <1, slope>
  local dy = math.sqrt(1 + (vx/vy)^2)  -- length of vector <1/slope, 1>

  local ix,iy = math.floor(x0), math.floor(y0) -- initialize starting positions
  local sx,ex -- sx is the increment direction
              -- ex is the distance from x0 to ix
  if vx < 0 then
    sx = -1
    ex = (x0-ix) * dx
  else
    sx = 1
    ex = (ix + 1-x0) * dx -- subtract from 1 instead of 0
                          -- to make up for flooring ix
  end

  local sy,ey
  if vy < 0 then
    sy = -1
    ey = (y0-iy) * dy
  else
    sy = 1
    ey = (iy + 1-y0) * dy
  end

  local done = false
  local len  = math.sqrt(vx^2 + vy^2)
  return function()
    if math.min(ex,ey) <= len then
      local rx,ry = ix,iy
      if ex < ey then
        ex = ex + dx
        ix = ix + sx
      else
        ey = ey + dy
        iy = iy + sy
      end
      return rx,ry
    elseif not done then -- return the final two coordinates
      done = true
      return ix,iy
    end
  end
end
功能行(x0,y0,x1,y1)
局部vx,vy=x1-x0,y1-y0——获得差值
局部dx=math.sqrt(1+(vy/vx)^2)——向量长度
局部dy=math.sqrt(1+(vx/vy)^2)——向量的长度
局部ix,iy=数学楼层(x0),数学楼层(y0)——初始化起始位置
局部sx,ex--sx是增量方向
--ex是从x0到ix的距离
如果vx<0,则
sx=-1
ex=(x0 ix)*dx
其他的
sx=1
ex=(ix+1-x0)*dx——从1中减去0
--弥补
结束
本地的sy,ey
如果vy<0,则
sy=-1
ey=(y0-iy)*dy
其他的
sy=1
ey=(iy+1-y0)*dy
结束
本地完成=错误
局部len=math.sqrt(vx^2+vy^2)
返回函数()

if math.min(ex,ey)“询问代码的问题必须证明对正在解决的问题的最低理解。包括尝试的解决方案、为什么它们不起作用以及预期的结果。”输入数据的结构是什么?请提供您感兴趣的算法的解释(或链接)。一种“简单”的方法是修改您的步骤(
s
)。对于廉价/肮脏的铸造,我使用了与您相同的方法,但乘以10可以检查每“单位”距离十次。它可能会跳过一些有微小交叉点的方块,但对于游戏来说,它已经足够好了。如果对您的目的来说足够快,则无需使事情复杂化。“询问代码的问题必须表明对正在解决的问题的最低理解。包括尝试的解决方案、为什么不起作用以及预期的结果。”输入数据的结构是什么?请提供您感兴趣的算法的解释(或链接)。一种“简单”的方法是修改您的步骤(
s
)。对于廉价/肮脏的铸造,我使用了与您相同的方法,但乘以10可以检查每“单位”距离十次。它可能会跳过一些有微小交叉点的方块,但对于游戏来说,它已经足够好了。如果它足够快,你的目的,没有必要复杂的事情。