如何通过几个点来绘制贝塞尔曲线?(How to draw bezier curve by sever

2019-07-05 17:58发布

我有几个点,我尝试使用下面的代码绘制贝塞尔曲线

 PathFigure pf = new PathFigure(points.From, ps, false); //ps - list of Bezier segments
    PathFigureCollection pfc = new PathFigureCollection();
    pfc.Add(pf);
    var pge = new PathGeometry();
    pge.Figures = pfc;
    Path p = new Path();
    p.Data = pge;
    p.Stroke = new SolidColorBrush(Color.FromRgb(244, 111, 011));

我的贝塞尔曲线段这个样子

  • 1,2,3点 - 第一区段
  • 3,4,5点 - 第二
  • 5,6,7 .. ..

但我得到这个奇怪的曲线(这里是3大(节点)和7个小椭圆(是我的点)):

Answer 1:

你得到的线是三个不同的贝塞尔曲线的结合 - 每个组的三个点。 (每个“贝塞尔曲线段”?)

如果你想要一个平滑的曲线,你需要通过你的9(或更多)点作为点的单个集合(单“贝塞尔曲线段”?),不作为的三点组。

编辑:显然BezierSegment支持三个点,所以难怪这不起作用。 即使“PolyBezierSegment”只是给贝塞尔曲线段的集合,而不是一个单一的光滑的贝塞尔...

如此以来,WPF不给你任何有用的,我敲的东西一起使用数学这里 。 这是一个数字解决方案,但它似乎是即使有足够的积分,好看,光滑漂亮高性能:

PolyLineSegment GetBezierApproximation(Point[] controlPoints, int outputSegmentCount)
{
    Point[] points = new Point[outputSegmentCount + 1];
    for (int i = 0; i <= outputSegmentCount; i++)
    {
        double t = (double)i / outputSegmentCount;
        points[i] = GetBezierPoint(t, controlPoints, 0, controlPoints.Length);
    }
    return new PolyLineSegment(points, true);
}

Point GetBezierPoint(double t, Point[] controlPoints, int index, int count)
{
    if (count == 1)
        return controlPoints[index];
    var P0 = GetBezierPoint(t, controlPoints, index, count - 1);
    var P1 = GetBezierPoint(t, controlPoints, index + 1, count - 1);
    return new Point((1 - t) * P0.X + t * P1.X, (1 - t) * P0.Y + t * P1.Y);
}

利用这一点,

private void Grid_Loaded(object sender, RoutedEventArgs e)
{
    Point[] points = new[] { 
            new Point(0, 200),
            new Point(0, 0),
            new Point(300, 0),
            new Point(350, 200),
            new Point(400, 0)
        };
    var b = GetBezierApproximation(points, 256);
    PathFigure pf = new PathFigure(b.Points[0], new[] { b }, false);
    PathFigureCollection pfc = new PathFigureCollection();
    pfc.Add(pf);
    var pge = new PathGeometry();
    pge.Figures = pfc;
    Path p = new Path();
    p.Data = pge;
    p.Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0));
    ((Grid)sender).Children.Add(p);
}



Answer 2:

由于每个曲线有一个控制点(即影响曲线,但不一定是曲线上的点),你使用二次贝塞尔曲线。

如果你想画的是共享一个终点两个二次曲线,并且希望关节显得光滑,在共享端点两侧的控制点必须与端点共线。 也就是说,两个控制点和它们之间的端点都必须趴在一条直线上。 例:

黑色实盘是端点。 空心圆圈是控制点。 黑色实线是曲线。 虚线示出了每个端点是共线的(与直线)任一侧上的控制点。



文章来源: How to draw bezier curve by several points?