См. Обзор анимации пути и MatrixAnimationUsingPath
Его можно использовать для перемещения элемента управления вдоль PathGeometry, и если вы зададите значение DidRotateWithTangent, элемент управления также будет вращаться вдоль направления пути.
EDIT1:
<Page.Resources>
<PathGeometry x:Key="Path" x:Shared="False" Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100"/>
</Page.Resources>
<Canvas Width="400" Height="400">
<Path Data="{StaticResource Path}" Stroke="Blue" StrokeThickness="1"/>
<Path
x:Name="Arrow1"
Stretch="Fill"
Width="16" Height="16" StrokeLineJoin="Miter"
Data="M 0 -5 L 10 -5 M 5 0 L 10 -5 L 5 -10"
Stroke="Black" StrokeThickness="3">
<Path.RenderTransform>
<TransformGroup>
<TranslateTransform X="-8" Y="-8"/>
<MatrixTransform>
<MatrixTransform.Matrix>
<Matrix/>
</MatrixTransform.Matrix>
</MatrixTransform>
</TransformGroup>
</Path.RenderTransform>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<MatrixAnimationUsingPath
Storyboard.TargetName="Arrow1"
Storyboard.TargetProperty="RenderTransform.Children[1].Matrix"
DoesRotateWithTangent="True"
Duration="0:0:5"
BeginTime="0:0:0"
RepeatBehavior="Forever" PathGeometry="{StaticResource Path}" >
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
РЕДАКТИРОВАТЬ 2: Подсчет, сколько стрелок вам нужно
Я предполагаю, что вы создаете пользовательский элемент управления и программно добавляете стрелки?
Если так, то я думаю, что самым простым способом было бы указать Duration для одного цикла и BeginTimeGap, время между BeginTimes последующих стрелок. Количество стрелок, которое вы должны добавить, будет Duration / BeginTimeGap или в упрощенном коде:
while (BeginTime < Duration)
{
//add arrow with BeginTime and Duration;
BeginTime += BeginTimeGap;
}
Получение правильной скорости и расстояния между стрелками сводится к настройке этих двух значений.