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
----
----
7
  • 1
    This is missing necessary code to reproduce the error. Commented Mar 30 at 15:22
  • 1
    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. 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") Commented Mar 30 at 15:50
  • 1
    Please provide the code that, when copied into an editor and executed, causes the error or problematic behavior. Commented Mar 30 at 19:52
  • 1
    fyi:can't repoduce , furthermore,under the covers loop variables ( i, vertextCount ) are 'copied' to working variables (hidden) and regardless of what is done to them within the confines of the loop makes no difference to the loop control - , suggest you knock up a trivial example where you mess with i, vertexCount inside the loop - use copious prints to see what's going on Commented Apr 1 at 0:59

1 Answer 1

-1

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 ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.