最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

lua - Loop exceeds its limit - Stack Overflow

programmeradmin2浏览0评论

I am experiencing a very strange error in Lua/Love2D code where for-loop index exceeds the maximum limit. The initial problem arose from Geom.segmentSegmentIntersection() having passed nil as argument and throwing an error of attempt to perform arithmetic on nil. As I couldn't to narrow down the cause I have added extra if with logging to detect this situation. To my surprise it seems that loop iterator i somehow can exceed loop limit vertexCount. The code runs on a single thread without coroutines, and all polygon tables are not modified once object is created. Problem appears at random and for some reason I cannot recreate it, even with same segment coordinates and the exact same polygon.

I could keep the check and break the loop forcefully but that just seems wrong.

Here's the code and caught output:

-- Checks if a line segment intersects with a polygon.
-- Parameters:
--   x, y: Starting point coordinates of the segment.
--   x2, y2: Ending point coordinates of the segment.
--   polygon: A table of coordinates defining the polygon as a series of points {x1, y1, x2, y2, ..., xn, yn}.
--            The polygon is assumed to be closed, where the last point connects back to the first point.
-- Returns:
--   intersects: A boolean value; true if the segment intersects the polygon, false otherwise.
--   ix, iy: Coordinates of the intersection point, if an intersection occurs.
Geom.isIntersectionSegmentPolygon = function(x, y, x2, y2, polygon)
  -- TODO: sometimes p1x passed to segmentSegmentIntersection is nil for some reason, this should allow to debug this
  Geom._ix = x
  Geom._iy = y
  Geom._ix2 = x2
  Geom._iy2 = y2
  Geom._ipolygon = polygon

  local vertexCount = #polygon
  local p0x = polygon[vertexCount - 1]
  local p0y = polygon[vertexCount]
  
  for i = 1, vertexCount, 2 do
      local p1x = polygon[i]
      local p1y = polygon[i + 1]
      -- TODO remove this
      if p1x==nil or p1y==nil or i>vertexCount then
        fail("isIntersectionSegmentPolygon error, index", i, "; vertexCount", vertexCount)
        fail("p1x",p1x)
        fail("p1y",p1y)
        log(x, y, x2, y2)
        log("polygon size:",#polygon,"and elements:")
        for ii=1,vertexCount do log(ii,polygon[ii]) end
        logtab(polygon)
        for _,a in pairs(Actor.actors) do if a.polygon==Geom._ipolygon then log(a.id,a.name,a.__type) end end
        fail("----")
      end
      local ix, iy, intersects = Geom.segmentSegmentIntersection(x, y, x2, y2, p0x, p0y, p1x, p1y)
      if intersects then
          return true, ix, iy
      end
      p0x = p1x
      p0y = p1y
  end
  return false, nil, nil
end

the output

isIntersectionSegmentPolygon error, index       9       ; vertexCount   8
p1x     nil
p1y     nil
-7359.7282151011        -4523.1013367583        -7427.732922483 -4587.5428777841
polygon size:   8       and elements:
1       -7478.3615612719
2       -4713.7197332234
3       -7421.2353293006
4       -4588.2516139988
5       -7381.6384387281
6       -4606.2802667766
7       -7438.7646706994
8       -4731.7483860012
{-7478.36156,-4713.71973,-7421.23533,-4588.25161,-7381.63844,-4606.28027,-7438.76467,-4731.74839}
8198    nil     house
----
----

I am experiencing a very strange error in Lua/Love2D code where for-loop index exceeds the maximum limit. The initial problem arose from Geom.segmentSegmentIntersection() having passed nil as argument and throwing an error of attempt to perform arithmetic on nil. As I couldn't to narrow down the cause I have added extra if with logging to detect this situation. To my surprise it seems that loop iterator i somehow can exceed loop limit vertexCount. The code runs on a single thread without coroutines, and all polygon tables are not modified once object is created. Problem appears at random and for some reason I cannot recreate it, even with same segment coordinates and the exact same polygon.

I could keep the check and break the loop forcefully but that just seems wrong.

Here's the code and caught output:

-- Checks if a line segment intersects with a polygon.
-- Parameters:
--   x, y: Starting point coordinates of the segment.
--   x2, y2: Ending point coordinates of the segment.
--   polygon: A table of coordinates defining the polygon as a series of points {x1, y1, x2, y2, ..., xn, yn}.
--            The polygon is assumed to be closed, where the last point connects back to the first point.
-- Returns:
--   intersects: A boolean value; true if the segment intersects the polygon, false otherwise.
--   ix, iy: Coordinates of the intersection point, if an intersection occurs.
Geom.isIntersectionSegmentPolygon = function(x, y, x2, y2, polygon)
  -- TODO: sometimes p1x passed to segmentSegmentIntersection is nil for some reason, this should allow to debug this
  Geom._ix = x
  Geom._iy = y
  Geom._ix2 = x2
  Geom._iy2 = y2
  Geom._ipolygon = polygon

  local vertexCount = #polygon
  local p0x = polygon[vertexCount - 1]
  local p0y = polygon[vertexCount]
  
  for i = 1, vertexCount, 2 do
      local p1x = polygon[i]
      local p1y = polygon[i + 1]
      -- TODO remove this
      if p1x==nil or p1y==nil or i>vertexCount then
        fail("isIntersectionSegmentPolygon error, index", i, "; vertexCount", vertexCount)
        fail("p1x",p1x)
        fail("p1y",p1y)
        log(x, y, x2, y2)
        log("polygon size:",#polygon,"and elements:")
        for ii=1,vertexCount do log(ii,polygon[ii]) end
        logtab(polygon)
        for _,a in pairs(Actor.actors) do if a.polygon==Geom._ipolygon then log(a.id,a.name,a.__type) end end
        fail("----")
      end
      local ix, iy, intersects = Geom.segmentSegmentIntersection(x, y, x2, y2, p0x, p0y, p1x, p1y)
      if intersects then
          return true, ix, iy
      end
      p0x = p1x
      p0y = p1y
  end
  return false, nil, nil
end

the output

isIntersectionSegmentPolygon error, index       9       ; vertexCount   8
p1x     nil
p1y     nil
-7359.7282151011        -4523.1013367583        -7427.732922483 -4587.5428777841
polygon size:   8       and elements:
1       -7478.3615612719
2       -4713.7197332234
3       -7421.2353293006
4       -4588.2516139988
5       -7381.6384387281
6       -4606.2802667766
7       -7438.7646706994
8       -4731.7483860012
{-7478.36156,-4713.71973,-7421.23533,-4588.25161,-7381.63844,-4606.28027,-7438.76467,-4731.74839}
8198    nil     house
----
----
Share Improve this question edited Mar 30 at 14:44 jonrsharpe 122k30 gold badges268 silver badges475 bronze badges asked Mar 30 at 14:34 rostokrostok 2,1452 gold badges18 silver badges21 bronze badges 7
  • This is missing necessary code to reproduce the error. – ggorlen Commented Mar 30 at 15:22
  • I can't reproduce. Even after I catch the error, and game enters different error handler, where I can still execute remote lua commands from external tool it wont happen again. Even for the exact same parameters and the same polygon table. – rostok Commented Mar 30 at 15:45
  • So there's no error then? If you can't reproduce the error and neither can we, then it seems all is well. (I suspect you may not be understanding my request--I need code i can run to see the error you're showing here... but most of the code isn't provided here. "Reproduce" just means "code I can run that causes the error") – ggorlen Commented Mar 30 at 15:50
  • What do you propose I do to reproduce it? – rostok Commented Mar 30 at 19:01
  • Please provide the code that, when copied into an editor and executed, causes the error or problematic behavior. – ggorlen Commented Mar 30 at 19:52
 |  Show 2 more comments

1 Answer 1

Reset to default 0

trivial example - mess with loop control variable i


cat ./rostok.lua 
#! /usr/bin/env lua

local vertexCount = 9
print("START:vertexCount = " .. vertexCount .. " non-existant i: " .. tostring(i))

for i = 1, vertexCount, 2 do
    print(" loop variables: vertexCount:" .. vertexCount .. " i:" .. i )
    vertexCount = i*i
    i = i*i
    print("HACKED vertexCount:" .. vertexCount .. "   HACKED i:" .. i )
end
print("END: vertexCount:" .. vertexCount .. " non-existant i: " .. tostring(i))

#
# run it
#
$ ./rostok.lua 
START:vertexCount = 9 non-existant i: nil
    loop variables: vertexCount:9 i:1
HACKED vertexCount:1   HACKED i:1
    loop variables: vertexCount:1 i:3
HACKED vertexCount:9   HACKED i:9
    loop variables: vertexCount:9 i:5
HACKED vertexCount:25   HACKED i:25
    loop variables: vertexCount:25 i:7
HACKED vertexCount:49   HACKED i:49
    loop variables: vertexCount:49 i:9
HACKED vertexCount:81   HACKED i:81
END: vertexCount:81 non-existant i: nil

#
#
#
luacheck rostok.lua 
Checking rostok.lua                               2 warnings

    rostok.lua:4:80: accessing undefined variable i
    rostok.lua:12:77: accessing undefined variable i

Total: 2 warnings / 0 errors in 1 file

hope this helps ...
发布评论

评论列表(0)

  1. 暂无评论