1
votes

I am new to Farseer Physics and using version 3.3.1. I am after some help and would even be happy to receive Box2d answers just to ensure I get a response as I should then be able to convert it! -- Thanks

...After a lot of tinkering around I have managed to produce a thin vertical rectangle shape on the screen and I wish this to swing back and forth pinned at the top up to an angle I set (90 degrees would be fine for this sample).

When it is approaching the top I wish it to slow down, then fall back the way it just came, increase speed then obviously slow to a stop at the top again. Almost how a swinging pirate ship would work at a theme park.

This is the code I have so far which swings the shape, but it is seeming to lose speed on each swing eventually grinding to a halt:

float playerWidth = ConvertUnits.ToSimUnits(5), playerHeight = ConvertUnits.ToSimUnits(68);
playerPosition = ConvertUnits.ToSimUnits(-350, 0);
playerBody = BodyFactory.CreateRectangle(World, playerWidth, playerHeight, 2f, playerPosition);
playerBody.BodyType = BodyType.Dynamic;
// create player sprite based on player body
_rectangleSprite = new Sprite(ScreenManager.Assets.TextureFromShape(playerBody.FixtureList[0].Shape, MaterialType.Player, Color.Orange, 1f));
// Create swinging joint
var joint = JointFactory.CreateFixedRevoluteJoint(World, playerBody, ConvertUnits.ToSimUnits(0, -34), playerBody.Position);

If somebody could also provide the command I would need to pause the shape on a mouse click or keyboard command at it's current angle and then continue when I let go of the mouse click that would be super fantastic!

Cheers

2
Please don't crosspost on SE.user1228

2 Answers

1
votes

Usually a body swinging in this situation will take a very long time to come to a halt (in fact we have questions here sometimes asking how to make it stop...) so I'm guessing that the long thin shape could be playing a part. Like other physics engines Box2D has trouble with long thin shapes.

But that's not your question... to keep it swinging unchanged you will need to manually set the speed on each swing, either at the top or as it passes the midpoint of the swing. I think the midpoint would be safer and less noticeable.

Does this pendulum need to bump into other objects though? It might look odd if it picked up a heavier object but did not slow down, or it slowed down just until it reached the point where you top up the speed, and then suddenly got faster. If it doesn't need to react in a dynamic way you may be better off with a kinematic body which you control yourself by setting the appropriate angular velocity each frame.

A kinematic body would also make the last part of your question simpler, because you could just set the speed to zero until you're ready for it to move again. To get this effect with a dynamic body/joint setup, you would need to make a note of the current linear and angular velocity, then cancel gravity for the body in every frame while it should not move, and then reinstate the velocities to keep it moving again. But if anything bumps it during this time, that trick will fail. You could also temporarily set the joint limits (lower/upper) to the same angle to force the joint to hold the pendulum still, but I really have my doubts that a 5x68 sized body will play nicely under those constraints.

1
votes

Any non-purpose-built simulation of a pendulum is probably going to lose energy over time.

If you need the pendulum to interact with other physics objects, then keep what you have now, but as the simulation runs, adjust it to keep it going; for example, every time it swings through vertical, scale the linear and angular velocity to the same magnitude they were the first time it did so (unless it e.g. hit something in which case it shouldn't keep going like that).

If you don't need it to interact with anything, or it should not react but only push other objects, then don't make it a simulated rigid body; instead just animate it (setting the angle) based on the current time. Your physics engine probably has an option for objects which move but are not themselves moved by other bodies, and it's probably that BodyType property. (I don't offhand have the formula for the position of a pendulum over time, but I'm sure it's available somewhere.)


I see from the other copy of your question (don't do that, by the way; ask the mods to migrate your question instead) that you don't want it to interact, but do want to convert it into an un-pinned (falling) body and back. I think either strategy I describe above would work to handle that, but the first one would require less fiddling to implement.