我正致力于实施"基于目标的矢量场寻路" (在this link的文章中说明)它要求我用我的世界图中的每个节点标记距离目标节点的路径距离,并建议使用brushfire(波前)算法来执行此操作。这是我遇到问题的区域。当我进入while循环的第8次迭代和嵌套for
的第6次迭代时,我在标记的行上得到一个nil引用错误。
g 是我的图表,它有一个8向邻接列表表单。
q 是this FIFO lua库的实例。
rtx 和 rty 是根节点的x和y坐标。
d 是为了跟踪分配给每个节点的路径距离而添加的迭代器。
图中每个节点的结构与正在处理的节点的结构不同。
要处理的节点:
n = {}
n[1] = x coord
n[2] = y coord
n[3] = adjacency list (eight entries)
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
节点存储在图表中:
n = {}
n[1] = adjacency list
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
Beneath是我迄今为止的实施方式。 for循环中的t只是一个临时节点,用于将信息传递给队列。 BTW t是所有节点的距离设置的地方。
local function brushFire( g, rtx, rty )
local q = q.new()
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][3]
s.dist = 0
q:pushRight( s )
s = nil
local d = 0
while( table.getn( q.list[q.first] ) ~= 0 ) do
print( d )
local n = q:popLeft()
setDist( g, n )
print( #n[3] )
for i = 1, #n[3] do
print( ":"..i )
if( g[n[3][i][4]][n[3][i][2]].v ~= true ) then
g[n[3][i][5]][n[3][i][2]].v = true
local t = {}
t[1] = n[3][i][1]
t[2] = n[3][i][2]
t[3] = g[n[3][i][7]][n[3][i][2]][1] <------Error here
t.dist = d
q:pushRight( t )
t = nil
end
end
d = d + 1
end
end
如果您需要更多信息以便回答我的问题,请与我们联系。
答案 0 :(得分:1)
我找到了问题的答案。如果有人想使用该来源,我将在下面发布:
队列模块:
local q = {}
local q_mt = { __index = q }
function q.new()
local nq = { first = 0, last = -1, list = {} }
return setmetatable( nq, q_mt )
end
function q:pushLeft( value )
local first = self.first - 1
self.first = first
self.list[first] = value
end
function q:pushRight( value )
local last = self.last + 1
self.last = last
self.list[last] = value
end
function q:popLeft()
local first = self.first
if first > self.last then error( "list is empty" ) end
local value = self.list[first]
self.list[first] = nil
self.first = first + 1
return value
end
function q:popRight()
local last = self.last
if self.first > last then error( "list is empty" ) end
local value = self.list[last]
self.list[last] = nil
self.last = last - 1
return value
end
return q
以下模块创建一个向量字段,当调用pathFind.findPath时,该字段指向目标:
local q = require( "Queue" )
local pathFind = {}
local pathFind_mt = { __index = pathFind }
-- Private Functions
local function genDistMap( g, rtx, rty ) -<-<-<- genDistMap is the brushfire part
local q = q.new()
local g = g
g[rtx][rty].v = true
g[rtx][rty].dist = 0
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][1]
s.dist = 0
q:pushRight( s )
s = nil
while( q.list[q.first] ~= nil ) do
local n = q:popLeft()
for i = 1, #n[3] do
local x, y = n[3][i][1], n[3][i][2]
if( g[x][y].v ~= true ) then
g[x][y].v = true
local t = {}
t[1] = x
t[2] = y
t[3] = g[x][y][1]
t.dist = n.dist + 1
g[x][y].dist = n.dist + 1
q:pushRight( t )
t = nil
end
end
end
return g
end
local function genVectorField( nodes )
local nodes = nodes
for i = 2, #nodes - 1 do
for j = 2, #nodes[i] - 1 do
local a = nodes[i - 1][j].dist - nodes[i + 1][j].dist
local b = nodes[i][j - 1].dist - nodes[i][j + 1].dist
local c = math.sqrt( a*a + b*b )
nodes[i][j].vX = a/c*5
nodes[i][j].vY = b/c*5
end
end
return nodes
end
-- Public Functions
function pathFind.new()
local newPathFind = {}
return setmetatable ( newPathFind, pathFind_mt )
end
function pathFind.findPath( nodeSet, rootX, rootY )
local nodes = nodeSet
nodes = genDistMap( nodes, rootX, rootY )
nodes = genVectorField( nodes )
return( nodes )
end
return pathFind