Problem with indexing a Spatial Grid

Hey there,

I’m developing for a few weeks now and I often encountered problems which I could solve after a 1 or 2 days at worst, but now I don’t think that I can solve it on my own.

So I have this Spatial Grid for collision detection. And because I want to implement a pathfinding, I thought it would be a good idea to add a points grid into that grid. 100 points to be exact. The problem is not really about the points, but more about the positioning.

Image: https://prnt.sc/g1ze7n

As you can see - i have 2 problems:

1.) the main spatial grid is only covering parts of the screen, even when using actualContentWidth & Height (which I’m currently not doing). The actual y=0 is around -40.

It also had a margin on the left side - I “fixed” this through anchoring it at the top left. Eventhough I don’t know if it has any side effects for the collision detection.

2.) A similar problem is now with points, because I have to use the original Cell Coordinates.

Structure is: Generate Grid -\> Generate Cell -\> Generate Points in Cell -\> Next Cell -- Cell Class -- IMPORTANT: xpos and ypos are the starting coordinates from the cell. function SpatialCell:createPoints() -- creating 100 points into a cell of the main grid local x = 1 local y = 1 for x = 1, self.columns do -- columns and rows is 10 self.pointGrid[x] = PathPoint:new(self.xpos,self.ypos,x,y,self.pointsize) for y = 1, self.rows do self.pointGrid[x][y] = PathPoint:new(self.xpos,self.ypos,x,y,self.pointsize) end end data.points = data.points + #self.pointGrid end -- local PathPoint = class() function PathPoint:init(cellX,cellY,x,y,size) -- cellX and cellY are xpos and ypos self.xpos = cellX + (x \* size) self.ypos = cellY + (y \* size) self.size = size self.id = x .. "/" .. y self.debug = true if(self.debug) then self:create() end --if(x \< 100) then print("PP " .. self.xpos .. " / " .. self.ypos) end end function PathPoint:create() self.object = display.newRect(self.xpos,self.ypos,self.size,self.size) --print("xpos" .. self.xpos) self.object:setFillColor(0) self.object.strokeWidth = 1 self.object:setStrokeColor(0) self.object.anchorX = 1 self.object.anchorY = 1 self.object.alpha = 0.15 end return PathPoint

I think the main reason for the problem is that I have to start the loop at 1 and not 0 (!) since I can’t store an item into an array/table at index 0. This means that I’m not starting at x=0 and y=0 (top left) rather than already 1 in. Which at the finishing code with 1 cell width and height is a lot.

I already tried to start at 0 manually but this messes with the collision detection and I’m not sure if I can fix this without applying something quick and dirty.

Really would appreciate your experts help.

Thank you! :slight_smile:

Timo,

I have not really read the code. I do not have a lot of time to read it and analyze it, but a quick look shows me a possible quick and simple hack to fix your ‘positioning’ issue.  I assume you are using physics engine for collision detection and I do not use the physics engine very much, so I am not sure if this positioning hack I suggest will make a difference on that. 

I had to make some assumptions here about what x,y are when they get sent to the pathPoint.init, but I am assuming the first call they are 1,1 and each call to pathPoint:init after that they are incremented as they move by column and row; but then I just quickly look at this, so am am note sure. But, if nothing else, hope I get you pointed in a direction to solving the issue.

in pathPoint:init    … this should adjust for the offset caused by not being able to index with zero

self.xpos = cellX + ( (x - 1) * size )  

self.ypos = cellY + ( (y - 1) * size )

Hey cyber, thanks for the reply. I already tried this before and tried again but this just resulted in the table being one short and the other functions working incorrectly. 

I’m not sure why - because I thought it doesn’t work and I tried it before - but setting the x and y value to 0 worked. :slight_smile:

function SpatialGrid:create() local x = 0 -- can even be -(negative) integers local y = 0 for x = 0, self.columns do self.grid[x] = SpatialCell:new(x,y,self.size) for y = 0, self.rows do self.grid[x][y] = SpatialCell:new(x,y,self.size) end end end

Timo,
 

Great, Glad to see you got it fixed.   Best of luck on your project!

Bob

You can even omit the local declarations altogether. Those are distinct variables from the ones automatically created by your loops, which will temporarily shadow them since they have the same name, and in this case don’t serve any purpose.

Timo,

I have not really read the code. I do not have a lot of time to read it and analyze it, but a quick look shows me a possible quick and simple hack to fix your ‘positioning’ issue.  I assume you are using physics engine for collision detection and I do not use the physics engine very much, so I am not sure if this positioning hack I suggest will make a difference on that. 

I had to make some assumptions here about what x,y are when they get sent to the pathPoint.init, but I am assuming the first call they are 1,1 and each call to pathPoint:init after that they are incremented as they move by column and row; but then I just quickly look at this, so am am note sure. But, if nothing else, hope I get you pointed in a direction to solving the issue.

in pathPoint:init    … this should adjust for the offset caused by not being able to index with zero

self.xpos = cellX + ( (x - 1) * size )  

self.ypos = cellY + ( (y - 1) * size )

Hey cyber, thanks for the reply. I already tried this before and tried again but this just resulted in the table being one short and the other functions working incorrectly. 

I’m not sure why - because I thought it doesn’t work and I tried it before - but setting the x and y value to 0 worked. :slight_smile:

function SpatialGrid:create() local x = 0 -- can even be -(negative) integers local y = 0 for x = 0, self.columns do self.grid[x] = SpatialCell:new(x,y,self.size) for y = 0, self.rows do self.grid[x][y] = SpatialCell:new(x,y,self.size) end end end

Timo,
 

Great, Glad to see you got it fixed.   Best of luck on your project!

Bob

You can even omit the local declarations altogether. Those are distinct variables from the ones automatically created by your loops, which will temporarily shadow them since they have the same name, and in this case don’t serve any purpose.