我有几点,我尝试使用下面的代码绘制贝塞尔曲线
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));
我的贝齐尔片段看起来像这样
但我得到了这条奇怪的曲线(这里是3个大的(节点)和7个小椭圆(是我的观点)):
答案 0 :(得分:20)
您获得的是三条不同贝塞尔曲线的并集 - 每组三个曲线之一。 (每个“Bezier段”一个?)
如果你想要一条平滑的曲线,你需要将9个(或更多)点作为单个点集合(单个“贝塞尔曲线段”?)传递,而不是作为三个点的组。
编辑:显然BezierSegment
只有支持三个点,所以难怪这不起作用。即使'PolyBezierSegment'只提供了贝塞尔曲线的集合,而不是一个光滑的贝塞尔曲线......
因为WPF没有给你任何有用的东西,所以我使用数学here一起敲了一下。这是一个数字解决方案,但即使有足够的点看起来也很漂亮,它似乎非常高效:
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);
}
给出
答案 1 :(得分:12)
由于您的每条曲线都有一个控制点(一个影响曲线但不一定在曲线上的点),您使用的是二次贝塞尔曲线。
如果要绘制共享端点的两条二次曲线,并且希望关节看起来平滑,则共享端点每侧的控制点必须与端点共线。也就是说,两个控制点和它们之间的端点必须全部位于一条直线上。例如:
实心黑色光盘是端点。空心圆是控制点。黑色实线是曲线。虚线表示每个端点与两侧的控制点共线(在一条直线上)。