我尝试制作一个计算圆圈之间交点的函数:一个圆圈对着圆圈列表.
对于每种情况,有0,1或2个交叉点.
我希望函数返回nil,nil表示0点,z0,nil表示1和z1,z2表示2点.我想通过一个循环逐步收集表中的结果对,并在最后解压缩它,但是表没有采用零值.
我暂时试过这个.我怎样才能实现我的目标?
function InterSection_Cercles (Ca,... ) local C = table.pack( ... ) local d,CosTheta,Theta,i local t = {} for i = 1,C.n do d = complex.abs ( Ca.Ct - C[i].Ct ) CosTheta = round (((Ca.Ry * Ca.Ry + d * d - C[i].Ry * C[i].Ry) /( 2 * Ca.Ry * d )),10 ) Theta = round ( math.acos( CosTheta ),Prec) if not Theta then -- 0 solution -- table.insert( t,nil ) useless -- table.insert( t,nil ) elseif Theta == 0 then -- 1 solution table.insert( t,Ca.Ct + complex.polar (Ca.Ry,Theta + complex.arg (C[i].Ct -Ca.Ct))) -- table.insert( t,nil ) useless else -- 2 solitions table.insert( t,Theta + complex.arg (C[i].Ct -Ca.Ct))) table.insert( t,-Theta + complex.arg (C[i].Ct -Ca.Ct))) end -- if end -- for return table.unpack ( t ) end -- function
解决方法
无法在Lua中构建包含nil值的数组. Lua中的数组定义为[1,n]表中的序列,其中没有nil值.
您可以插入占位符值(false),也可以手动跟踪表的大小.因此,不必调用table.insert,而是必须创建一个新函数,将表的长度存储在某个值中:
local function manualInsert(tbl,val) if(not tbl.n) then tbl.n = 0 end --all values are assumed to be inserted through this function. tbl[tbl.n + 1] = val tbl.n = tbl.n + 1 end
通常,tbl不能与标准Lua机制一起使用来处理数组.你不能在它上面调用#来获得正确的长度,所以除非你知道它是特殊的,否则很难迭代它.删除元素需要它自己的特殊功能,等等.
但是,您可以使用Metatable和Metamethods来使这种伪数组看起来更具功能性.例如,在Lua 5.2中,您可以覆盖__len元方法以返回n.这将允许您使用i = 1,#tbl do迭代元素.它还允许table.unpack在没有手动传递长度的情况下工作,因为如果你不提供它,它被定义为使用#来获取长度.
请注意,虽然Lua 5.1允许使用__len元方法,但它不允许表覆盖默认长度计算.仅使用userdata的__len元方法.
在Lua 5.2中,您可以覆盖__ipairs元方法以使ipairs工作.在Lua 5.3中,这已被弃用; ipairs依赖于标准的Metamethods.这可能是可行的,但文档说,ipairs将继续“达到第一个零值”.所以在Lua 5.3中可能无法实现.
因此,除非你在Lua 5.2或更高版本中,否则manualInsert将创建一个非常不正常的表.