# How simulate the return effect of the wheel of fortune needle

I am trying to create a spinning wheel which slows down after a specific time. I managed to simulate the slowdown of the wheel but I need also to put a needle which go up and down with an angle of 45°.

Here my wheel with the needle :

My wheel turn in clockwise and the needle (object in red in the above scheme) rotate in counter clockwise.

Once done the needle back to his original position slower than the previous movement.

The code i wrote :

// Once 3 seconds are passed, the speed rotation start to decrease
If RealMillisecs() -_fRotateTime > 3000 Then
If _fSpeedRotation > 0 Then
_fSpeedRotation = _fSpeedRotation - 0.001
Else
_fSpeedRotation = 0
EndIf
EndIf

_fWheelRotation -= _fSpeedRotation * dt.frametime

// If the needle is not going back to its orginal position then is going up
If not _bAnimBackNeedle Then
_fNeedleRotation = _fWheelRotation Mod 45 * -1

/* If its previous rotation greater than actual position
it's mean that the needle has reach its max angle (45)*/
If _fNeedleRotation < _fPreviousNeedleRotation Then
_bAnimBackNeedle = True // The going back animation to true
EndIf

_fPreviousNeedleRotation = _fNeedleRotation
EndIf

// If the going back animation is set to true or the wheel has stopped to turn
// get the needle back to its position at constant speed
If _bAnimBackNeedle Or _fSpeedRotation = 0 Then
_fNeedleRotation -= 0.5 * dt.frametime
If _fNeedleRotation <= 0 Then
_bAnimBackNeedle = False
EndIf
EndIf


My code doesn't make what i hope.

The needle doesn't come back to its original position when the wheel is stopped.

How can I managed the code to have the wheel and the needle with a good behaviour?

How about letting box2d do the work for you? It wasn't too difficult for me to setup everything in RUBE:

There are two major parts: the wheel and the needle.

## Wheel

1. First there is a base. In this case the base is a static body with a square fixture.
2. The wheel is attached to the base via a revolute joint. This joint allows the wheel to spin freely about the center.
3. The wheel consists of 33 circle fixtures: 1 big wheel and 32 pegs. I created the pegs using a simple Rubescript. The pegs and wheel are on different bitplanes, allowing the needle to collide only with the pegs and not the wheel. One other ajustment is that the boolean isBullet needs to be true; the reason for this is that the pegs can move very quickly when the wheel is spinning fast and sometimes the peg-needle collision will be missed by box2d. If the isBullet flag is set, box2d resolves those cases correctly.

## Needle

1. The needle is a body with a single fixture in the shape of a kite. I have increased the friction a little on the needle fixture and peg fixtures. This way when the needle rubs against the pegs it will eventually slow the wheel down. We also need to set the bitplane and bitmask of the needle so it only collides with the pegs.
2. The needle can rotate about the revolute joint. The second body for the revolute joint is the static body from before.
3. Two opposing distance joints act as springs to try and keep the needle in place. The damping parameter on the distance joints also helps dissipate the wheel's energy.

## Result

You get a lot of nice realisms when you go with a physics-based solution. Most notably, you can let the player actually spin the wheel with a swipe of their finger or a click+drag of their mouse. Also, it's easy to do things like add more needles for more players if you want to.

I know there is a lot of stuff here specific to box2d which you might not be familiar with but it is well worth learning IMO. The spinning wheel is an excellent way for you to get started.

• Mile. Thanks for this detailed answer. It' works really great with box 2D, i thought that use box 2D would be too difficult to understand and implement with my code. But with RUBE it's seems more easly. – Moerin Mar 27 '14 at 19:57

As a side-note, your use of EndIf makes me think you're trying to do this in PHP - which makes no sense whatsoever, but whatever. It would help if you could clarify what language you're working with.

But concerning the mathematics alone...

The two events you need to catch are when the edge of the space contacts the needle and when the edge breaks contact with the needle.

if( (fWheelRotation + 7) % 45 < 6 )
{
fNeedleRotation = ((((367 - fWheelRotation) % 45)^2) * 1.8);
} else {
if( fNeedleRotation < 0 )
{
fNeedleRotation = 0;
}
else if( fNeedleRotation < 46 )
{
fNeedleRotation -= 10;  // Adjust this value to control return speed
// Be sure to allow a small overshoot
}
}


Due to how close to the threshold you're operating, the offset offers a buffer. Without the buffer, a fast-spinning wheel could bypass the (much smaller) trigger zone(s) without the needle responding.

I could offer a slightly more elegant solution if you included what language you're using.