[Solved] Table comparison logic question

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

[Solved] Table comparison logic question

Post by Vmpwraith »

I have a table that holds balls that have been spawned and grow over time. I'm trying to figure out a way to make them disappear once they grow to touch each other.

I plan to check overlaps via Pythagoras.

The part I'm struggling with is the table like this. Basically I have added a static growth speed that increments the r (radius value).

I need to test each circle against all others in the array and destroy any two or more that touch as they grow. I'm not sure how to loop through this as it needs to go forward and backwards. Do I need to extract the one I'm looking at then compare it to all others and place it back at the end if not touching any of the others then start with the next one? some sort of reordering? or is there a cleaner way to do this.

Code: Select all

table = {}
table[1] = {x=10,y=10,r=10}
table[2] = {x=100,y=150,r=10}
table[3] = {x=200,y=200,r=10}
table[4] = {x=400,y=400,r=10}

eg.
compare table[1] to all others in the table then table[2] to all others in table eventually destroying them as the collide. is fine just cant seem to work the comparisons through the table.

Code: Select all

  local dx = rX - v.x
             local dy = rY - v.y               
             local distCalc = dx * dx + dy * dy
             if distCalc <= ((v.r ) + (rR ))^2 then
             collides = true
             --remove from table



regards
Last edited by Vmpwraith on Tue Aug 08, 2017 11:03 am, edited 1 time in total.
User avatar
partnano
Prole
Posts: 20
Joined: Sat Jun 11, 2016 4:53 pm
Location: twitter.com/partnano
Contact:

Re: Table comparison logic question

Post by partnano »

I guess there are multiple ways of doing this, the first one I can think of would be with flags:

To every table entry you add a flag, like to_remove for example, then you go over your table with a double for, so you compare every ball with all the other balls, you mark which ones to remove (to_remove = true) and after all that you go through the table once more and remove the marked balls.

Code: Select all

-- pseudocode-ish
-- table is a bad name btw. since lua uses it as a keyword
balls = {
	{ x = 1, y = 2, r = 3, to_remove = false },
	{ x = 1, y = 2, r = 3, to_remove = false },
	{ x = 1, y = 2, r = 3, to_remove = false }
}

-- other code

for _, ball1 in pairs(balls) do
	for _, ball2 in pairs(balls) do
		-- collision logic, be careful of comparing the same element
		if collision then ball1.to_remove = true; ball2.to_remove = true end
	end
end

for i, ball in pairs(balls) do
	if ball.to_remove then
		balls[i] = nil
	end
end

-- other code

This is obviously not the prettiest, or most performant way of doing things, but depending on what you do and how you do it, it's a good first step.
Improvements to think about (if needed) is to use a variant with table.remove instead of balls = nil, to keep up the index serial (since table.remove shifts down all following elements after the removed one) and as another improvement iterating only over following elements, to remove unnecessary redundancy (so element 1 compares with 2, 3, 4 .. / el 2 with 3, 4 .. / el 3 with 4 .. / etc)
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

Re: Table comparison logic question

Post by Vmpwraith »

I have been able, with help, to get this, and it seems to work fine for the purpose. Though I haven't tested it with high numbers of spawned rings yet.

Code: Select all

function collision()

-- remove all collided rings
  for k = #rings, 1, -1 do
     local rX = rings[k].x
     local rY = rings[k].y
     local rR = rings[k].r
     local collides
     for j = k + 1, #rings do
        local dx = rX - rings[j].x
        local dy = rY - rings[j].y
  
        local distCalc = dx * dx + dy * dy
        if distCalc <= ((rings[j].r + ringWidth) + (rR ))^2 then
           collides = true
           break
        end
     end
     if collides then
        -- do something here (erase ring[k] from the screen, etc.)
        table.remove(rings, k)
        table.remove(rings, j)
     end
  end
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 7 guests