More Ruby questions

Official forum for the Chipmunk2D Physics Library.
Post Reply
citrys
Posts: 16
Joined: Thu Nov 15, 2007 12:26 am
Contact:

More Ruby questions

Post by citrys »

Lovely library. I'm having some trouble with static shapes, though.

Is there a Ruby equivalent for INFINITY? I copied 10**1000 out of the C source, but it seems like there ought to be a constant.

I don't understand the counterclockwise winding requirement for poly shapes. At the moment, if I were to define a 2x2 square, assuming +y is down and +x is right, I'd feed the shape constructor vectors [1,1], [1,-1], [-1,-1], [-1,1], with a center of gravity at [0,0]. Is this correct?

At the moment I'm just trying to have a couple of boxes fall onto a flat line. I'm creating the line as a CP::Shape::Segment with radius 1 (the Ruby docs are missing the radius arg, BTW) and an infinite mass/moment body, defining a collision function between the boxes and the line, and adding the line to the space using #add_static_shape. Is this the correct procedure?

I'm getting some really weird behavior, and I think one of these things is tripping me up. My boxes are falling off the bottom of the screen, colliding with the "ground" line several hundred pixels too far +y, and then bouncing around like crazy.

Thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: More Ruby questions

Post by slembcke »

Code: Select all

irb(main):001:0> inf = 1.0/0.0
=> Infinity
It's lame, but I always do that. I'm really tempted to just add a Float::INFINITY constant.

Yes, your winding is correct. The counterclockwise winding requirement is because of the way I calculate normals. The Ruby code probably should throw an exception for an incorrect winding or a concave poly. (I also probably should have a function for transforming a set of points into a convex hull, the list goes on...)

You only have to define a collision function if you want to be notified of the collision. It's not necessary if all you want is a "normal" collision to happen.

Not sure what's causing your final issue. Could you be more specific or post up some of the code? What are you friction/elasticity values? What are the masses of the objects and static body
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
citrys
Posts: 16
Joined: Thu Nov 15, 2007 12:26 am
Contact:

Re: More Ruby questions

Post by citrys »

Aha! I went looking for CP::INFINITY; I didn't know about the divide-by-zero trick. My head's hardwired to avoid those at all costs. =) Thanks!

On polygon winding, I think your docs say to wind the vertices so that "up" is at 0 radians (+x). How should that affect the order in which I supply my points?

On transforming points to a hull, I've added a #to_verts to Rubygame's Rect class to do something similar. The Array class could probably be extended that way, too.

Won't two objects pass through each other if you don't explicitly call space.add_collision_func(collision_type_1, collision_type_2)? If I don't need to be notified, I just don't supply a block when I "declare" collidable objects with #add_collision_func.

At the moment, I think my static body has a near-infinite mass/moment, and each of the boxes has a mass of 10 and a moment of 150. I don't have a good feel for the units yet. I'm sort of experimenting with the numbers until I find a combo that feels right on screen. I think I've left friction/elasticity at their defaults, but I'll have to check when I get a chance to work on the code again.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: More Ruby questions

Post by slembcke »

citrys wrote:On polygon winding, I think your docs say to wind the vertices so that "up" is at 0 radians (+x). How should that affect the order in which I supply my points?
Not sure I follow. Where did I say that?
citrys wrote:Won't two objects pass through each other if you don't explicitly call space.add_collision_func(collision_type_1, collision_type_2)? If I don't need to be notified, I just don't supply a block when I "declare" collidable objects with #add_collision_func.
No. It's actually implemented where there is a default collision pair function that accepts all collisions. You should only define a collision pair function when you want to specify that collisions should never happen (by specifying nilI think), or to conditionally reject collisions or do something fancy with the information.
citrys wrote:each of the boxes has a mass of 10 and a moment of 150
That is probably your problem. You don't really want to guess the moment of inertia. There is a function CP.moment_for_poly that should help. http://files.slembcke.net/chipmunk/doc/ ... ml#M000005
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
citrys
Posts: 16
Joined: Thu Nov 15, 2007 12:26 am
Contact:

Re: More Ruby questions

Post by citrys »

slembcke wrote:Where did I say that?
Oops, that was my mistake... There was a comment to that effect in the Gosu/Chipmunk example source code hosted at the Gosu site. Nevermind. =)
slembcke wrote:You should only define a collision pair function when you want to specify that collisions should never happen (by specifying nilI think), or to conditionally reject collisions or do something fancy with the information.
Ah, I misunderstood. I also didn't realize that you could conditionally reject collisions, that's handy. I see it now in the C documentation; time to get more familiar with that resource.

I don't know how I missed CP.moment_for_poly. Thanks for the pointer.
citrys
Posts: 16
Joined: Thu Nov 15, 2007 12:26 am
Contact:

Re: More Ruby questions

Post by citrys »

CP.moment_for_poly worked wonders. My 4 boxes are falling and stacking properly onto the flat, invisible ground (a static line segment shape). I was having the "rotated-by-one-pixel" problem outlined in a previous thread, but solved it by giving my sprites a one-pixel transparent border.

Unfortunately, now I've got the other problem mentioned in that thread. I like to see the boxes bounce a bit, so I've experimented with elasticities ranging from 0.25 to 0.75. After the boxes land, stacked, and their high-magnitude bouncing has finished, each box will sort of vibrate in place by a pixel every couple of seconds. If I wait long enough, sometimes these pixel vibrations will build up to an impulse large enough to rotate one of the boxes a bit. It's as if some part of the stack's energy is never completely depleted, or the collision handler is continually adding energy to the system. The Chipmunk demos don't seem to have this problem, but I haven't checked their source code to see what's going on. I'd the stack to eventually settle completely.

I've tried running space.iterations as high as 100 per one of the recommendations in the previous thread, but it didn't seem to make a difference.

My ground object has an elasticity of 0, and everything in the scene has a coefficient of friction of 0.9. The space has gravity of 9.8 and a damping factor of 0.9, and I'm stepping the space 6 times with a delta of 1/60th of a second.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: More Ruby questions

Post by slembcke »

Well, you don't want any elasticity if you want things to stack nicely. I need to add a separate collision and contact phase a la "Nonconvex Rigid Bodies with Stacking" (Google it) in order to allow elastic objects to stack nicely. The other problem I mentioned is that when objects originally land, they will generate impulses that are too large. Unfortunately this "bounce" that occurs is a tradeoff between the initial and eventual accuracy of the contact solution.

If you set the elasticities to 0 and use more iterations, it should work fine. If not, then I have no idea what the issue is.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
citrys
Posts: 16
Joined: Thu Nov 15, 2007 12:26 am
Contact:

Re: More Ruby questions

Post by citrys »

I solved the problem by having the shape elasticities decay over time after the first collision. The boxes start with e=1.25, and this decays to 0 over 2 seconds. This provides a delightful bit of bouncing when the boxes first stack, and it settles down very quickly.

I've actually just been running this animation over and over again because it's so much fun to watch. =) The boxes start out with somewhat random rotations, so the stack is always different.
User avatar
tartley
Posts: 37
Joined: Thu Jun 12, 2008 5:01 pm
Location: London, England
Contact:

Re: More Ruby questions

Post by tartley »

Shouldn't elasticities always lie between 0 and 1?

As I understand it the product of the e value for two colliding entities determines how much fast they bounce away from each other, compared to before the collision. So with e1 of 0.5 and e2 of 0.6, the collision overall 3 will be 0.5 * 0.6 = 0.3, hence they will bounce with 0.3 times the speed (or energy?) that they approached.

Anyhow, the upshot is that e values of >1 will result in things bouncing away faster than they struck each other, and might very well result in the long-lived vibrations you report.
[color=#808080]Tartley - Jonathan Hartley, [url]http://tartley.com[/url]
Using Pymunk (Chipmunk's Python bindings) for a game project:
[url]http://code.google.com/p/sole-scion[/url][/color]
Post Reply

Who is online

Users browsing this forum: No registered users and 33 guests