I have had some success with this problem, and my solution was certainly a "compromise" on the exact physics. That is almost always desirable, anyway.
My method was to maintain a fixed radius from the grapple point, and only update a speed scalar. I did not store a velocity vector; I will explain. Then each frame:
- Determine player direction as a normal vector perpendicular to the direction from center of rotation to position.
- Calculate total acceleration, (gravity, player input, etc.) in the direction of motion, and reduce that to a scalar value.
- Modify speed scalar by the acceleration scalar.
- Move the player in the direction of motion from step 1, with distance according to the speed scalar.
- Modify position such that the stored radius is maintained. (Find the new direction to the center, and reduce the distance to that point to what it should be.)
- Determine the new direction of motion and reduce speed by its dot product with the old direction (aka the cosine of the angle between them).
That last step will be a very high fraction of unity for small angle changes. It will slow the player down, but the deceleration will be almost imperceptible for slow speeds, and far more noticeable for higher speeds. It will appear as though you planned it that way, almost as if you were calculating a drag force. :)
It is conceivable to allow the swing radius to change, but I would recommend making that a separate system with completely independent, more arcade-like motion. In any case, it would also yield weird effects. For example, it would introduce physics abuses like those the ninja rope races in the recent versions of worms:
You will need to mitigate these problems as you see fit. But then again, they made for fun gameplay, so try it and see what happens.