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
1 Answer
Reset to default 0trivial 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 ...