Zmiana położenia punktu przegięcia krzywej

0

Witam,
chcę stworzyć taki wykres abym mógł w czasie trwania programu zmieniać np. za pomocą myszki położenie punktów przegięcia. Tak jak jest to zrobione w oprogramowaniu (dla płyt głównych), do ustalania prędkości obrotowej wentylatorów.

Projektuję sterownik do wentylatorów i zatrzymałem się w tym miejscu.

Na stronie microsoftu znalazłem instrukcję: Rysowanie krzywych kardynalnych. Są punkty, mają swoje x,y ale jak je przesunąć?
Czy może lepiej skierować się w stronę Charta?

1

Tak na szybko zrobiłem dla 5 punktów przesuwanie punktów krzywych. Mam nadzieję, że jako wzór przyda się.
Ogólnie działa to tak: Budujemy sobie 5 punktów i funkcją do rysowania łączymy je. Gdy chcemy coś przesunąć w zdarzeniu kliknięcia myszką szukamy czy jesteśmy obok jakiegoś punktu Findem na kolekcji. Stwierdzenie obok jakiegoś punktu zależy od tego jaką precyzję sobie wybierzemy zmienną distanceFromTarget (ja sobie ustawiłem na 20). Gdy trafimy w coś to czytamy jego indeks w liście. W zdarzeniu ruchu myszki na bieżąco zmieniamy współrzędne trafionego punktu i Invalidate przerysowujemy całą grafikę. Jak klikniemy po raz kolejny to upuszczamy trzymany punkt i mamy zmienioną krzywą. Mam nadzieję, że to pomoże :)

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;

namespace krzywe_kardynalne
{
    public partial class Form1 : Form
    {
        private bool pickedUp;
        int pickedUpPointIndex;
        private List<Point> points = new List<Point>();
        private const int distanceFromTarget = 20;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.FromArgb(255, 0, 0, 255));

            //rysujemy krzywe
            if (points.Count > 1)
                e.Graphics.DrawCurve(pen, points.ToArray());

            foreach(Point point in points)
            {
                //pogrubiamy punkty
                e.Graphics.FillRectangle(new SolidBrush(Color.Red), point.X-2, point.Y-2, 4, 4);
            }

        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            if (points.Count < 5)
            {
                points.Add(new Point(e.X, e.Y));
            }
            else
            {
                if(!pickedUp)
                {
                    Point clicked = new Point(e.X, e.Y);

                    Point foundedPoint = points.Find(
                        (x) =>
                        {
                            return Contains(x, clicked);
                        }
                        );

                    if (!foundedPoint.IsEmpty)
                    {
                        pickedUpPointIndex = points.IndexOf(foundedPoint);
                        pickedUp = true;
                    }
                }
                else
                {
                    pickedUp = false;
                }

            }

            Invalidate();
        }

        private bool Contains(Point target, Point clicked)
        {
            int x = target.X - distanceFromTarget / 2;
            int y = target.Y - distanceFromTarget / 2;

            Rectangle rectangle = new Rectangle(x, y, distanceFromTarget, distanceFromTarget);

            if (rectangle.Contains(clicked))
                return true;
            else
                return false;
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if(pickedUp)
            {
                //zmien wspolrzedne dla podniesionego punktu
                points[pickedUpPointIndex] = new Point(e.X,e.Y);
                Invalidate();
            }
        }
    }
}
0

Dzięki,
fajnie to działa ale już poszedłem w stronę Charta, a punkty przesuwam za pomocą numericUpDown, co mi w sumie wystarcza (bo kto ciągle zmienia krzywe wentylatorów?).
Temat uważam za zamknięty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1