C# 如何通过几个点绘制贝塞尔曲线?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13940983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to draw bezier curve by several points?
提问by Roman Bats
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 points - first segment
- 3,4,5 points - second
- 5,6,7.. ..
- 1,2,3 点 - 第一段
- 3,4,5 点 - 秒
- 5、6、7……
But I got this strange curve (here is 3 big (Nodes) and 7 small ellipse (is my points)):
但是我得到了这条奇怪的曲线(这里有 3 个大(节点)和 7 个小椭圆(是我的点)):
采纳答案by Rawling
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"?)
你得到的线是三个不同的贝塞尔曲线的联合 - 每组三个点一个。(每个“贝塞尔曲线段”一个?)
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.
如果您想要一条平滑的曲线,则需要将 9 个(或更多)点作为单个点集合(单个“贝塞尔线段”?)传递,而不是作为三个点的组传递。
Edit: Apparently BezierSegment
only supportsthree points, so no wonder this doesn't work. Even 'PolyBezierSegment'just gives a collection of Bezier segments rather than a single smooth Bezier...
编辑:显然BezierSegment
只支持三点,所以难怪这不起作用。甚至“PolyBezierSegment”也只是给出了一系列贝塞尔曲线段,而不是一个平滑的贝塞尔曲线……
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:
因此,由于 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);
}
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);
}
gives
给
回答by rob mayoff
Since each of your curves has one control point (a point that influences the curve but isn't necessarily on the curve), you're using quadratic Bézier curves.
由于每条曲线都有一个控制点(影响曲线但不一定在曲线上的点),因此您使用的是二次贝塞尔曲线。
If you want to draw two quadratic curves that share an endpoint, and you want the joint to appear smooth, the control points on each side of the shared endpoint must be collinear with the endpoint. That is, the two control points and the endpoint between them must all lie on a straight line. Example:
如果要绘制两条共享端点的二次曲线,并且希望关节看起来平滑,则共享端点每一侧的控制点必须与端点共线。也就是说,两个控制点和它们之间的端点必须都在一条直线上。例子:
The solid black discs are the endpoints. The hollow circles are the control points. The solid black line is the curve. The dotted lines show that each endpoint is collinear (on a straight line with) the control point on either side.
实心黑色圆盘是端点。空心圆是控制点。黑色实线是曲线。虚线显示每个端点与任一侧的控制点共线(在一条直线上)。