Posts Tagged with Circular Rotation

Silverlight Circular Collision Animation

Building on the sample I created on Circular Motion, in this example I add a concept of collision.  In physics, deflection is the event that occurs where an object collides and bounces off of another surface.  In my example, two spheres collide at a given X/Y causing each ball to reverse direction and maintains its current speed and angle.

Just as in my previous example I use a single DispatcherTimer and a generic collection of UserConrols. To keep track of the direction that each ball is traveling I added a boolean property to my “Ball” user control to determine if it was rotating clockwise.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void _timer_Tick(object sender, EventArgs e)
{
    foreach (Ball ball in _balls)
    {
        double x = 0.0
        double y = 0.0
        double angle = ball.Rotate.Angle
 
        CalculatePosition(ball.Clockwise, ref x, ref y, ref angle, 1)
        //update the position of the ball
        ball.Rotate.Angle = angle
        ball.Translate.X = x
        ball.Translate.Y = y
 
        //check to see if a collision has occured
        if (ball.CollisionType == Ball.CollisionTypes.Deflect)
        {
            foreach (Ball ball2 in _balls)
            {
                if (!ball.Equals(ball2))
                {
                    double b2X = 0.0
                    double b2Y = 0.0
                    double b2A = ball2.Rotate.Angle
                    //if we wait until the two balls are at the same X/Y then the balls
                    //will have overlapped.  Instead, predict by looking 5 degrees ahead 
                    //then switching direction.
                    CalculatePosition(ball2.Clockwise, ref b2X, ref b2Y, ref b2A, 5)
                    if (Math.Ceiling(x).Equals(Math.Ceiling(b2X))
                        &amp&amp Math.Ceiling(y).Equals(Math.Ceiling(b2Y)))
                    {
                        ball.Clockwise = !ball.Clockwise
                        ball2.Clockwise = !ball2.Clockwise
                        //ball.sound.Position = TimeSpan.FromMilliseconds(0)
                        //ball.sound.Play()
                        break
                    }
                }
            }
        }
    }
}

As you can see in the code above, I am doing a quick check to see if my rotating ball is defined to deflect upon collision. In this example, this is the only type of collision supported. In the future, I might add things like exploding on impact or magnetism upon the collision.

The first step in the circular rotation is to move each ball to its new X/Y position. Once moved, I check to see if any other balls overlap its current X/Y location. To make the collision more realistic (no overlap), I predict where each additional ball will exist 5 degrees forward of its current angle. This allows me to simulate the ball just touching each other before reversing directions.

Code: CircularCollision.zip

Silverlight Circular Motion Animation

In this sample I demonstrate how to take a series of UserControls (Simple ellipses) and rotate each in a counter-clockwise circular motion.

The first step in the process is to define a user control and expose both the TranslateTransform and RotateTransform from the TransformGroup object.  This allows us to rotate and move each user control on a specified tick (DispatcherTimer tick).  The timer is controlled by the main page.xaml.

In this example, I start with a single “ball”, begin rotating it, and every second add an additional ball to the animation.  Instead of having each user control have its own animation, I have chosen to use a single DispatcherTimer that iterates over a generic collection of UserControls, to generate the circular motion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Page_Loaded(object sender, RoutedEventArgs e)
{
    _centerX = this.Width/2
    _centerY = this.Height / 2
    _timerAnimation.Interval = TimeSpan.FromMilliseconds(20)
    _timerAnimation.Tick += new EventHandler(_timer_Tick)
 
    _timerInserter.Interval = TimeSpan.FromSeconds(1)
    _timerInserter.Tick += new EventHandler(_timer2_Tick)
 
    PlaceBall("Bo")
 
    _timerAnimation.Start()
    _timerInserter.Start()
}

In this handler I determine the center of my circle, place the first control, and define two DispatcherTimers, one for the animation, and one for inserting additional controls into the main Grid. Since the speed of rotation is consistent for each “ball”, I am able to use a single timer which iterates over a generic collection of UserControls. Each time the Animation timer fires, I will call the following method.

1
2
3
4
5
6
7
8
9
10
11
12
void _timer_Tick(object sender, EventArgs e)
{
    foreach(KeyValuePair<string ,BALL> ball in _balls)
    {
        ball.Value.Rotate.Angle -= 5
        ball.Value.Rotate.Angle %= 360
        // Transform angle degrees to radian value
        double radians = ((ball.Value.Rotate.Angle / 180) * Math.PI)
        ball.Value.Translate.X = _centerX + Math.Cos(radians) * _radius
        ball.Value.Translate.Y = _centerY + Math.Sin(radians) * _radius
    }
}

The math in this method is pretty basic, on each tick I rotate the ball between 1 and 360 degrees. The angle I am looking for is the remainder of the angle of my rotation from 360 degrees. To calculate this, I apply the modulus assignment operator to my new angle. To determine the appropriate X and Y position I transform my angle into Radians and apply a bit of trigonometry to calculate X/Y based on the sin and cosine of the radian. Thanks again to Paul Ortchanian flash site, reflektions for a Flash sample I could translate into Silverlight.

Code: CircularMotion.zip