如何通过几个点来绘制贝塞尔曲线? [英] How to draw bezier curve by several points?

查看:1524
本文介绍了如何通过几个点来绘制贝塞尔曲线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个点,我尝试使用code绘制贝塞尔曲线的下方

I have several points, and I try to draw Bezier curve using code below

 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));

我的贝塞尔曲线段像这样

My Bezier segments look like this

  • 在1,2,3点 - 第一段
  • 在3,4,5分 - 秒
  • 在5,6,7 .. ..

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

But I got this strange curve (here is 3 big (Nodes) and 7 small ellipse (is my points)):

推荐答案

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

The line you're getting is the union of three distinct Bezier curves - one for each group of three points. (One for each "Bezier segment"?)

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

If you want a single smooth curve, you need to pass your 9 (or more) points as a single collection of points (single "Bezier segment"?), not as groups of three points.

编辑:显然<一href="http://msdn.microsoft.com/en-us/library/system.windows.media.beziersegment.aspx"><$c$c>BezierSegment唯一的支持的三个点,所以难怪这不起作用。即使PolyBezierSegment只是给贝塞尔曲线段的集合,而不是一个单一的平滑贝塞尔...

Apparently BezierSegment only supports three points, so no wonder this doesn't work. Even 'PolyBezierSegment' just gives a collection of Bezier segments rather than a single smooth Bezier...

因此​​,既然WPF不给你什么有用的,我敲东西一起用数学这里。这是一个数字的解决方案,但它似乎是pretty的高性能即使有足够的积分,好看,光滑:

So since WPF doesn't give you anything useful, I knocked something together using the maths here. It's a numeric solution, but it seems to be pretty performant even with enough points to look nice and smooth:

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);
}

利用这一点,

Using this,

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);
}

这篇关于如何通过几个点来绘制贝塞尔曲线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆