Кривая Безье обратная - PullRequest
0 голосов
/ 28 января 2020

Я новичок в C# и вообще в кодировании. Я написал алгоритм для кривой Куби c Безье, но теперь моя следующая задача - сделать инверсию для кривой Куби c Безье, что для меня сложно. И так и должно быть: после прорисовки 4 контрольных точек линия от 3-й контрольной точки должна продолжиться, и когда мы поместим новую контрольную точку на линию (прямая линия, соединяющая контрольные точки), мы сможем продолжить создание кривой Безье.

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 _12_CubicBezier
{
    public partial class Form1 : Form
    {
        Graphics g;
        int s = 6;
        int gotcha = -1;
        List<PointF> P = new List<PointF>();


        Pen pPoint = Pens.Black;
        Pen pTangent = Pens.Black;
        Pen pCurve = new Pen(Color.Blue, 3.0f);

        Brush bPoint;

        public Form1()
        {
            InitializeComponent();
            bPoint = new SolidBrush(Canvas.BackColor);
        }

        private void Canvas_Paint(object sender, PaintEventArgs e)
        {
            g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            for (int i = 0; i < P.Count - 1; i++)
                g.DrawLine(pTangent, P[i], P[i + 1]);

            if (P.Count == 4)
                DrawBezier();

            for (int i = 0; i < P.Count; i++)
            {
                g.FillEllipse(bPoint, P[i].X - s, P[i].Y - s, 2 * s, 2 * s);
                g.DrawEllipse(pPoint, P[i].X - s, P[i].Y - s, 2 * s, 2 * s);
            }
        }
        private void Canvas_MouseDown(object sender, MouseEventArgs e)
        {
            for (int i = 0; i < P.Count; i++)
            {
                if (Math.Abs(P[i].X - e.X) <= s && Math.Abs(P[i].Y - e.Y) <= s)
                    gotcha = i;
            }          

            if (gotcha == -1 && P.Count < 4)
            {
                P.Add(e.Location);
                gotcha = P.Count - 1;
                Canvas.Invalidate();
            }
        }
        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (gotcha != -1)
            {
                P[gotcha] = e.Location;
                Canvas.Invalidate();
            }
        }
        private void Canvas_MouseUp(object sender, MouseEventArgs e)
        {
            gotcha = -1;
        }

        private double B0(double t) { return (1 - t) * (1 - t) * (1 - t); }
        private double B1(double t) { return 3 * t * (1 - t) * (1 - t); }
        private double B2(double t) { return 3 * t * t * (1 - t); }
        private double B3(double t) { return t * t * t; }

        private void DrawBezier()
        {
            PointF t0, t1;
            double t = 0.0;
            double h = 1.0 / 500.0;
            t0 = new PointF((float)(B0(t) * P[0].X + B1(t) * P[1].X + B2(t) * P[2].X + B3(t) * P[3].X),
                            (float)(B0(t) * P[0].Y + B1(t) * P[1].Y + B2(t) * P[2].Y + B3(t) * P[3].Y));
            while (t < 1.0)
            {
                t += h;
                t1 = new PointF((float)(B0(t) * P[0].X + B1(t) * P[1].X + B2(t) * P[2].X + B3(t) * P[3].X),
                                (float)(B0(t) * P[0].Y + B1(t) * P[1].Y + B2(t) * P[2].Y + B3(t) * P[3].Y));
                g.DrawLine(pCurve, t0, t1);
                t0 = t1;
            }
        }
    }
}```

...