Page 1 of 1

HardonCollider polygon:unpack() question

Posted: Tue Apr 09, 2013 6:06 am
by stcredzero
Hey. I'm using HardonCollider to glom together some almost-squares to form pentominoes. I'm using Polygon.mergeWith() with slightly perturbed coordinates to make this work. (So each square in the pentomino has non-co-linear edges with its neighbors.) So when I use Polygon.unpack() I get something like:

60.01 20.01 60 40.01 40 40 20 40.01 20.01 60.01 0.01 60 0 40 0.01 20 20.01 20.01 20 0.01 40 0 40.01 20

I would like to take the floor() of all of these pairs of numbers and turn them into another Polygon. That would make the example above into:

60 20 60 40 40 40 20 40 20 60 0 60 0 40 0 20 20 20 20 0 40 0 40 20

I'm confused how to do this, however. The type of the value returned from Polygon.unpack() is "number". What gives? I get an error if I try to iterate across that wit ipairs(). How do I turn this into an array of numbers that I can use to create a PolygonShape?

Re: HardonCollider polygon:unpack() question

Posted: Tue Apr 09, 2013 9:21 am
by Robin
This is what Lua calls a "list". It is a very unstable thing by itself, but if you wrap it inside a table constructor (as in {polygon:unpack()}, you have a table with the values you need.

Re: HardonCollider polygon:unpack() question

Posted: Tue Apr 09, 2013 10:24 am
by Roland_Yonaba
Robin's totally right. Actually, polygon:unpack() behaves like a Lua function, unpack (actually, it uses it indeed). Unpack() just explodes an array, and makes use of the fact that Lua's function can return multiple values to yield all items found in the table at the same time.

Calling type on the returned values from unpack will actually return the type of the very first item in the array passed to unpack, as type function will only catch the first returned value, not the others.

Code: Select all

print(type(unpack({'a',1,2}))) --> string
print(type(unpack({1,2}))) --> number
A common way to catch all values returned from unpack is, as Robin already said, wrap them into table constructors.

Code: Select all

local t = {1.01, 2.02, 3.03}
local retValues = {unpack(t)}
In your case, though, unpack becomes Poygon:unpack()
From now on, it's easy as pie to iterate through the new table with ipairs and floor each single value.

Code: Select all

for _,v in ipairs(retValues) do v = math.floor(v) end

Re: HardonCollider polygon:unpack() question

Posted: Tue Apr 09, 2013 8:07 pm
by stcredzero
Roland_Yonaba wrote:
Calling type on the returned values from unpack will actually return the type of the very first item in the array passed to unpack, as type function will only catch the first returned value, not the others.

Code: Select all

for _,v in ipairs(retValues) do v = math.floor(v) end
Re: type returning type of the first item in a table: I guess that's one Lua gotcha that got me!

I came up with something similar to the code above:

Code: Select all

	for i,j in ipairs(poly.vertices) do
		j.x = math.floor(j.x)
		j.y = math.floor(j.y)
	end
I'm modifying things in place, but I should be able to get away with it as an initialization action. I won't be modifying coordinates after that.

Re: HardonCollider polygon:unpack() question

Posted: Tue Apr 09, 2013 11:56 pm
by Roland_Yonaba
Sorry, I had to fix a mistake in the snippet I gave above:

Code: Select all

for i,v in ipairs(retValues) do 
  retValues[i] = math.floor(v)
end
You actually need to assign the new values this very way.