【问题标题】:Lua Separation Steering algorithm groups overlapping rooms into one cornerLua Separation Steering 算法将重叠的房间分组到一个角落
【发布时间】:2013-07-23 01:57:44
【问题描述】:

我正在尝试实现一个地牢生成算法(presented heredemo-ed here),该算法涉及生成随机数量的相互重叠的单元格。然后将细胞推开/分离,然后连接。现在,原始发帖人/作者描述说他正在使用分离指导算法以便将细胞均匀分布在一个区域上。我对植绒算法和/或分离转向行为没有太多经验,因此我转向谷歌寻求解释(并找到this)。我的实现(基于上次提到的那篇文章)如下:

function pdg:_computeSeparation(_agent)
  local neighbours = 0
  local rtWidth = #self._rooms
  local v =
  {
    x = self._rooms[_agent].startX,
    y = self._rooms[_agent].startY,
    --velocity = 1,
  }

  for i = 1, rtWidth do
    if _agent ~= i then
      local distance = math.dist(self._rooms[_agent].startX, 
                                 self._rooms[_agent].startY, 
                                 self._rooms[i].startX,
                                 self._rooms[i].startY)
      if distance < 12 then
        --print("Separating agent: ".._agent.." from agent: "..i.."")
        v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance
        v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance
        neighbours = neighbours + 1
      end
    end
  end


  if neighbours == 0 then
    return v
  else
    v.x = v.x / neighbours
    v.y = v.y / neighbours
    v.x = v.x * -1
    v.y = v.y * -1
    pdg:_normalize(v, 1)
    return v
  end
end

self._rooms 是一个表格,其中包含房间在网格中的原始 X 和 Y 位置,以及它的宽度和高度(endX,endY)。

问题在于,它不是在网格上整齐排列单元格,而是采用重叠的单元格并将它们移动到从 1,1 到距离+2、距离+2 的区域 (as seen in my video [youtube])

我试图了解为什么会发生这种情况。

如果需要,这里我解析网格表,分离后填充单元格:

function pdg:separate( )
  if #self._rooms > 0 then
    --print("NR ROOMS: "..#self._rooms.."")

    -- reset the map to empty
  for x = 1, self._pdgMapWidth do
    for y = 1, self._pdgMapHeight do
      self._pdgMap[x][y] = 4
    end
  end

  -- now, we separate the rooms
  local numRooms = #self._rooms
  for i = 1, numRooms do
    local v = pdg:_computeSeparation(i)
    --we adjust the x and y positions of the items in the room table
    self._rooms[i].startX = v.x
    self._rooms[i].startY = v.y
    --self._rooms[i].endX = v.x + self._rooms[i].endX 
    --self._rooms[i].endY = v.y + self._rooms[i].endY
  end


  -- we render them again
  for i = 1, numRooms do
    local px = math.abs( math.floor(self._rooms[i].startX) )
    local py = math.abs( math.floor(self._rooms[i].startY) )

    for k = self.rectMinWidth, self._rooms[i].endX do
      for v = self.rectMinHeight, self._rooms[i].endY do
        print("PX IS AT: "..px.." and k is: "..k.." and their sum is: "..px+k.."")
        print("PY IS AT: "..py.." and v is: "..v.." and their sum is: "..py+v.."")
        if k == self.rectMinWidth or 
           v == self.rectMinHeight or 
           k == self._rooms[i].endX or 
           v == self._rooms[i].endY then
          self._pdgMap[px+k][py+v] = 1
        else
          self._pdgMap[px+k][py+v] = 2
        end
      end
    end
  end
end

【问题讨论】:

    标签: lua cell flock procedural


    【解决方案1】:

    嗯,我知道这是一个老问题,但我注意到了一些东西,也许它对某人有用,所以......

    我觉得这里有问题:

    v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance
    v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance
    

    为什么要将这些方程乘以距离? “(self._rooms[_agent].startX - self._rooms[i].startX)”已经包含(平方)距离! 另外,将所有内容乘以“distance”,您将修改之前存储在 v 中的结果! 如果至少将“v.x”放在括号外,结果会更高,规范化功能会修复它。虽然这是一些无用的计算......

    顺便说一句,我很确定代码应该是这样的:

    v.x = v.x + (self._rooms[_agent].startX - self._rooms[i].startX)
    v.y = v.y + (self._rooms[_agent].startY - self._rooms[i].startY)
    

    我会举个例子。想象一下,您的主要代理位于 (0,0),三个邻居位于 (0,-2)、(-2,0) 和 (0,2)。分离转向行为会将主要代理移向 X 轴,在 (1,0) 的归一化方向上。 让我们只关注结果向量的 Y 分量。

    数学应该是这样的:

    --Iteration 1
    v.y = 0 + ( 0 + 2 )
    --Iteration 2
    v.y = 2 + ( 0 - 0 )
    --Iteration 3
    v.y = 2 + ( 0 - 2 )
    --Result
    v.y = 0
    

    这与我们的理论一致。 这就是您的代码所做的:

    (note that the distance is always 2)
    --Iteration 1
    v.y = ( 0 + 0 + 2 ) * 2
    --Iteration 2
    v.y = ( 4 + 0 - 0 ) * 2
    --Iteration 3
    v.y = ( 8 + 0 - 2 ) * 2
    --Result
    v.y = 12
    

    如果我得到正确的分离转向行为,这是不正确的。

    【讨论】:

      【解决方案2】:

      我也实现了这个生成算法,我或多或少地遇到了同样的问题。我所有的矩形都位于左上角。

      我的问题是我正在归一化长度为零的速度向量。如果将它们标准化,则除以零,得到 NaN。

      您可以通过简单地检查您的速度长度是否为零来解决此问题,然后再将其用于任何进一步的计算。

      我希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-22
        • 1970-01-01
        相关资源
        最近更新 更多