How to make an image(or a rectangle) follow a Spline

Viewed 70

I have a project that I need to make an image follow a spline.

I build the spline using Graphics.DrawCurve through an array of Points.

I'm trying to use PointAnimationUsingPath but I can't seem to get it to work. Apparently it doesn't work in C# with Windows form.

Can someone give me a light on how to do this?

Thank you All.

-----EDIT----- enter image description here Change to a WPF UserControl as recommend in comments.

Still need some help as the shape does not move exactly following the dots, below my code:

 public partial class SplineBox : UserControl
{
    Point[] finalPoint;

    public SplineBox()
    {
        InitializeComponent();

    }

    public void MoveShape(Point[] _path)
    {
        // Create a NameScope for the page so that
        // we can use Storyboards.
        NameScope.SetNameScope(this, new NameScope());

        // Create the EllipseGeometry to animate.
        EllipseGeometry animatedEllipseGeometry =
            new EllipseGeometry(new Point(10, 100), 15, 15);

        // Register the EllipseGeometry's name with
        // the page so that it can be targeted by a
        // storyboard.
        this.RegisterName("AnimatedEllipseGeometry", animatedEllipseGeometry);

        // Create a Path element to display the geometry.
        Path ellipsePath = new Path();
        ellipsePath.Data = animatedEllipseGeometry;
        ellipsePath.Fill = Brushes.Blue;
        ellipsePath.Margin = new Thickness(15);

        SplineCanvas.Children.Add(ellipsePath);
        this.Content = SplineCanvas;

        // Create the animation path.
        PathGeometry animationPath = new PathGeometry();
        PathFigure pFigure = new PathFigure();
        pFigure.StartPoint = _path[0];

        PolyBezierSegment pBezierSegment = new PolyBezierSegment();

        for (int p = 1; p < _path.Length; p++)
        {
            pBezierSegment.Points.Add(_path[p]);
        }

        pFigure.Segments.Add(pBezierSegment);
        animationPath.Figures.Add(pFigure);

        // Freeze the PathGeometry for performance benefits.
        animationPath.Freeze();

        // Create a PointAnimationgUsingPath to move
        // the EllipseGeometry along the animation path.
        PointAnimationUsingPath centerPointAnimation =  new PointAnimationUsingPath();
        centerPointAnimation.PathGeometry = animationPath;
        centerPointAnimation.Duration = TimeSpan.FromSeconds(5);
        centerPointAnimation.RepeatBehavior = RepeatBehavior.Forever;

        // Set the animation to target the Center property
        // of the EllipseGeometry named "AnimatedEllipseGeometry".
        Storyboard.SetTargetName(centerPointAnimation, "AnimatedEllipseGeometry");
        Storyboard.SetTargetProperty(centerPointAnimation,
            new PropertyPath(EllipseGeometry.CenterProperty));

        // Create a Storyboard to contain and apply the animation.
        Storyboard pathAnimationStoryboard = new Storyboard();
        pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
        pathAnimationStoryboard.AutoReverse = true;
        pathAnimationStoryboard.Children.Add(centerPointAnimation);

        // Start the Storyboard when ellipsePath is loaded.
        ellipsePath.Loaded += delegate (object sender, RoutedEventArgs e)
        {
            // Start the storyboard.
            pathAnimationStoryboard.Begin(this);
        };
    }

    public void Paint(ScreenObject _spline)
    {            

        List<Point> points = new List<Point>();

        if (true)
        {
            var spline = _spline;

            foreach (System.Windows.Point point in spline.SplineAnchors)
            {
                Point tempP = new Point((int)point.X, (int)point.Y);
                points.Add(tempP);
            }


            finalPoint = points.ToArray();

            //Pen pen = new Pen(Color.FromArgb(255, 0, 0, 255), 1);
            //e.Graphics.DrawCurve(pen, finalPoint);

            foreach (Point p in finalPoint)
            {
                // Create a red Ellipse.
                Ellipse myEllipse = new Ellipse();

                // Create a SolidColorBrush with a red color to fill the
                // Ellipse with.
                SolidColorBrush mySolidColorBrush = new SolidColorBrush();

                // Describes the brush's color using RGB values.
                // Each value has a range of 0-255.
                mySolidColorBrush.Color = Color.FromArgb(255, 100, 255, 0);
                myEllipse.Fill = mySolidColorBrush;
                myEllipse.StrokeThickness = 2;
                myEllipse.Stroke = Brushes.Black;

                // Set the width and height of the Ellipse.
                myEllipse.Width = 10;
                myEllipse.Height = 10;

                myEllipse.Margin = new Thickness(p.X - 5, p.Y - 5, 0, 0);
                //e.Graphics.DrawRectangle(pen, new Rectangle(p.X - 5, p.Y - 5, 10, 10));
                //e.Graphics.FillRectangle(Brushes.Red, new Rectangle(p.X - 5, p.Y - 5, 10, 10));

                SplineCanvas.Children.Add(myEllipse);
            }
        }
    }

}
0 Answers
Related