【问题标题】:How to draw Bezier-Curve C#如何绘制贝塞尔曲线 C#
【发布时间】:2025-12-28 14:10:06
【问题描述】:

我需要画一条贝塞尔曲线。但问题是我的代码带来了这个输出:

但它应该是这样的:

我怎样才能“删除”其余的行。我不知道如何仅在他最好的折线级别上绘制控制多边形。

    private void pb_Bezier_Paint(object sender, PaintEventArgs e)
    {
        Point P1 = new Point(10, 300);
        Point P2 = new Point(180, 50);
        Point P3 = new Point(320, 300);

        ZeichneBezier(6, P1, P2, P3, e);
    }

    private void ZeichneBezier(int n, Point P1, Point P2, Point P3, PaintEventArgs pva)
    {
        Graphics g = pva.Graphics;
        Pen kpStift = new Pen(Color.Black, 3);
        Pen bkStift = new Pen(Color.Red, 2);

        for(int i = n; i >= 0; i--)
        {
            if(i==0)
            {
                g.DrawLine(bkStift, P1, P2);
                g.DrawLine(bkStift, P2, P3);
            }
            else
            {
                Point P12 = new Point((P1.X + P2.X)/2,(P1.Y + P2.Y)/2);
                Point P23 = new Point((P2.X + P3.X)/2,(P2.Y + P3.Y)/2);
                Point P123 = new Point((P12.X + P23.X)/2,(P12.Y + P23.Y)/2);

                ZeichneBezier(n-1, P1, P12, P123, pva);
                ZeichneBezier(n-1, P123, P23, P3, pva);
            }
        }

【问题讨论】:

  • 我不知道这是否是一项家庭作业,但请注意Graphics 也有绘制贝塞尔曲线的特定方法,因此您可以省去用线条近似贝塞尔曲线的麻烦段...
  • 是的,你是对的@elgonzo,这是作业:D 我知道有这些方法可以绘制贝塞尔曲线,但我们需要这样 :(
  • 既然是作业,让我们把问题抛给你 :-) 你如何(或将)确定你何时处于折线的最佳水平?
  • 我认为这将是一条带有 3 点的曲线,对吗?开始,控制,结束。还是我必须只画线条的中点?所以点?对不起我的英语不好。
  • 对不起,我不明白这与我提出的问题有什么关系。如果您希望您的程序仅在其最佳水平上绘制多段线,您需要回答以下问题:我的程序如何(或如何)确定它是否处于最佳水平并且应该绘制或是否不是还处于最好的水平,还不应该画画?

标签: c# visual-studio gdi+ bezier


【解决方案1】:

也许这个……

    private void pb_Bezier_Paint(object sender, PaintEventArgs e)
    {
        Point P1 = new Point(10, 300);
        Point P2 = new Point(180, 50);
        Point P3 = new Point(320, 300);

        ZeichneBezier(6, P1, P2, P3, e, true);
    }

    private void ZeichneBezier(int n, Point P1, Point P2, Point P3, PaintEventArgs pva, bool initial)
    {
        Graphics g = pva.Graphics;
        Pen bkStift = new Pen(Color.Red, 2);
        Pen kpStift = new Pen(Color.Black, 3);

        if(initial)
        {
            g.DrawLine(kpStift, P1, P2);
            g.DrawLine(kpStift, P2, P3);
        }

        if (n > 0)
        {
            Point P12 = new Point((P1.X + P2.X) / 2, (P1.Y + P2.Y) / 2);
            Point P23 = new Point((P2.X + P3.X) / 2, (P2.Y + P3.Y) / 2);
            Point P123 = new Point((P12.X + P23.X) / 2, (P12.Y + P23.Y) / 2);

            ZeichneBezier(n - 1, P1, P12, P123, pva, false);
            ZeichneBezier(n - 1, P123, P23, P3, pva, false);
        }
        else
        {
            g.DrawLine(bkStift, P1, P2);
            g.DrawLine(bkStift, P2, P3);
        }
    }

您的 for 循环似乎没有必要,并且会降低您的性能。

我添加了一个参数“bool initial”来决定何时绘制黑线。

只有在 pb_Bezier_Paint 事件处理程序中第一次调用 ZeichneBezier 才能绘制线条。

【讨论】: