2

我之前发布了一个关于仅基于起点和终点生成贝塞尔曲线的问题,感谢使用我拥有的信息创建贝塞尔曲线的答案。

这是允许我在表单上绘制所需曲线类型的代码。

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    Random rnd = new Random();
    Point startp = new Point(rnd.Next(0, this.Width), rnd.Next(0, this.Height));
    Point endp = new Point(rnd.Next(0, this.Width), rnd.Next(0, this.Height));
    int xMod = 0;
    int yMod = 0;
    if (startp.X > endp.X) {
        xMod = -1;
    } else {
        xMod = 1;
    }
    if (startp.Y > endp.Y) {
        yMod = 1;
    } else {
        yMod = -1;
    }
    Point control1p = new Point(endp.X + (rnd.Next(20, 50) * xMod), endp.Y + (rnd.Next(20, 50) * yMod));
    Point control2p = new Point(endp.X + (rnd.Next(5, 20) * xMod), endp.Y + (rnd.Next(5, 20) * yMod));
    Point[] pts = {
        startp,
        control1p,
        control2p,
        endp
    };
    Pen dashed_pen = new Pen(Color.Black, 0);
    dashed_pen.DashStyle = Drawing2D.DashStyle.Dash;
    for (int i = 0; i <= 2; i++) {
        e.Graphics.DrawLine(dashed_pen, pts(i), pts(i + 1));
    }
    e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
    Pen bez_pen = new Pen(Color.Black, 3);
    e.Graphics.DrawBezier(bez_pen, pts(0), pts(1), pts(2), pts(3))
}

有没有办法,或者有人可以帮助我返回形成曲线的所有点?我希望从这些点计算出的曲线的每个点都以点数组的形式返回,但是我没有运气弄清楚,并且无法在 stackoverflow 或 google 上找到类似的解决方案一般的。

谢谢。

4

4 回答 4

3

您要做的是将贝塞尔曲线(从外观上看为三次)转换为Polyline

使用本页上的公式...的值t应该介于0 to 1...计算 和 的所有值,Bx(t)By(t)使用 t 的增量值的等式计算"0, 0.01, 0.02....1"(当然将它们转换integers为) 增量越小,您的点越准确将会。

这是DeCasteljau 算法的 C 示例(几乎相同的程序,但我相信它有点优化):)

于 2010-10-28T05:21:45.763 回答
1

Maxim Shemanarev 在 Anti-Grain Geometry 页面上描述了创建具有最佳点数的平滑贝塞尔曲线的完美算法:贝塞尔曲线的自适应细分

于 2013-04-15T20:30:48.387 回答
0

如果您在绘制贝塞尔曲线之间使用 lerp 或 float t 导数可能会有所帮助。我发现它有助于提高准确性;考虑到 float calcs 的数量。

于 2015-01-22T02:30:17.623 回答
0

我知道这是一篇旧帖子,但是,在目前的答案中没有一个是令人满意的,希望其他人能从以下内容中得到一些用处:

using System.Collections.Generic;
using System.Drawing;
    
public List<Point> CubicBezierToPoints(Point P0, Point P1, Point P2, Point P3, double step = 0.01)
{
    var pointList = new List<Point>();
    for (var t = 0.00; t <= 1; t += step)
    {
        var x = Math.Pow(1 - t, 3) * P0.X + 3 * Math.Pow(1 - t, 2) * t * P1.X +
                3 * (1 - t) * Math.Pow(t, 2) * P2.X + Math.Pow(t, 3) * P3.X;
        var y = Math.Pow(1 - t, 3) * P0.Y + 3 * Math.Pow(1 - t, 2) * t * P1.Y +
                3 * (1 - t) * Math.Pow(t, 2) * P2.Y + Math.Pow(t, 3) * P3.Y;
        pointList.Add(new Point((int)x,(int)y));
    }
    return pointList;
}
于 2021-08-19T05:00:18.187 回答