Share via


Doppler Two

Last time, I talked about a WPF application to demonstrate the Doppler effect; this time I'm going to look at a Win8 app. The starting point is the C# Windows Store application project template, of course, and then almost exactly the same Xaml content as before. The one and only change is that Win8 apps don't support bitmap effects, custom or otherwise, so the contrast enhancing blur from last time isn't available in this version.

There are a few small changes in the C# code, to deal with variations in the animation and timer APIs - this application isn't doing anything with files, streams, etc. so there are no synchronous to asynchronous changes, just these minor tweaks. To begin, the DispatcherTimer constructor is different; instead of calling a multi-parameter constructor to set it all up, I have this collection of lines:

             this.timer = new DispatcherTimer{ Interval = TimeSpan.FromSeconds(0.01) };
            this.timer.Tick += Tick;
            this.timer.Start();

There are similar small scale tweaks to CreateWave:

         private void CreateWave(Point c)
        {
            var wave = new Path
            {
                Stroke = brush,
                Data = new EllipseGeometry { Center = c }
            };
 
            this.Surface.Children.Insert(0, wave);
            waves.Add(wave);
 
            var d = new Duration(TimeSpan.FromSeconds(2));
            var sb = new Storyboard { Duration = d };
 
            const double max = 200;
 
            var sizeAnimX = new DoubleAnimation { From = 11, To = max, Duration = d, EnableDependentAnimation = true };
            sb.Children.Add(sizeAnimX);
            Storyboard.SetTarget(sizeAnimX, wave);
            Storyboard.SetTargetProperty(sizeAnimX, "(Path.Data).(EllipseGeometry.RadiusX)");
 
            var sizeAnimY = new DoubleAnimation { From = 11, To = max, Duration = d, EnableDependentAnimation = true };
            sb.Children.Add(sizeAnimY);
            Storyboard.SetTarget(sizeAnimY, wave);
            Storyboard.SetTargetProperty(sizeAnimY, "(Path.Data).(EllipseGeometry.RadiusY)");
 
            var strokeAnim = new DoubleAnimation { From = 5, To = 9, Duration = d, EnableDependentAnimation = true };
            sb.Children.Add(strokeAnim);
            Storyboard.SetTarget(strokeAnim, wave);
            Storyboard.SetTargetProperty(strokeAnim, "StrokeThickness");
 
            var opacityAnim = new DoubleAnimationUsingKeyFrames { EnableDependentAnimation = true };
            opacityAnim.KeyFrames.Add(new LinearDoubleKeyFrame { Value = 0.7, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0)) });
            opacityAnim.KeyFrames.Add(new LinearDoubleKeyFrame { Value = 0.6, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1.8)) });
            opacityAnim.KeyFrames.Add(new LinearDoubleKeyFrame { Value = 0.0, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2)) });
            sb.Children.Add(opacityAnim);
            Storyboard.SetTarget(opacityAnim, wave);
            Storyboard.SetTargetProperty(opacityAnim, "Opacity");
 
            sb.Completed += (sender, e) =>
            {
                var w = this.waves[0];
                this.waves.RemoveAt(0);
                this.Surface.Children.Remove(w);
            };
 
            sb.Begin();
        }

At the end of this, I have something that looks like the non-blurred version of the WPF application, except that it runs realllllyyyyy reaaallllllyyyyyy slowly. In fact, adding a bit of time keeping to the timer tick routine shows that it's being called a lot less than 100 times a second - even changing the timeout to be much shorter has little effect, suggesting that something is causing the foreground thread (the UI one) to stall - probably all those heavyweight animations. Anyway, even at a slow speed, it's pretty obvious that the lack of blur effect makes this a very poor variant of the program, so I'll not put much time into investigating the speed issues at the moment.

It looks like the only way to get something effect-like is to switch to DirectX, which means brushing up on my C++ a bit. Next time...