游戏开发中的贝塞尔曲线

目的
了解Bezier Curve(贝塞尔曲线)的计算方式

预览

本章实现效果如下


简介

贝塞尔曲线是最基本的一种曲线,通常用于计算机图行和图像的处理。可被用来创建平滑弯曲的道路,如同祖玛游戏中弯曲的道路,蜿蜒的河流一样。

通过设置一组从 P0到Pn的点来定义一条贝塞尔曲线,其中n表示曲线的序列点(n=1时为一次,n=2时为二次)。第一个和最后一个点通常是曲线的结束点。如果在两个点之间有控制点的话,控制点通常并不在曲线路径上。

  • 贝塞尔曲线包含两个控制点(即n=2)的贝塞尔曲线称之为线性贝塞尔曲线
  • 贝塞尔曲线包含三个控制点(即n=3)的贝塞尔曲线称之为二次贝塞尔曲线
  • 贝塞尔曲线包含四个控制的(即n=4)得贝塞尔曲线称之为立方贝塞尔曲线

贝塞尔函数在贝塞尔曲线上返回点,以线性插值的概念作为基础。因此,我们首先理解什么是线性插值。

线性插值
  • 线性插值是介于两个点之间在不同的t时间点获得得一个值,其中0<t<1,Unity3D中的Mathf.Lerp()函数就是基于此。
    其公式为:

P = P 0 + t ( P 1 − P 0 ) , 0 &lt; = t &lt; = 1 P=P_0+t(P_1-P_0),0&lt;=t&lt;=1 P=P0+t(P1P0),0<=t<=1

  • 为了能够得到插值点,根据两个点之间的距离进行时间t的积分:

  • 当t=0时,P=P0

  • 当t=1时,P=P1

  • 当t=0.5时,P=(P1-P0)/2

线性贝塞尔曲线
  • 线性贝塞尔曲线有两个控制点,分别为P0和P1,线性贝塞尔曲线即为介于两个控制点之间的一条直线。该曲线相当于线性插值,其实现公式如下:

B ( t ) = P 0 + t ∗ ( P 1 − P 0 ) = ( 1 − t ) ∗ P 0 + t ∗ P 1 , 0 &lt; = t &lt; = 1 B(t)=P_0+t*(P_1-P_0)=(1-t)*P_0+t*P_1,0&lt;=t&lt;=1 B(t)=P0+t(P1P0)=(1t)P0+tP1,0<=t<=1

  • 线性贝塞尔曲线的计算过程动画演示效果如下:

二次贝塞尔曲线
  • 二次贝塞尔曲线有三个控制点,二次贝塞尔曲线是两个线性贝塞尔曲线点对点插值的结果。对于给定的三个点P0、P1、P2,二次贝塞尔曲线是两个点之间的插值,即P0到P1之间的线性插值和P1到P2之间的线性插值;因此,二次贝塞尔曲线的计算公式如下:

B ( t ) = ( 1 − t ) ∗ B p 0 , p 1 ( t ) + t ∗ B p 1 , p 2 ( t ) ; 0 &lt; = t &lt; = 1 B(t)=(1-t)*Bp0,p1(t)+t*Bp1,p2(t);0&lt;=t&lt;=1 B(t)=(1t)Bp0,p1(t)+tBp1,p2(t);0<=t<=1
B ( t ) = ( 1 − t ) [ ( 1 − t ) P 0 + t P 1 ] + t ∗ [ ( 1 − t ) P 1 + t P 2 ] ; 0 &lt; = t &lt; = 1 B(t)=(1-t)[(1-t)P0+tP1]+t*[(1-t)P1+tP2];0&lt;=t&lt;=1 B(t)=(1t)[(1t)P0+tP1]+t[(1t)P1+tP2];0<=t<=1

  • 对上面两个公式合并重新排列如下:

B ( t ) = ( 1 − t ) 2 P 0 + 2 ( 1 − t ) ∗ P 1 ∗ t + t 2 ∗ p 2 ; 0 &lt; = t &lt; = 1 B(t)=(1-t)^2P0+2(1-t)*P1*t+t^2*p2; 0&lt;=t&lt;=1 B(t)=(1t)2P0+2(1t)P1t+t2p2;0<=t<=1

  • 二次贝塞尔曲线的计算过程动画演示效果如下:

三次贝塞尔曲线
  • 三次贝塞尔曲线有四个控制点;三次贝塞尔曲线是一系列介于两个二次贝塞尔的点对点的插值。对于给定的四个点P0,P1,P2,P3,三次贝塞尔曲线是两个点之间的线性插值,即P0,P1,P2之间的二次贝塞尔曲线和P1,P2,P3之间的二次贝塞尔曲线;因此,三次贝塞尔曲线的计算公式如下:

B ( t ) = ( 1 − t ) ∗ B p 0 , p 1 , p 2 ( t ) + t ∗ B p 1 , p 2 , p 3 ( t ) ; 0 &lt; = t &lt; = 1 B(t)=(1-t)*Bp0,p1,p2(t)+t*Bp1,p2,p3(t);0&lt;=t&lt;=1 B(t)=(1t)Bp0,p1,p2(t)+tBp1,p2,p3(t);0<=t<=1
B ( t ) = ( 1 − t ) [ ( 1 − t ) 2 ∗ P 0 + 2 ( 1 − t ) ∗ P 1 + t 2 ∗ P 2 ] + t ∗ [ ( 1 − t ) 2 P 1 + 2 ∗ ( 1 − t ) t ∗ P 2 + t 2 P 3 ] ; 0 &lt; = t &lt; = 1 B(t)=(1-t)[(1-t)^2*P0+2(1-t)*P1+t^2*P2]+t*[(1-t)^2P1+2*(1-t)t*P2+t^2P3];0&lt;=t&lt;=1 B(t)=(1t)[(1t)2P0+2(1t)P1+t2P2]+t[(1t)2P1+2(1t)tP2+t2P3];0<=t<=1

  • 对上面两个公式合并重新排列如下:

B ( t ) = ( 1 − t ) 3 ∗ P 0 + 3 ( 1 − t ) 2 ∗ t ∗ p 1 + 3 ∗ ( 1 − t ) ∗ t 2 P 2 + t 3 ∗ P 3 ; 0 &lt; = t &lt; = 1 B(t)=(1-t)^3*P0+3(1-t)^2*t*p1+3*(1-t)*t^2P2+t^3*P3;0&lt;=t&lt;=1 B(t)=(1t)3P0+3(1t)2tp1+3(1t)t2P2+t3P3;0<=t<=1

  • 三次贝塞尔曲线的计算过程动画演示效果如下:


  • 因此,通常根据n来定义贝塞尔曲线的维度;度数为n的贝塞尔曲线可以通过度数为n-1的两条贝塞尔曲线之间点对点的插值获得。

Demo

大多数的应用程序中,贝塞尔曲线的使用很频繁。通常情况下,你可能使用较高维度的贝塞尔函数来处理较为复杂的曲线,但是这种做法通常会更加复杂并且会增加计算开销。面对这种情况,我们可以多次使用二次或者三次贝塞尔函数来替代使用高纬度的贝塞尔曲线。在这个Demo中,创建了一个形状的曲线,在循环中使用两次三次贝塞尔曲线来完成如下所示的效果:


核心代码如下所示:

依据以下公式:

B ( t ) = ( 1 − t ) 3 ∗ P 0 + 3 ( 1 − t ) 2 ∗ t ∗ p 1 + 3 ∗ ( 1 − t ) ∗ t 2 P 2 + t 3 ∗ P 3 ; 0 &lt; = t &lt; = 1 B(t)=(1-t)^3*P0+3(1-t)^2*t*p1+3*(1-t)*t^2P2+t^3*P3;0&lt;=t&lt;=1 B(t)=(1t)3P0+3(1t)2tp1+3(1t)t2P2+t3P3;0<=t<=1

Vector3 CalculateCubicBezierPoint (float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        float uuu = uu * u;
        float ttt = tt * t;

        Vector3 p = uuu * p0;
        p += 3 * uu * t * p1;
        p += 3 * u * tt * p2;
        p += ttt * p3;

        return p;
    }

获取Demo:

扫码关注->历史消息->当前文章末尾->Demo地址:


在这里插入图片描述

翻译自:

http://www.theappguruz.com/blog/bezier-curve-in-games

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SU贝兹曲线插件(BezierSpline)是一款多种方式绘制完美的曲线。此款为用户打造提供可以绘制常规的曲线,同时也具有断线焊接的功能,相信一定可以对你的工作提供便利的帮助,让你的效率更高。 贝兹曲线怎么用 画曲线和把断开的线合并,先说画曲线,你可以一个一个点,你就会明白了,画完右键点击完成就行,也可以右键在菜单选择编辑,那样就可以做细调整。还有就是点击工具栏以后可以直接更改段数与最大控制点,也可以在画完以后更改,跟自带圆弧改段数一样;另外一个就是合并,选断开曲线,右键转为贝兹,要是更改段数选更改固定段数,按提示操作,最重要的还是多练习。 贝兹曲线插件介绍 一、手绘工具: 1、绘直线: 单条直线:单击起点,再单击终点, 连续直线:单击起点,再双击终点,再双击另一个终点。。。。。 2、绘曲线:按住鼠标左键不放,随意移动即可。 3、属性:线型,箭头,平滑度。 二、贝塞尔工具: 1、绘直线和折线:逐次单击。 2、绘曲线:按住鼠标左键不放,拖出控制线 3、用造型工具调整。 三、造型工具: 增加节点:1、双击直线任意部分(不是节点);2、点直线任意部分,再点 减少节点:1、双击节点;2、选节点,再点 结合节点:选一个物体的两个节点,再点 断开节点:选物体的一个或多个节点,再点 。   曲线转换为直线: 更新日志 版本1.6d新增功能 完美汉化 完善SketchUp2014版本支持; 规范命令名称,补充“固定段数多段线”、“编辑曲线”功能; 解决右键菜单重复载入的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值