Lua - 错误 Attempt to perform arithmetic on field '?' -- This occurs at the end of the for loop

我正在为 Ti-nspire CX CAS 笔记本电脑开发程序,在执行时指示第 52 行出现错误,这是在“area”函数的 for 循环结束时出现的。 抱歉我的英语。

local coX = {0,2,2,0}
local coY = {0,0,2,0}
local xmax = 2
local ymax = 2

-- Matriz de coordenadas para función "on.paint(gc)"
function conCoor(x,y)
    local nx = x
    for i=1, #x do
        table.insert(nx,i*2,y[i])
    end
    return nx
end

-- Valor absoluto
function math.abs(valor)
    if valor < 0 then
        valor = valor*(-1)
    end
    return valor
end

-- Inercia del polígono respecto el eje X
function inerciex(x,y)
    local E = 0
    local z =0
    for i = 1, #x-1 do
        E = (x[i+1]-x[i])*(y[i+1]+y[i])*((y[i+1])^2+(y[i])^2)
        z = E + z
    end
    return math.abs(z/12)
end

-- Inercia del polígono respecto el eje Y
function inerciey(x,y)
    local E = 0
    local z =0
    for i = 1, #x-1 do
        E = (y[i+1]-y[i])*(x[i+1]+x[i])*((x[i+1])^2+(x[i])^2)
        z = E + z
    end
    return math.abs(z/12)
end

-- Área del poligono
function area(x,y)
    local A = 0
    local z = 0
    for i = 1, #x-1 do
        A = (y[i]*x[i+1]-x[i]*y[i+1])
        z = A + z
    end -- 第 52 行,这是问题所在的行
    return math.abs(z/2)
end

-- Centro de masa del polígono (eje x)
function centroix(x,y)
    local Ac = area(x,y)
    local z = 0
    local cx = 0
    for i = 1, #x-1 do
        cx = (x[i]+x[i+1])*(x[i]*y[i+1]-x[i+1]*y[i])
        z = cx + z
    end
    return z/(6*Ac)
end

-- Centro de masa del polígono (eje y)
function centroiy(x,y)
    local Ac = area(x,y)
    local z = 0
    local cx = 0
    for i = 1, #x-1 do
        cx = (y[i]+y[i+1])*(x[i]*y[i+1]-x[i+1]*y[i])
        z = cx + z
    end
    return z/(6*Ac)
end

-- Escala de figura
function escala(xmax,ymax)
    local sc = 0
    if xmax > ymax then
        sc = 81/xmax
    else
        sc = 81/ymax
    end
    return math.floor(sc)
end

-- Coordenadas del origen en pantalla
function oriDispX(x,y,xmax,ymax)
    return math.floor(212 + (-1)*centroix(x,y)*escala(xmax,ymax))
end

function oriDispY(x,y,xmax,ymax)
    return math.floor(105 + (-1)*centroiy(x,y)*escala(xmax,ymax))
end

-- Cambio de coordenadas real
function coorCamb(x,y,xmax,ymax)
    -- Escalado de coordenadas
    local escx = x
    local escy = y
    local orix = oriDispX(escx,escy,xmax,ymax)
    local oriy = oriDispY(escx,escy,xmax,ymax)
    for i = 1, #escx do
        escx[i] = math.floor(escx[i]*escala(xmax,ymax))
        escy[i] = math.floor(escy[i]*escala(xmax,ymax))
    end
    -- Cambio de coordenadas
    for i = 1, #escx do
        escx[i] = escx[i] + orix
        escy[i] = escy[i] + oriy
    end
    return conCoor(escx,escy)
end

function on.paint(gc)
    local ox = oriDispX(coX,coY,xmax,ymax)
    local oy = oriDispY(coX,coY,xmax,ymax)
    local c = coorCamb(coX,coY,xmax,ymax)
    gc:drawPolyLine(c)
    gc:drawLine(ox-3,oy,ox+3,oy)
    gc:drawLine(ox,oy-3,ox,oy+3)
    gc:fillArc(ox-1,oy-1,2,2,0,360)
    gc:fillArc(212-1,105-1,2,2,0,360)
    gc:drawString(tostring(area(coX,coY)),10,10)
    platform.window:invalidate()
end

更具体地说,这个错误发生在这里:

function area(x,y)
    local A = 0
    local z = 0
    for i = 1, #x-1 do
        A = (y[i]*x[i+1]-x[i]*y[i+1])
        z = A + z
    end -- 第 52 行,这是问题所在的行
    return math.abs(z/2)
end
点赞
用户3735873
用户3735873

你的代码假设 X 和 Y 数组大小相等(因为你用 i 索引同时访问 X 和 Y 数组),或者至少 Y 不会比 X 小。然而,i 的索引范围是从 1 到 X 数组大小,这对于小于 X 大小的 Y 数组来说是无效的。

因此,如果 Y 数组比 X 数组小,你会遇到这个错误。下面是证明:

function area(x,y)
  local A = 0
  local z = 0
  for i = 1, #x-1 do
    A = (y[i]*x[i+1]-x[i]*y[i+1])
    z = A + z
  end
  return math.abs(z/2)
end

print(area({1,2,3},{4,5,6})) -- 可以执行
print(area({1,2,3},{4,5})) -- 报错
2017-03-18 22:54:29
用户7729582
用户7729582

解决方案是在整个脚本的开头初始化变量和表格,然后在on.paint函数中使用"var.recall"调用新的值。

2017-03-23 06:03:01