WPF将点列连接成光滑曲线——贝塞尔曲线
背景
最近在写一个游戏场景编辑器,虽然很水,但是还是遇到了不少问题。连接离散个点列成为光滑曲线就是一个问题。主要是为了通过关键点产生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[n]);}if (n == list.Count - 1){point[1] = list[list.Count - 1];}else{point[1] = Average(list[n], list[n+1]);}Point ave = Average(point[0], point[1]);Point sh = Sub(list[n], ave);point[0] = Mul(Add(point[0], sh),list[n],0.6);point[1] = Mul(Add(point[1], sh),list[n],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;}
WPF将点列连接成光滑曲线——贝塞尔曲线相关推荐
- WPF绘制光滑连续贝塞尔曲线
原文:WPF绘制光滑连续贝塞尔曲线 1.需求 WPF本身没有直接把点集合绘制成曲线的函数.可以通过贝塞尔曲线函数来绘制. 贝塞尔曲线类是:BezierSegment,三次贝塞尔曲线,通过两个控制点来控 ...
- bezier曲线_套娃成神:贝塞尔曲线
说明: 主要参考了 维基百科 , 建议将其和本文对照阅读. 应用场景 贝塞尔曲线在数学和图形学以及设计中都发挥了重要作用,原因就是它能够"作为一种多项式逼近在[ a, b ] 区间上所有的连 ...
- python 贝塞尔曲线,贝塞尔曲线原理分析及其Android的实现
本文主要内容为贝塞尔曲线原理解析并用 SurfaceView 实现其展示动画 关于SurfaceView 的使用,大家可以看我的上一篇文章 Android:SurfaceView 的使用(附代码模板) ...
- php 贝瑟尔曲线,贝塞尔曲线的应用详解
简介 贝塞尔曲线是可以做出很多复杂的效果来的,比如弹跳球的复杂动画效果,首先加速下降,停止,然后弹起时逐渐减速的效果. 使用贝塞尔曲线常用的两个网址如下: 缓动函数: cubic-bezier: 如何 ...
- 技术分享 | 一条神奇的曲线——贝塞尔曲线在前端的应用
源宝导读:在前端的开发中我们经常会遇到利用贝塞尔曲线帮助我们完成前端的动画和图形绘制,但是对其中的一些参数配置是一头雾水.本文将从贝塞尔曲线的原理讲起,由浅入深剖析一阶到多阶贝塞尔的实现原理,最后从三 ...
- 【Android UI】贝塞尔曲线 ③ ( 贝塞尔曲线关键点坐标记录 | 二阶贝塞尔曲线示例 )
文章目录 一.贝塞尔曲线关键点坐标记录 二.二阶贝塞尔曲线示例 三.代码示例 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一.贝塞尔曲线关键点坐 ...
- 【Android UI】贝塞尔曲线 ⑥ ( 贝塞尔曲线递归算法原理 | 贝塞尔曲线递归算法实现 )
文章目录 一.贝塞尔曲线递归算法 二.贝塞尔曲线递归算法实现 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一.贝塞尔曲线递归算法 一阶贝塞尔曲线 ...
- WPF 跟随拖动改变的三次贝塞尔曲线思路
代码不多,思路也很简单, 先看看效果: 简单示例,所有代码都在MainWindow.xaml和MainWindow.xaml.cs内, Xaml代码: <Window x:Class=" ...
- Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效
Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效 特效预览图 什么是贝塞尔曲线? 百度百科: 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图 ...
最新文章
- apache kafka技术分享系列(目录索引)--转载
- IT人员健康信号之舌苔
- SAP MM 用户不希望采购订单一旦Release就自动打印输出,如何控制?
- 【Tensorflow-Error】CUDA_ERROR_OUT_OF_MEMORY: out of memory
- 理解 JavaScript 闭包
- Andorid之KeyguardManager的介绍
- scheduling java_JAVA定时任务实现的几种方式
- raspberry pi_适用于Linux,Raspberry Pi和开源的游戏:年度热门读物
- Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(1)
- 控制台报错:java.lang.ClassNotFoundException: javax.xml.bind.JAXBException之解决方法
- 关于图神经网络的相关学习资源的分享——网站 博客(一)
- 凹凸性和Jensen不等式
- Origin introduction and install
- ubuntu安装xp字体
- Telink BLE MESH开发|ble mesh开发教程《四》telink_sig_mesh休眠与唤醒
- R 编程语言 - 简介
- freenom 加 cloudflare免费域名申请
- mysql报错error2002_mysql中异常出错ERROR:2002的处理办法分享
- 计算机考研380分难吗,考研380分相当于高考多少分的难度
- Maven——简介、下载安装与配置