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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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

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