C# .net Линии Безье, рисовать их быстрее

Я пытаюсь сделать панель в С#, используя .net framework. У меня есть панель, где я рисую несколько линий и точек. И я хочу с его помощью контролировать кривые де Безье. И я вышел с этим: ``

пространство имен Безье { общедоступный частичный класс FormMain : Form { Pen lapisLinhas = новое перо (Цвет.Белый, 3); Pen lapisPontos = новое перо (Color.Black, 2); Pen lapisControlos = новое перо (Color.Red, 3); Случайный ряд;

    private int frame = 40;
    private int sele = 0, ct = 0;
    private Point p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;


    public FormMain()
    {
        InitializeComponent();
        
    }
    private void PanelDraw_Paint(object sender, PaintEventArgs e)
    {
        desenhaBezier(e.Graphics);
    }
    /* protected virtual void OnLoad(EventArgs e)
    {
        gerarPontos();
    }*/

    private void FormMain_Load(object sender, EventArgs e)
    {
        gerarPontos();
    }
    private void desenhaBezier(Graphics g)
    {
        Point[] pontos = { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10 };
        g.Clear(PanelDraw.BackColor);

        int w = PanelDraw.DisplayRectangle.Width;
        int h = PanelDraw.DisplayRectangle.Height;

        rnd = new Random();

        g.DrawBeziers(lapisLinhas, pontos);

        int r = 3;
        for (int i = 0; i < pontos.Length; i++)
        {
            g.DrawEllipse(lapisPontos, pontos[i].X - r, pontos[i].Y - r, r * 2, r * 2);
        }

        g.DrawLine(lapisControlos, p1, p2);
        g.DrawLine(lapisControlos, p3, p4);
        g.DrawLine(lapisControlos, p5, p6);
        g.DrawLine(lapisControlos, p7, p8);
        g.DrawLine(lapisControlos, p9, p10);
    }

    private void gerarPontos()
    {
        int w = PanelDraw.DisplayRectangle.Width;
        int h = PanelDraw.DisplayRectangle.Height;

        StatusLabelScreen.Text = "Screen: (w: " + w + "|h: " + h + ")";

        rnd = new Random();

        p1 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p2 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p3 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p4 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p5 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p6 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p7 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p8 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p9 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p10 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));

        PanelDraw.Invalidate();

    }
    private void StatusLabelPosicao_Click(object sender, EventArgs e)
    {

    }

    private void novosPontosToolStripMenuItem_Click(object sender, EventArgs e)
    {
        rnd = new Random();

        int w = PanelDraw.DisplayRectangle.Width;
        int h = PanelDraw.DisplayRectangle.Height;

        StatusLabelScreen.Text = "Screen: (w: " + w + "| h: " + h + ")";

        p1 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p2 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p3 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p4 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p5 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p6 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p7 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p8 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p9 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));
        p10 = new Point(rnd.Next(frame, w - frame), rnd.Next(frame, h - frame));

        PanelDraw.Invalidate();
    }

    private void corDosPontosToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (colorDialog.ShowDialog() == DialogResult.OK)
        {
            Color pontosCor = colorDialog.Color;
            lapisPontos.Color = pontosCor;
            PanelDraw.Invalidate();
        }
    }

    private void pontosToolStripMenuItem_Click(object sender, EventArgs e)
    {
        pontosToolStripMenuItem.Checked = !pontosToolStripMenuItem.Checked;


        if (!pontosToolStripMenuItem.Checked)
        {
            Color trans = Color.Transparent;
            lapisPontos = new Pen(trans);
        }
        else
        {
            lapisPontos = new Pen(Color.Red);
        }
        PanelDraw.Invalidate();
    }

    private void controlosToolStripMenuItem_Click(object sender, EventArgs e)
    {
        controlosToolStripMenuItem.Checked = !controlosToolStripMenuItem.Checked;

        if (!controlosToolStripMenuItem.Checked)
        {
            Color trans = Color.Transparent;
            lapisControlos = new Pen(trans);
        }
        else
        {
            lapisControlos = new Pen(Color.Black);
        }
        PanelDraw.Invalidate();
    }

    private void corDosControlosToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (colorDialog.ShowDialog() == DialogResult.OK)
        {
            Color controlosCor = colorDialog.Color;
            lapisControlos.Color = controlosCor;
            PanelDraw.Invalidate();
        }
    }

    private void PanelDraw_MouseMove(object sender, MouseEventArgs e)
    {
        StatusLabelPosicao.Text = "Rato = (" + e.X + "|" + e.Y + ")";

        if (sele == 1)
        {

            for (int i = 0; i < 10; i++)
            {
                if (ct - 1 == i)
                {
                    switch (i)
                    {
                        case 0:
                            p1.X = e.X;
                            p1.Y = e.Y;
                            break;

                        case 1:
                            p2.X = e.X;
                            p2.Y = e.Y;
                            break;

                        case 2:
                            p3.X = e.X;
                            p3.Y = e.Y;
                            break;

                        case 3:
                            p4.X = e.X;
                            p4.Y = e.Y;
                            break;

                        case 4:
                            p5.X = e.X;
                            p5.Y = e.Y;
                            break;

                        case 5:
                            p6.X = e.X;
                            p6.Y = e.Y;
                            break;

                        case 6:
                            p7.X = e.X;
                            p7.Y = e.Y;
                            break;

                        case 7:
                            p8.X = e.X;
                            p8.Y = e.Y;
                            break;

                        case 8:
                            p9.X = e.X;
                            p9.Y = e.Y;
                            break;

                        case 9:
                            p10.X = e.X;
                            p10.Y = e.Y;
                            break;

                    }
                }
            }
            PanelDraw.Invalidate();
        }
    }

    private void sairToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    private void PanelDraw_Resize(object sender, EventArgs e)
    {

        int w = PanelDraw.DisplayRectangle.Width;
        int h = PanelDraw.DisplayRectangle.Height;
        StatusLabelScreen.Text = "Screen: (w: " + w + "| h: " + h + ")";
        PanelDraw.Invalidate();
    }

    private void corDasLinhasToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (colorDialog.ShowDialog() == DialogResult.OK)
        {

            Color linhasCor = colorDialog.Color;
            lapisLinhas.Color = linhasCor;
            PanelDraw.Invalidate();
        }
    }

    private void PanelDraw_click(object sender, MouseEventArgs e)
    {
        Point[] pontos = { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10 };
        if (sele == 1)
        {

            for (int i = 0; i < 10; i++)
            {
                if (ct - 1 == i)
                {
                    switch (i)
                    {
                        case 0:
                            p1.X = e.X;
                            p1.Y = e.Y;
                            break;

                        case 1:
                            p2.X = e.X;
                            p2.Y = e.Y;
                            break;

                        case 2:
                            p3.X = e.X;
                            p3.Y = e.Y;
                            break;

                        case 3:
                            p4.X = e.X;
                            p4.Y = e.Y;
                            break;

                        case 4:
                            p5.X = e.X;
                            p5.Y = e.Y;
                            break;

                        case 5:
                            p6.X = e.X;
                            p6.Y = e.Y;
                            break;

                        case 6:
                            p7.X = e.X;
                            p7.Y = e.Y;
                            break;

                        case 7:
                            p8.X = e.X;
                            p8.Y = e.Y;
                            break;

                        case 8:
                            p9.X = e.X;
                            p9.Y = e.Y;
                            break;

                        case 9:
                            p10.X = e.X;
                            p10.Y = e.Y;
                            break;

                    }

                    PanelDraw.Update();
                    sele = 0;

                }
            }
        }
        else
        {
            ct = 0;
            foreach (Point point in pontos)
            {
                ct++;
                if (e.X >= point.X - 3 && e.X <= point.X + 3 && e.Y >= point.Y - 3 && e.Y <= point.Y + 3)
                {
                    sele = 1;
                    return;
                }
            }
        }
        PanelDraw.Invalidate();
    }
}

} ``

Есть ли способ заставить линии рисовать быстрее? Каждый раз, когда я двигаю мышью, они обновляются, и я этого хочу. Но они просто мигают все время. Я пробовал update() вместо проверки, но строка обновляется после щелчка, поэтому я не вижу ее должным образом.

Есть ли способ сделать плавный переход?

Для части с мерцанием (мигание...) вам понадобится холст DoubleBuffered, чтобы уменьшить мерцание. Вы можете использовать PictureBox вместо Panel, которая по умолчанию является DoubleBuffered. Не воссоздавать Random объект rnd = new Random();. Просто сделайте его полем класса и создайте экземпляр в конструкторе. Закройте форму, вызвав this.Close(); вместо Application.Exit();, чтобы правильно выйти из приложения и не пропустить события и методы завершения ....

dr.null 20.11.2022 00:49

Знаете ли вы, как реализовать двойной буфер в этой ситуации? Я должен использовать drawpanel для домашней работы.

Filipe Cruz 20.11.2022 01:48

rnd исправлено, выход исправлен. Мне нужно использовать панель, и у меня получилось это, но я не знаю, как ее использовать здесь:

Filipe Cruz 20.11.2022 01:55

PictureBox и Label — это два элемента управления с двойной буферизацией. Panel — это контейнер и не совсем подходит для рисования, хотя многие используют/злоупотребляют им для этого.

TaW 20.11.2022 09:27
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
4
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я использовал это, найденное в другом посте, и это сработало очень хорошо:

 typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty
            | BindingFlags.Instance | BindingFlags.NonPublic, null,
            YourPanelName, new object[] { true });

Сообщение: https://stackoverflow.com/a/31562892/16282563

Другие вопросы по теме