Click here to Skip to main content
15,796,102 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everybody,
I'm working on an animated map control, where lines represent roads and ellipse objects are animated along these lines. Paths are currently drawn in Expression Blend, but in future they should be generated in code. These paths are applied in Expression to moving paths.

My current code looks like this:
private void ApplyAnimationToElement(string animationName, DependencyProperty targetProperty, FrameworkElement target)
            DoubleAnimationUsingPath anim = ((DoubleAnimationUsingPath)Resources[animationName]);
            AnimationClock animClock = anim.CreateClock();
            target.ApplyAnimationClock(targetProperty, animClock);


 ApplyAnimationToElement("animationX", Canvas.LeftProperty, ellipse);
 ApplyAnimationToElement("animationY", Canvas.TopProperty, ellipse);

One of the animations looks like this:
<DoubleAnimationUsingPath x:Key="animationY" Duration="0:0:5" Source="Y" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="ellipse" IsAdditive="True">
					<PathGeometry Figures="M51,16.39761 C-24.537898,34.288169 -99.506096,99.331318 -180.99999,48.397609 C-272.95909,-9.0768199 -273.32109,-7.6023899 -396.99999,-7.6023899 C-542.68229,-7.6023899 -749.89068,-134.26628 -860.99998,32.397609 C-908.87698,104.21312 -973.26728,125.18958 -964.99998,224.39761 C-957.10698,319.1142 -881.84698,326.46864 -868.99998,416.3976 C-847.86878,564.316 -884.99998,746.27899 -884.99998,904.39759 C-1102.1311,947.82379 -1069,1082.9669 -1069,1392.3976 C-1069,1628.7411 -1144.1431,1787.4617 -676.99998,1728.3976"/>

Animation is paused and inserted into a list, because I take snapshots from each animation step to create a video (that's the whole point, I'm using WPF to render some video, which may be a bit dumb, but I didn't find easier solution for me).

Everything is working fine now, but I want to move the ellipse according to timetable. I thought about that I could write code which provide some custom implementation of polyline and combined with time data I calculate the Canvas coordinates.

On the other hand, I think that it would be easier to use the built-in animation with some basic speed curve, but I didn't find way to pass a custom timeline object to DoubleAnimationUsingPath object. Moreover it would be nice if later, when the ellipse might be replaced with pictures I could rotate them using matrixanimation.

Could you help me if it's worth using WPF's built-in animation capabilities or rather write my own implementation which would be less capable, but at least objects' movements are based on timetable. If I should use WPF animation, how could I set to it my custom timeline?

Bit more detailed description: Say I have a path with three sections between points A,B,C,D . My timetable contains, that the ellipse moves from A to B in 4 sec, B to C in 9, C to D in 3 no matter how long these lines are. Can this be achieved using WPF animations?
Updated 4-Apr-15 13:27pm
Sergey Alexandrovich Kryukov 4-Apr-15 18:38pm    
WPF animation? If the timing is custom, I personally would not even think about WPF animation feature. I would take a separate thread, timing from System.Diagnostic.Stopwatch and animated everything from scratch. Anything in the UI can be updated using Dispatcher.Invoke... And this is easy. If everything else is already done (geometry, calculation of all properties depending in current time), this work could be done quite quickly.

Also, it depends on the goals of the tasks. If your animation is some "physics", in the sense of this word understood in gaming and similar fields, nothing you described above would make sense. All UI elements, paths (more exactly paths should not be applicable per se, let's talk about generalized coordinates) and timing should be calculated out of physics laws, without even remembering WPF animation. The same approach should be used in most other approaches. WPF animation should be left to some purely decorative effects...

In your case... as I understand, the path is the road. I can speculate, the objects represent driving along the road. You need to consult speed limits (or anything like that, traffic), accelerate accordingly on turns, stop, accelerate, etc.

macika123 4-Apr-15 19:16pm    
Basically, this application should serve for traffic simulation purposes (trains, metros, bus lines based on timetables or other vehicles based on recorded GPS routes), where the output is just a video. So I think you persuaded me, that WPF animations should not be used.

I really appreciated your comment ;-). I'm often having hard time making decisions. Thank you very much.
Sergey Alexandrovich Kryukov 4-Apr-15 20:41pm    
Then let me put a formal answer. Hope you will accept it formally, even if you are still have to think more at your final decisions (which is always a good idea). It won't prevent others from adding their answers.



1 solution

I expressed my opinion in my comments to the question. I hope you understand my motivation of the advice to get rid of the idea of using WPF animation feature. The animation could be made out of first principles in a more efficient, and, in essence, a simper way.

Here is the idea: you create a separate thread which takes the scenery (in this case, the map with routes and some data about these routes) and build some "physics" over it, using general and simple kinematic and mechanic laws to represent motion of objects on this scenery. This thread itself should work exclusively with data, calculation and time.

The timing is delicate issue. Say, you create a loop in your thread: it takes current coordinates, time spend on the physical world you model and calculate new generalized coordinates in your configuration space ( However, no way you can rely on the assumption that your loops gives you equal time durations when the execution periodically comes to this point — this is not a real-time system. Instead, you can use the class System.Diagnostics.Stopwatch and get the real time when you need it:[^].

This way, you can get a real point of time and calculate the coordinates for the moment of time you acquire from the system. For example, for the motion with the speed v and acceleration a, coordinate calculations x = x₀ + vt + a²t should use this acquired value of t. The time spans between your "frames" won't be equal, nevertheless, the motion will look quite smooth and realistic to a human eye; I had many cases to be sure.

Now, you need to update your UI and perform proper rendering of you motion. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
How to get a keydown event to operate on a different thread in,
Control events not firing after enable disable + multithreading.

In you case, animation, you will need to use Dispatcher.Invoke, not BeginInvoke, to hold on your thread calculating the motion, and to prevent the situations when this thread produces more and more calculated coordinates in the configuration space and your rendering does not follow the tempo. This is yet another reason you need to use Stopwatch.

Basically, that's all. Feel free to ask if you have any follow-up questions.

Share this answer
macika123 4-Apr-15 21:40pm    
Thank you for detailed (and now official) answer!

To be honest this is the first time I heard about term 'degrees of freedom', which makes me feel a bit dumb, but at least I read about it now :) . Thanks again!
Sergey Alexandrovich Kryukov 4-Apr-15 22:02pm    
You are very welcome.
No, there is no a need "to feel dumb" about these concepts, when it comes to you problems; in practice, it would not affect your work much. But of course, for general education, it's always good to understand such things. And just knowing basic concepts helps, for example, to explain things and understand explanations, or get better ideas, which is often stimulated by more generalized views...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900