如何通过几点绘制贝塞尔曲线?

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

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

我的Bezier部分看起来像这样

  • 1,2,3分 – 第一节
  • 3,4,5分 – 秒
  • 5,6,7 .. ..

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

在此处输入图像描述

你得到的线是三条不同贝塞尔曲线的并集 – 每组三个点之一。 (每个“贝塞尔分段”一个?)

如果你想要一条平滑的曲线,你需要将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); } 

在此处输入图像描述

由于每条曲线都有一个控制点(影响曲线但不一定在曲线上的点),因此您使用的是二次贝塞尔曲线。

如果要绘制共享端点的两条二次曲线,并且希望关节看起来平滑,则共享端点每侧的控制点必须与端点共线。 也就是说,两个控制点和它们之间的端点必须全部位于一条直线上。 例:

具有光滑关节的样方

实心黑色圆盘是端点。 空心圆是控制点。 黑色实线是曲线。 虚线表示每个端点与两侧的控制点共线(在一条直线上)。