WPF点连成曲线,贝塞尔曲线两种画法
先看效果图:
黑色是需要经过的点;
黄色为控制点;
绿色为两点之间的中点。
方式一:

方式二:

<Canvas x:Name="canvas2"/>
方法一代码,【这是别人的代码,时间久了忘记原出处了】:
Path path;
public void UpdateRoad(List<Point> list)
{
double x = this.canvas2.ActualWidth;
double y = this.canvas2.ActualHeight;
PathFigure pf = new PathFigure();
pf.StartPoint = list[0];
List<Point> controls = new List<Point>();
for (int i = 0; i < list.Count; i++)
{
controls.AddRange(Control1(list, i));
}
for (int i = 1; i < list.Count; i++)
{
BezierSegment bs = new BezierSegment(controls[i * 2 - 1], controls[i * 2], list[i], true);
bs.IsSmoothJoin = true;
pf.Segments.Add(bs);
}
PathFigureCollection pfc = new PathFigureCollection();
pfc.Add(pf);
PathGeometry pg = new PathGeometry(pfc);
path = new Path();
path.Stroke = Brushes.Black;
path.Data = pg;
canvas2.Children.Add(path);
}
public List<Point> Control1(List<Point> list, int n)
{
List<Point> point = new List<Point>();
point.Add(new Point());
point.Add(new Point());
if (n == 0)
{
point[0] = list[0];
}
else
{
point[0] = Average(list[n - 1], list[n]);
}
if (n == list.Count - 1)
{
point[1] = list[list.Count - 1];
}
else
{
point[1] = Average(list[n], list[n + 1]);
}
Point footPoint = Average(point[0], point[1]);
Point sh = Sub(list[n], footPoint);
point[0] = Mul(Add(point[0], sh), list[n]);
point[1] = Mul(Add(point[1], sh), list[n]);
AddPoint(point[0]);
AddPoint(point[1]);
return point;
}
public Point Average(Point x, Point y)
{
return new Point((x.X + y.X) / 2, (x.Y + y.Y) / 2);
}
public Point Add(Point x, Point y)
{
return new Point(x.X + y.X, x.Y + y.Y);
}
public Point Sub(Point x, Point y)
{
return new Point(x.X - y.X, x.Y - y.Y);
}
public Point Mul(Point x, Point y, double d = 0.6)
{
Point temp = Sub(x, y);
temp = new Point(temp.X * d, temp.Y * d);
temp = Add(y, temp);
return temp;
}
方式二代码:
Path path2 = null;
private void PaintLine(List<Point> points)
{
StringBuilder data = new StringBuilder("M");
data.AppendFormat("{0},{1} C", points[0].X, points[0].Y);for (int i = 1; i < points.Count; i++)
{
Point pre = new Point((points[i - 1].X + points[i].X) / 2, points[i - 1].Y); //控制点
Point next = new Point((points[i - 1].X + points[i].X) / 2, points[i].Y); //控制点
data.AppendFormat(" {0},{1} {2},{3} {4},{5}", pre.X, pre.Y, next.X, next.Y, points[i].X, points[i].Y);
}
path2 = new Path { Stroke = Brushes.DodgerBlue, StrokeThickness = 1, Data = Geometry.Parse(data.ToString()) };
this.canvas2.Children.Add(path2);
}
方法二逻辑简单得多,代码量也特别少,控制点为两点之间的中点,然后第一个控制点与第一个点水平,第二个控制点与第二个点水平。
浙公网安备 33010602011771号