BounceEase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Animation / BounceEase.cs / 1305600 / BounceEase.cs

                            //------------------------------------------------------------------------------ 
//  Copyright (c) Microsoft Corporation, 2008
//
//  File: BounceEase.cs
//----------------------------------------------------------------------------- 

using MS.Internal; 
 
namespace System.Windows.Media.Animation
{ 
    /// 
    ///     This class implements an easing function that can be used to simulate bouncing
    /// 
    public class BounceEase : EasingFunctionBase 
    {
        public BounceEase() 
        { 

        } 

        /// 
        /// Bounces Property
        ///  
        public static readonly DependencyProperty BouncesProperty =
            DependencyProperty.Register( 
                    "Bounces", 
                    typeof(int),
                    typeof(BounceEase), 
                    new PropertyMetadata(3));

        /// 
        /// Specifies the number of bounces.  This does not include the final half bounce. 
        /// 
        public int Bounces 
        { 
            get
            { 
                return (int)GetValue(BouncesProperty);
            }
            set
            { 
                SetValueInternal(BouncesProperty, value);
            } 
        } 

        ///  
        /// Bounciness Property
        /// 
        public static readonly DependencyProperty BouncinessProperty =
            DependencyProperty.Register( 
                    "Bounciness",
                    typeof(double), 
                    typeof(BounceEase), 
                    new PropertyMetadata(2.0));
 
        /// 
        ///     Specifies the amount of bounciness.  This corresponds to the scale difference between a bounce and the next bounce.
        ///     For example, Bounciness = 2.0 correspondes to the next bounce being twices as high and taking twice as long.
        ///  
        public double Bounciness
        { 
            get 
            {
                return (double)GetValue(BouncinessProperty); 
            }
            set
            {
                SetValueInternal(BouncinessProperty, value); 
            }
        } 
 
        protected override double EaseInCore(double normalizedTime)
        { 
            // The math below is complicated because we have a few requirements to get the correct look for bounce:
            //  1) The bounces should be symetrical
            //  2) Bounciness should control both the amplitude and the period of the bounces
            //  3) Bounces should control the number of bounces without including the final half bounce to get you back to 1.0 
            //
            //  Note: Simply modulating a expo or power curve with a abs(sin(...)) wont work because it violates 1) above. 
            // 

            // Constants 
            double bounces = Math.Max(0.0, (double)Bounces);
            double bounciness = Bounciness;

            // Clamp the bounciness so we dont hit a divide by zero 
            if (bounciness < 1.0 || DoubleUtil.IsOne(bounciness))
            { 
                // Make it just over one.  In practice, this will look like 1.0 but avoid divide by zeros. 
                bounciness = 1.001;
            } 

            double pow = Math.Pow(bounciness, bounces);
            double oneMinusBounciness = 1.0 - bounciness;
 
            // 'unit' space calculations.
            // Our bounces grow in the x axis exponentially.  we define the first bounce as having a 'unit' width of 1.0 and compute 
            // the total number of 'units' using a geometric series. 
            // We then compute which 'unit' the current time is in.
            double sumOfUnits = (1.0 - pow) / oneMinusBounciness + pow * 0.5; // geometric series with only half the last sum 
            double unitAtT = normalizedTime * sumOfUnits;

            // 'bounce' space calculations.
            // Now that we know which 'unit' the current time is in, we can determine which bounce we're in by solving the geometric equation: 
            // unitAtT = (1 - bounciness^bounce) / (1 - bounciness), for bounce.
            double bounceAtT = Math.Log(-unitAtT * (1.0-bounciness) + 1.0, bounciness); 
            double start = Math.Floor(bounceAtT); 
            double end = start + 1.0;
 
            // 'time' space calculations.
            // We then project the start and end of the bounce into 'time' space
            double startTime = (1.0 - Math.Pow(bounciness, start)) / (oneMinusBounciness * sumOfUnits);
            double endTime = (1.0 - Math.Pow(bounciness, end)) / (oneMinusBounciness * sumOfUnits); 

            // Curve fitting for bounce. 
            double midTime = (startTime + endTime) * 0.5; 
            double timeRelativeToPeak = normalizedTime - midTime;
            double radius = midTime - startTime; 
            double amplitude = Math.Pow(1.0 / bounciness, (bounces - start));

            // Evaluate a quadratic that hits (startTime,0), (endTime, 0), and peaks at amplitude.
            return (-amplitude / (radius * radius)) * (timeRelativeToPeak - radius) * (timeRelativeToPeak + radius); 
        }
 
        protected override Freezable CreateInstanceCore() 
        {
            return new BounceEase(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK