简单的小球沿贝塞尔曲线运动,适合场景漫游使用

贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自http://blog.csdn.net/u010019717/article/details/47684223 。仅供学习,知识分享。如有侵权,联系删除。)

贝塞尔曲线是最基本的曲线,一般用在计算机 图形学和 图像处理。贝塞尔曲线可以用来创建平滑的曲线的道路、 弯曲的路径就像 祖玛游戏、 弯曲型的河流等。

一条贝塞尔曲线是由一组定义的控制点 P0到 Pn,在 n 调用它的顺序 (n = 1 为线性,2 为二次,等.)。第一个和最后一个控制点总是具有终结点的曲线;然而,中间两个控制点 (如果有的话) 一般不会位于曲线上 。

贝塞尔曲线包含两个控制点即 n = 2 称为线性的贝塞尔曲线

贝塞尔曲线包含三个控制点即 n = 3 称为二次贝塞尔曲线

贝塞尔曲线包含四个控制点即 n = 4,所以称为三次贝塞尔曲线。

贝塞尔曲线返回点的贝塞尔函数,使用线性插值的概念作为基础。所以,让我们了解什么首先是线性插值。

两个点之间的线性插值的点获取那两个点之间,0 <= t <= 1,像 Mathf.Lerp 。

插值点,与 P 公式P0和 P1可以写成,

P = P0+ t (P1 - P0),0 <= t <= 1

在这里,为得到插值的点我们添加 tth指向 P 的分数与这两个之间的距离0.所以,

For T = 0,P = P0.

For T = 1,P = P1.

For T = 0.5,P =  P0和 P1间的点.

线性的贝塞尔曲线:

线性的贝塞尔曲线有两个控制点。为给出了两个点 P0和 P1一个线性的贝塞尔曲线是只是这两个点之间的直线。曲线是相当于线性插值给出,

B(t) = P0+ t (P1 -  P0) = (1-t) P0 + tP1    ,0 <= t <= 1

线性贝塞尔曲线如何计算出来的是如下所示:

二次贝塞尔曲线:

二次贝塞尔曲线具有三个控制点。二次贝塞尔曲线是点对点的两个线性贝塞尔曲线的线性插值。为给出了三个点 P0、P1和 P2一条二次贝塞尔曲线,其实是两条线性的贝塞尔曲线,线性贝塞尔曲线的 P0和 P1和   线性贝塞尔曲线P1和 P2.     所以,给出二次贝塞尔曲线 :

B(t) = (1-t) BP0P1(t) + t BP1P2(t),0 <= t <= 1

B(t) = (1-t) [(1-t) P0 + tP1] + t [(1-t) P1+ tP2],0 <= t <= 1

通过重新排列上述方程,

B(t) = (1-t)2P0+ 2 (1-t) tP1 + t2P2,   0 <= t <= 1

二次贝塞尔曲线动画计算如下所示:

三次贝塞尔曲线:

三次方贝塞尔曲线具有四个控制点。二次贝塞尔曲线是  点对点的两条二次贝塞尔曲线的线性插值。对于给出的四个点 P0、P1、P2和 P3三次方贝塞尔曲线,是二次贝塞尔曲线P0、P1和 P2和   二次贝塞尔曲线P1、P2和 P3 得到的 线性插值  .所以,给出三次方贝塞尔曲线

B(t) = (1-t) BP0,P1,P2(t) + t BP1,P2,P3(t),0 <= t <= 1

B(t) = (1-t) [(1-t)2P0+ 2 (1-t) tP1 + t2P2] + t [(1-t)2P1+ 2 (1-t) tP2 + t2P3],0 <= t <= 1

通过重新排列上述方程中,

B(t) = (1-t)3P0 + 3(1-t)2tP1+ 3 (1-t) t2P2 + t3P3           0 <= t <= 1

三次贝塞尔曲线计算如下所示:

所以,一般可以作为点对点的线性插值获得从两个相应的贝赛尔曲线的程度 n-1 的两个点定义程度 n 的贝塞尔曲线(就是高级的是两个低一级的线性插值)。

以下是本人所写。

Hierarchy视图如下:

效果如下动画所示:

脚本如下:(脚本挂载在场景中任意对象上)

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4
  5 //实现代码如下:(最外层有6个点,依次5,4,3,2,1)
  6 //添加一个小球,沿曲线运动,使小球看向目标物体
  7 public class Test_DrawLine : MonoBehaviour {
  8
  9     [SerializeField] private Transform points;                          //控制点父对象
 10     private List<Transform> point_tranList = new List<Transform>();     //控制点列表
 11     [SerializeField] private int pointCount = 100;                      //曲线点的个数
 12     private List<Vector3> line_pointList;                               //曲线点列表
 13
 14     [SerializeField] private Transform lookTarget;                      //看向目标
 15     [SerializeField] private GameObject ball;                           //运动物体
 16     [SerializeField] private float time0 = 0;                           //曲线点之间移动时间间隔
 17     private float timer = 0;                    //计时器
 18     private int item = 1;                       //曲线点的索引
 19     private bool isTrue = false;
 20
 21     //使小球沿曲线运动
 22     //这里不能直接在for里以Point使用差值运算,看不到小球运算效果
 23     //定义一个计时器,在相隔时间内进行一次差值运算。
 24     void Awake()
 25     {
 26         Init();
 27     }
 28     void Init()
 29     {
 30         if (null != points && point_tranList.Count == 0)
 31         {
 32             foreach (Transform item in points)
 33             {
 34                 point_tranList.Add(item);
 35             }
 36         }
 37         line_pointList = new List<Vector3>();
 38         for (int i = 0; point_tranList.Count != 0 && i < pointCount; i++)
 39         {
 40             //一
 41             Vector3 pos1 = Vector3.Lerp(point_tranList[0].position, point_tranList[1].position, i / (float)pointCount);
 42             Vector3 pos2 = Vector3.Lerp(point_tranList[1].position, point_tranList[2].position, i / (float)pointCount);
 43             Vector3 pos3 = Vector3.Lerp(point_tranList[2].position, point_tranList[3].position, i / (float)pointCount);
 44             Vector3 pos4 = Vector3.Lerp(point_tranList[3].position, point_tranList[4].position, i / (float)pointCount);
 45             Vector3 pos5 = Vector3.Lerp(point_tranList[4].position, point_tranList[5].position, i / (float)pointCount);
 46
 47             //二
 48             var pos1_0 = Vector3.Lerp(pos1, pos2, i / (float)pointCount);
 49             var pos1_1 = Vector3.Lerp(pos2, pos3, i / (float)pointCount);
 50             var pos1_2 = Vector3.Lerp(pos3, pos4, i / (float)pointCount);
 51             var pos1_3 = Vector3.Lerp(pos4, pos5, i / (float)pointCount);
 52             //三
 53             var pos2_0 = Vector3.Lerp(pos1_0, pos1_1, i / (float)pointCount);
 54             var pos2_1 = Vector3.Lerp(pos1_1, pos1_2, i / (float)pointCount);
 55             var pos2_2 = Vector3.Lerp(pos1_2, pos1_3, i / (float)pointCount);
 56             //四
 57             var pos3_0 = Vector3.Lerp(pos2_0, pos2_1, i / (float)pointCount);
 58             var pos3_1 = Vector3.Lerp(pos2_1, pos2_2, i / (float)pointCount);
 59             //五
 60             Vector3 find = Vector3.Lerp(pos3_0, pos3_1, i / (float)pointCount);
 61
 62             line_pointList.Add(find);
 63         }
 64         if (line_pointList.Count == pointCount)
 65             isTrue = true;
 66     }
 67
 68     void Update()
 69     {
 70         if (!isTrue)
 71             return;
 72         timer += Time.deltaTime;
 73         if (timer > time0)
 74         {
 75             timer = 0;
 76             if(item >= line_pointList.Count-10)
 77             {
 78                 ball.transform.LookAt(line_pointList[item]);
 79             }
 80             else
 81             {
 82                 if (lookTarget)
 83                     ball.transform.LookAt(lookTarget);
 84                 else
 85                     ball.transform.LookAt(line_pointList[item]);
 86             }
 87             ball.transform.localPosition = Vector3.Lerp(line_pointList[item - 1], line_pointList[item], 1f);
 88             item++;
 89             if (item >= line_pointList.Count)
 90                 item = 1;
 91         }
 92     }
 93
 94     //------------------------------------------------------------------------------
 95     //在scene视图显示
 96     void OnDrawGizmos()//画线
 97     {
 98         Init();
 99         Gizmos.color = Color.yellow;
100         for (int i = 0; i < line_pointList.Count - 1; i++)
101         {
102             Gizmos.DrawLine(line_pointList[i], line_pointList[i + 1]);
103         }
104     }
105
106 }

转载于:https://www.cnblogs.com/yanghui0702/p/yanghui20171122.html

Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)相关推荐

  1. 自定义View合辑(8)-跳跃的小球(贝塞尔曲线)

    为了加强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,所有的代码也都会开源,也希望读者能给个 star 哈 GitH ...

  2. 简单html js 特效,Js实现简单的小球运动特效

    废话不多说了,直接给大家贴js代码了,具体代码如下所示: //定义局部变量 var directX=;//定义x轴方向 var directY=;//定义y轴方向 var ballX=;//定义x轴坐 ...

  3. cocos匀速贝塞尔曲线运动

    cocos匀速贝塞尔曲线运动 const { ccclass, property } = cc._decorator;@ccclass export default class Expression ...

  4. 匀速贝塞尔曲线运动的实现(转)

    二次贝塞尔曲线通常以如下方式构建,给定二维平面上的固定点P0,P1,P2,用B(t)表示该条曲线 用一个动画来演示,可以更加清楚的表明这条曲线的构建过程 如果t变量本身线形变化的话,这条贝塞尔曲线本身 ...

  5. 关于《匀速贝塞尔曲线运动的实现》的过程推算

    原文: 作者:world 链接:https://www.zhihu.com/question/27715729/answer/293563315 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...

  6. 匀速贝塞尔曲线运动的实现

    转自:https://www.iteye.com/blog/as3-865587 二次贝塞尔曲线通常以如下方式构建,给定二维平面上的固定点P0,P1,P2,用B(t)表示该条曲线 用一个动画来演示,可 ...

  7. Unity3D简单的打飞机游戏

    Unity3D简单的打飞机游戏 这是下载地址,请自行下载 这是下载地址,请自行下载

  8. js实现简单的小球与边框碰撞反弹改变运动方向及颜色,并且继续运动的特效

    js实现简单的小球与边框碰撞反弹改变运动方向及颜色,并且继续运动的特效 (代码可以直接复制使用,只需要把body中的div的id换成对应的就行,css中可以设置小球的大小和初始位置,修改小球大小之后需 ...

  9. html5绘制运动的图形,html5 canvas高级贝塞尔曲线运动动画

    canvas高级贝塞尔曲线运动动画 window.addEventListener('load',eventWindowLoaded,false);functioneventWindowLoaded( ...

最新文章

  1. Hololens2-OpenXR开发(二)-实现通讯
  2. java web与android互通的aes算法
  3. 解决方案架构师我需要懂代码吗_架构师不写代码,能行吗?
  4. ajax dorado,02. Dorado的AJAX异常
  5. java class文件常量池_《Java虚拟机原理图解》 1.2.3、Class文件中的常量池详解(下)...
  6. 如何用 Python 给女友准备甜蜜的七夕礼物?
  7. 准备好的文字转换成语音的方法
  8. IHttpModule与IHttpHandler的区别整理
  9. 【图像处理】高斯模糊、高斯函数、高斯核、高斯卷积操作
  10. 小水智能-智能楼宇智慧建筑3D可视化系统,为房屋建设增加智能化
  11. Android无限流量统计,无限流量套餐国内也有 但并没什么用
  12. 地震了!最好直接砸死我!
  13. 「兔了个兔」龟兔赛跑——乌龟和兔子能否相遇?
  14. C++: explicit的适用场合以及为什么要使用explicit
  15. ora-00257报错解决办法
  16. 「Don‘t Make Me Think」 读后感
  17. 使用poi把excel分割为多个excel
  18. PyQt5制作一个爬虫小工具,爬取雪球网上市公司的财务数据
  19. LQ0023 三羊献瑞【枚举】
  20. 考研英语(41-50)转自何凯文老师

热门文章

  1. hbuilder ios 打包失败,无法导入p12证书的解决方案
  2. 洛谷P3807 【模板】卢卡斯定理exgcd
  3. Python之黏包的解决
  4. C# 中的委托(Delegate)
  5. 【Spring】23、ApplicationContext ,ApplicationContextAware,Listener,Event 的关系解读
  6. 单片机入门-矩阵键盘控制数码管显示
  7. Unity InvalidOperationException: out of sync错误
  8. 算法笔记_120:蓝桥杯第六届省赛(Java语言B组部分习题)试题解答
  9. 利用OpenCV的级联分类器类CascadeClassifier和Haar特征实现人脸区域的检测
  10. Java线程同步机制synchronized关键字的理解