Witam, mam do zrobienia projekt, w którym obiekt (np. kwadrat, kółko, trójkąt) będzie się poruszał dokładnie po wykresie funkcji sinus/cosinus. Mam już gotowy wykres, ale nie wiem jak utworzyć tą animację i obiekt. Próbowałem zrobić tak jak na stronie MSDN <https://msdn.microsoft.com/en[...]brary/ms743217(v=vs.110).aspx >, ale nie wychodzi mi.

Bardzo bym prosił o pomoc. (Nie robię tego hobbistycznie, po prostu muszę to zaliczyć na uczelni)

Mój kod dotąd:
(na końcu jest guzik obsługi animacji)

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//nowe przestrzenie
using System.Drawing.Drawing2D;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media;

namespace ProjektNr4_Beringer45289
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //kanwa dla wykresu
        private Bitmap GrafFunkcji;
        System.Drawing.Pen długopisSinus;

        //obsługa przycisku o funkcji kreślenia wykresu
        private void btnGraf_Click(object sender, EventArgs e)
        {
            GrafFunkcji = new Bitmap(
                kanwaWykresu.ClientSize.Width,
                kanwaWykresu.ClientSize.Height);
            using (Graphics graf = Graphics.FromImage(GrafFunkcji))
            {
                graf.Clear(System.Drawing.Color.White);
                graf.SmoothingMode = SmoothingMode.AntiAlias;

                using(System.Drawing.Pen cienkiDługopis = new System.Drawing.Pen(System.Drawing.Color.Black, 0))
                {
                    //ustalenie wymiarów
                    double xMin = (double)numXmin.Value * Math.PI;
                    double xMax = (double)numXmax.Value * Math.PI;
                    double yMin = -2.0;
                    double yMax = 2.0;

                    //skalowanie obszaru do umieszczenia w PictureBox
                    RectangleF współrzędne = new RectangleF(
                        (float)xMin, (float)yMax,
                        (float)(xMax - xMin),
                        (float)(yMin - yMax));
                    PointF[] współrzędne_d =
                    {
                        new PointF(0, 0),
                        new PointF(kanwaWykresu.ClientSize.Width, 0),
                        new PointF(0, kanwaWykresu.ClientSize.Height),
                    };
                    graf.Transform = new System.Drawing.Drawing2D.Matrix(współrzędne, współrzędne_d);

                    //rysowanie osi X
                    //początek na powtórzeniach liczby Pi < xMin
                    double start_x = Math.PI * ((int)(xMin - 1));
                    graf.DrawLine(cienkiDługopis, (float)xMin, 0, (float)xMax, 0);
                    float dy = (float)((yMax - yMin) / 30.0);
                    for(double x = start_x; x <= xMax; x += Math.PI)
                    {
                        graf.DrawLine(cienkiDługopis, (float)x, -2 * dy, (float)x, 2 * dy);
                    }
                    for(double x = start_x + Math.PI/2.0; x <= xMax; x += Math.PI)
                    {
                        graf.DrawLine(cienkiDługopis, (float)x, -dy, (float)x, dy);
                    }

                    //rysowanie osi Y
                    //początek od mnożników 1 < yMin
                    double start_y = (int)yMin - 1;
                    graf.DrawLine(cienkiDługopis, 0, (float)yMin, 0, (float)yMax);
                    float dx = (float)((xMax - xMin) / 60.0);
                    for(double y = start_y; y <=yMax; y += 1.0)
                    {
                        graf.DrawLine(cienkiDługopis, -2 * dx, (float)y, 2 * dx, (float)y);
                    }
                    for (double y = start_y + 0.5; y <= yMax; y += 1.0)
                    {
                        graf.DrawLine(cienkiDługopis, -dx, (float)y, dx, (float)y);
                    }

                    //rysowanie asymptot pionowych
                    cienkiDługopis.DashPattern = new float[] { 5, 5 };
                    for(double x = start_x + Math.PI/2.0; x <= xMax; x += Math.PI)
                    {
                        graf.DrawLine(cienkiDługopis, (float)x, (float)yMin, (float)x, (float)yMax);
                    }

                    //rysowanie granic dolnych i górnych dla funkcji sinus i cosinus
                    graf.DrawLine(cienkiDługopis, (float)xMin, 1, (float)xMax, 1);
                    graf.DrawLine(cienkiDługopis, (float)xMin, -1, (float)xMax, -1);
                    cienkiDługopis.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;

                    //sprawdzenie rozmiaru pixela przed skalowaniem
                    System.Drawing.Drawing2D.Matrix inwersja = graf.Transform;
                    inwersja.Invert();
                    PointF[] pktPixel =
                    {
                        new PointF(0, 0),
                        new PointF(1, 0),
                    };
                    inwersja.TransformPoints(pktPixel);
                    dx = pktPixel[1].X - pktPixel[0].X;

                    //funkcja sinus
                    System.Drawing.Pen PenSin = new System.Drawing.Pen(textBox1.BackColor, 0);
                    List<PointF> pktSinusa = new List<PointF>();
                    for (float x = (float)xMin; x <= xMax; x += dx)
                    {
                        pktSinusa.Add(new PointF(x, (float)Math.Sin(x)));
                    }
                    //cienkiDługopis.Color = Color.Blue;
                    graf.DrawLines(PenSin, pktSinusa.ToArray());

                    //funkcja cosinus
                    List<PointF> pktCosinusa = new List<PointF>();
                    for(float x = (float)xMin; x <= xMax; x += dx)
                    {
                        pktCosinusa.Add(new PointF(x, (float)Math.Cos(x)));
                    }
                    cienkiDługopis.Color = System.Drawing.Color.Green;
                    graf.DrawLines(cienkiDługopis, pktCosinusa.ToArray());
                    zapiszJakoToolStripMenuItem.Enabled = true; 

                }
            }

           //wyświetlanie wyników
           kanwaWykresu.Image = GrafFunkcji;

        }

        private void txtYMin_TextChanged(object sender, EventArgs e)
        {

        }

        private void zakończToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult exit = MessageBox.Show("Zakończyć działanie programu?", "", MessageBoxButtons.YesNo);
            if (exit == DialogResult.Yes)
            {
                Application.Exit();
            }
        }

        private void zapiszJakoToolStripMenuItem_Click(object sender, EventArgs e)
        {

            //metoda zapisania wygenerowanego obrazu wykresu funkcji do pliku "".gif
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Obraz GIF|*.gif";
            saveFileDialog.Title = "Zapisz plik jako...";
            saveFileDialog.FileName = "";

            DialogResult result = saveFileDialog.ShowDialog();
            saveFileDialog.RestoreDirectory = true;

            if (result == DialogResult.OK && saveFileDialog.FileName != "")
            {
                try
                {
                    if (saveFileDialog.CheckPathExists)
                    {
                        if (saveFileDialog.FilterIndex == 1)
                        {
                            GrafFunkcji.Save(saveFileDialog.FileName, System.Drawing.Imaging.ImageFormat.Gif);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Podana ścieżka nie istnieje");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            zapiszJakoToolStripMenuItem.Enabled = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void kolorLiniiToolStripMenuItem_Click(object sender, EventArgs e)
        {

            ColorDialog OknoKolorów = new ColorDialog();
            if (OknoKolorów.ShowDialog() == DialogResult.OK)
            {
                textBox1.BackColor = OknoKolorów.Color;
            }
            else
                długopisSinus.Color = System.Drawing.Color.Black;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            //utworzenie obiektu elipsy do poruszania się po wykresie
            Graphics mojaElipsa = base.CreateGraphics();
            System.Drawing.Pen elipsaPen = new System.Drawing.Pen(System.Drawing.Color.Black);
            SolidBrush myBrush = new SolidBrush(System.Drawing.Color.Red);
            mojaElipsa.DrawEllipse(elipsaPen, 50, 50, 150, 150);

            Path elipsaPath = new Path();
            elipsaPath.Data = animatedEllipseGeometry;//tutaj jest błąd, bo u mnie w programie "animatedEllipseGeometry" nie ma tak jak na stronie MSDN

        }
    }
}