Page 1 of 1

Newton's Cradle sim problem.

Posted: Sat May 28, 2011 9:17 am
by moci
Hi there,

Inspired by a problem in a 3D engine (in a 3D software package) I want to code the Cradle simulation myself. As these are the first bits of code I'll do in lua/love I'm sure to make mistakes. This is, of course, a purely physics based sim.

Problems:
- The circle that should initiate the sim is not where it should be when the sim starts. If I turn off gravity it is in the correct place. Anywhere from 1 to 320 gravity in the Y-direction and it will "jump" back to it's coded position. >320 breaks it entirely.
- The circle that initiates the sim pushes everything away, and not just the last one. Is this because of how Box2D works?

I'm setting the mass with the function getMassFromShapes(), which was the proper way of doing it (that's what I read on the wiki)?
The rectangles have no mass so they can not fall, and the circles have a DistanceJoint to the rectangles.

Re: Newton's Cradle sim problem.

Posted: Sat May 28, 2011 9:48 am
by ivan
Several things.
Your circles have a radius of 30. You are trying to simulate a small sphere, but in Box2D, 30 units means 30 meters. Box2D has some constants that play a major role depening on the scale of your objects and that's why your shperes are moving soooo slowly.
So ya, make your spheres smaller and draw them using a x2 or x4 scale, then the simulation might work.

setMassFromShapes is used when you specify a density for your shapes while in your script you are specifying the mass of the sphers explicitly.

Secondly, you may want to specify a restitution and friction value for your shperes.
I suggest looking up setRestitution and setFriction on the wiki.

When your gravity has a super-high value it may pull the distance joint apart.
Personally, I would use a 'revolute' joint in this case:

Code: Select all

joint = love.physics.newRevoluteJoint(bodyCir, bodyRec, x, y)
Lastly, Box2D doesn't like variable time steps. Look up 'accumulators' to avoid code like:

Code: Select all

world:update ( dt )

Re: Newton's Cradle sim problem.

Posted: Sat May 28, 2011 10:17 am
by moci
Thanks for the reply. I'll try updating the code later! ...maybe someone should update the wiki physics tutorial... :ehem:

Re: Newton's Cradle sim problem.

Posted: Sat May 28, 2011 10:47 am
by bartbes
ivan wrote: Your circles have a radius of 30. You are trying to simulate a small sphere, but in Box2D, 30 units means 30 meters. Box2D has some constants that play a major role depening on the scale of your objects and that's why your shperes are moving soooo slowly.
That shouldn't be the case, love does some scaling automatically because this mistake was very frequent. If I remember correctly the default scale is 30 px/m, so this means a radius of 1 meter, which is still too big, but not as much as you made it seem.

Re: Newton's Cradle sim problem.

Posted: Mon May 30, 2011 5:46 pm
by moci
I've tried removing the update(dt) to a fixed step

Code: Select all

function love.update(dt)
	accStep = accStep + dt;
	
	if accStep >= phyStep then
		accStep = accStep - phyStep
		world:update(phyStep)
	end
end
And to make the spheres "smaller" I just increased the pixelsPerMeter, which *should* have the sam effect.
I'll come back to this once I've used love (and the physics) more.

Re: Newton's Cradle sim problem.

Posted: Mon May 30, 2011 6:28 pm
by ivan
Yep, that's how accumulators work except that you may want to change the 'if' check to a 'while' loop:

Code: Select all

function love.update(dt)
	accStep = accStep + dt;
	
	while accStep >= phyStep do
		accStep = accStep - phyStep
		world:update(phyStep)
	end
end
This should keep your sim running at the same speed on slower machines.