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号