WPF将点列连接成光滑曲线——贝塞尔曲线
2015-04-14 16:38
537 查看
背景
最近在写一个游戏场景编辑器,虽然很水,但是还是遇到了不少问题。连接离散个点列成为光滑曲线就是一个问题。主要是为了通过关键点产生2D的赛道场景。总之马路不可能是直线相连的,当然需要曲线光滑相连。现在我就来解决这个问题。贝塞尔曲线
贝塞尔曲线,又称贝兹曲线或贝济埃曲线,一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。当然在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。这里是百度里面的介绍。直接搬过来了。
问题
如图,这些绿色的点我们希望用光滑的曲线连接它们。
看看WPF给我们提供的函数:
来自MSDN
我们发现point3和point4是我们需要的,这两个点我们直接可以从点列中取得,但是point1和point2如何获取呢?控制点到底是个什么东西。当然我试了很多次失败了很多次~~
巧妙的解决方案
大致思路就是 先算出相邻原始点的中点,在把相邻中点连成的线段平移到对应的原始点,以平移后的中点作为控制点,相邻原始点为起始点画贝塞尔曲线,这样就保证了连接处的光滑。而贝塞尔曲线本身是光滑的,所以就把这些原始点用光滑曲线连起来了。(http://liyiwen.javaeye.com/blog/705489)
实验结果
看起来连接的还是比较光滑的。
相关代码
Path path; public void UpdateRoad() { MapCanvas.Children.Remove(path); if (ScenePoint.roadPoint.Count > 0) { List<Point> list = new List<Point>(); foreach (ScenePoint sp in ScenePoint.roadPoint) { list.Add(new Point((sp.position.X + Shift.X) * Zoom, (sp.position.Y + Shift.Y) * Zoom)); } 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; MapCanvas.Children.Add(path); } } public void UpdateHeightCanvas() { HeightCanvas.Children.Clear(); foreach (ScenePoint sp in ScenePoint.listPoint) { HeightCanvas.Children.Add(sp.Ellipseh); } } 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 ); } if (n == list.Count - 1) { point[1] = list[list.Count - 1]; } else { point[1] = Average(list , list[n+1]); } Point ave = Average(point[0], point[1]); Point sh = Sub(list , ave); point[0] = Mul(Add(point[0], sh),list ,0.6); point[1] = Mul(Add(point[1], sh),list ,0.6); //Line line = new Line(); //line.X1 = point[0].X; //line.Y1 = point[0].Y; //line.X2 = point[1].X; //line.Y2 = point[1].Y; //line.Stroke = Brushes.Red; //MapCanvas.Children.Add(line); 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) { Point temp = Sub(x, y); temp = new Point(temp.X * d, temp.Y * d); temp = Add(y, temp); return temp; }转自:/article/5283961.html
相关文章推荐
- WPF将点列连接成光滑曲线——贝塞尔曲线
- canvas中的点用贝斯曲线连接成光滑曲线(解决移动端画布模糊问题)
- 平滑曲线连接各点(贝塞尔曲线)
- 用matlab画散点图并用光滑曲线连接(样条插值)
- WPF如何绘制光滑连续贝塞尔曲线示例代码
- 使用Unity画一条平滑曲线(贝塞尔曲线)并使小球沿曲线运动
- 实现曲线的光滑拟合,多次趋近直线
- WPF 连接数据库中文编码显示
- WPF连接数据库+显示数据到dataGrid
- 小程序二次贝塞尔曲线,购物车商品曲线飞入效果
- WPF DataGrid 数据绑定、样式、分页、增删改查,连接Access数据库
- 解决PcAnywhere 12.0在Windows 2003 Server中远程连接,WPF界面无法显示的问题
- C#中wpf使用Devexpress画图:柱状图,饼状图,散点图,曲线图
- Android贝塞尔曲线——曲线进阶
- Unity中利用贝塞尔曲线来实现3D中的曲线运动
- JFreeChart简单实现光滑曲线绘制
- java 三次样条插值 画光滑曲线 例子
- WPF连接数据库config文件
- 如何得到贝塞尔曲线的曲线长度和 t 的近似关系?
- wpf利用Visifire.Chart实现实时曲线绘制