This project has moved and is read-only. For the latest updates, please go here.

Ball bouncing problem

Nov 15, 2008 at 7:07 PM
Edited Nov 15, 2008 at 7:48 PM

I'm bouncing a ball on a flat ground. Depending on the value of circleBody.Rotation, the ball starts to rotate and bounces to the side (random to which side).
(The Rotation property only sets the angle for the circle not the actual rotation, right?)

All I want is a ball that behaves like a ball when bouncing on some rectangles. Is this possible?

I'm guessing this is due to the fact that a circle is aproximated by a polygon, but should the bouncing realy be this bad? 

Is there some settings I could change?

To see the problem change the following code in Demo3.cs (line 56) in the GettingStartedSilverlight project:

 public override void Initialize()
    physicsSimulator =
new PhysicsSimulator(new Vector2(0, 100));

    Body circleBody = BodyFactory.Instance.CreateCircleBody(physicsSimulator, 20, 1);
    circleBody.Position =
new Vector2(650, 6);
    circleBody.Rotation = 0.2f;
    Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator, circleBody, 20, 40);
    circleGeom =
GeomFactory.Instance.CreateCircleGeom(physicsSimulator, circleBody, 20, 40);
    circleGeom.RestitutionCoefficient = 1.0f;
    AddCircleToCanvas(circleBody, 20);

Nov 15, 2008 at 7:18 PM
There are some properties that you can change, to change the behavior of the ball.

RestitutionCoefficient - Makes the ball more bouncy. 0 = no bounce. 1 = perfect bounce
RotationalDragCoefficient - The rotational drag of the ball.
FrictionCoefficient - The friction of the ball. If it's a teflon ball, it have a low friction, if it's a rubber ball, it has high friction.

The Rotation property is the current rotation in radians. If you supply a value larger than 6.2 (PI * 2) the ball will add one to the Revolutions property.
Nov 15, 2008 at 7:30 PM
Thanks for the fast answer (I edited my post to add the code before I saw your answer)
I have tried to change the coefficients you sugge´sted but nothing helps.

The bounce to the side is about 200 from a ball that falls straight down from a height of 700.
Nov 15, 2008 at 7:35 PM
in LoadFloor(), change

_floorGeom.RestitutionCoefficient = .2f;

to this:

_floorGeom.RestitutionCoefficient = 1f;

This will make the ball bounce higher.
Nov 15, 2008 at 7:47 PM
Ok, but I want the ball to bounce straight up, not higher.
The problem is that the ball bounces off to the side.
Nov 15, 2008 at 8:31 PM
Oh, sorry. I'm too used to people asking for bounciness :)

What you want is to set the number of edges to a lower number. And a number where the vertices are placed such, that one is placed at the bottom.

Try with 12 edges, that should solve your problem. Oh... and you are creating the Geom twice. You only need the first line of those 2:

 Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator, circleBody, 20, 40);
    circleGeom =
GeomFactory.Instance.CreateCircleGeom(physicsSimulator, circleBody, 20, 40);
Nov 15, 2008 at 9:12 PM
Thanks for the answer but it didn't work any better.

Any other suggestions?
Nov 15, 2008 at 10:51 PM
You did remember to remove the circleBody.Rotation = 0.2f; right? It works here.
Nov 16, 2008 at 7:47 AM
Edited Nov 16, 2008 at 7:49 AM
No I did not remove circleBody.Rotation = 0.2f.
That line is there to illustrate the problem.

The ball should bounce straight up regarless of the Rotation setting. Otherwise I cant trust the physics engine and that is the whole problem.
Nov 16, 2008 at 11:59 AM
You can't get a perfectly round ball. As you said, it's because it's build from polygons. That's the way it works in all physics engines. Using a physics engine requires a lot of tweaking to get the desired behavior. If your problem is that it does not bounce perfectly off the ground every time, you will need to adjust the rotation of the ball relative to the plane it's about to hit.

You can adjust the angle of a body using the AngleJoint. If you also want to draw an uneven texture on to the ball, you can track the rotation manually and draw the texture rotated.
Nov 16, 2008 at 12:57 PM
Ok, thanks for the answer, I realy appreciate it.

I dont realy want to fix the angle with a joint because I like that the ball reacts to angularvelocity when hitting the ground, and I also want it to hit tilted rectangles which makes it hard to calculate the correct angle when hitting the rectangle.

Do you think it would be difficult to hack the engine to calculate a "perfect" circle to plane collision when you know that the shape realy is a circle?
Nov 16, 2008 at 6:59 PM
I found some settings that seems to get better results (not perfect but maybe ok):

physicSimulator.MaxContactsToDetect = 10;
(and 40 edges for the circle)

I don't know what it does to the speed of the engine and I don't know if I need as high value as 10 (5 seems to work ok also).
Nov 16, 2008 at 8:42 PM
The default for MaxContactsToDetect is 3 and Resolve is 2.

MaxContactsToDetect is used inside the narrow phase collision detection, to define the maximum number of contacts to detect, per geometry collision.
MaxContactsToResolve is also used inside the narrow phase. It's used to define the maximum number of contacts to have, after the contacts are sorted.

Setting those two to a high number, can cause a loss in performance. But it might make the engine more stable.

If you drop one box with 100 vertices at the bottom onto a nother box with 100 vertices on top, you would normally have a total of 200 contacts in a headon collision. But you actually only need a few (2-4) to make the collision reliable. Anymore than that is a waste.

In your case, you have a ball were a total of 1-3 contacts can be resolved at one time, depending on how deep the ball is penetrating the object it hits (high velocity = high penetration).

I'm not sure about hacking the engine to make a perfect ball. The only thing I can figure out on how to do that, is by having a polygon right at the spot where it collides. You could perhaps make a perfect ball using some algorithm to calculate a collision outside of the vertices at an arc.
Nov 17, 2008 at 2:17 AM
@mccrille - try creating the Geom for your ball with 360 edges. This works for me.
Nov 17, 2008 at 8:00 AM
mattbettcher - The bounces gets realy realy bad for me when using 360 edges. ( radius 40, MaxContactsToDetect = default, MaxContactsToResolve=default)
Do you use other settings to get it to work?

Nov 17, 2008 at 8:25 PM
@mccrille - I think I understand your problem. Right now this is impossible to fix until real circles are implemented into Farseer, if ever. If you really need this much accuracy you might be better off with another engine. Box2DX is a C# ported version of Box2D. It has real circles and has a lot more features, but is considerably more difficult to use. Good luck.