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

贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自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视图如下:

效果如下动画所示:

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

 using System.Collections;
using System.Collections.Generic;
using UnityEngine; //实现代码如下:(最外层有6个点,依次5,4,3,2,1)
//添加一个小球,沿曲线运动,使小球看向目标物体
public class Test_DrawLine : MonoBehaviour { [SerializeField] private Transform points; //控制点父对象
private List<Transform> point_tranList = new List<Transform>(); //控制点列表
[SerializeField] private int pointCount = ; //曲线点的个数
private List<Vector3> line_pointList; //曲线点列表 [SerializeField] private Transform lookTarget; //看向目标
[SerializeField] private GameObject ball; //运动物体
[SerializeField] private float time0 = ; //曲线点之间移动时间间隔
private float timer = ; //计时器
private int item = ; //曲线点的索引
private bool isTrue = false; //使小球沿曲线运动
//这里不能直接在for里以Point使用差值运算,看不到小球运算效果
//定义一个计时器,在相隔时间内进行一次差值运算。
void Awake()
{
Init();
}
void Init()
{
if (null != points && point_tranList.Count == )
{
foreach (Transform item in points)
{
point_tranList.Add(item);
}
}
line_pointList = new List<Vector3>();
for (int i = ; point_tranList.Count != && i < pointCount; i++)
{
//一
Vector3 pos1 = Vector3.Lerp(point_tranList[].position, point_tranList[].position, i / (float)pointCount);
Vector3 pos2 = Vector3.Lerp(point_tranList[].position, point_tranList[].position, i / (float)pointCount);
Vector3 pos3 = Vector3.Lerp(point_tranList[].position, point_tranList[].position, i / (float)pointCount);
Vector3 pos4 = Vector3.Lerp(point_tranList[].position, point_tranList[].position, i / (float)pointCount);
Vector3 pos5 = Vector3.Lerp(point_tranList[].position, point_tranList[].position, i / (float)pointCount); //二
var pos1_0 = Vector3.Lerp(pos1, pos2, i / (float)pointCount);
var pos1_1 = Vector3.Lerp(pos2, pos3, i / (float)pointCount);
var pos1_2 = Vector3.Lerp(pos3, pos4, i / (float)pointCount);
var pos1_3 = Vector3.Lerp(pos4, pos5, i / (float)pointCount);
//三
var pos2_0 = Vector3.Lerp(pos1_0, pos1_1, i / (float)pointCount);
var pos2_1 = Vector3.Lerp(pos1_1, pos1_2, i / (float)pointCount);
var pos2_2 = Vector3.Lerp(pos1_2, pos1_3, i / (float)pointCount);
//四
var pos3_0 = Vector3.Lerp(pos2_0, pos2_1, i / (float)pointCount);
var pos3_1 = Vector3.Lerp(pos2_1, pos2_2, i / (float)pointCount);
//五
Vector3 find = Vector3.Lerp(pos3_0, pos3_1, i / (float)pointCount); line_pointList.Add(find);
}
if (line_pointList.Count == pointCount)
isTrue = true;
} void Update()
{
if (!isTrue)
return;
timer += Time.deltaTime;
if (timer > time0)
{
timer = ;
if(item >= line_pointList.Count-)
{
ball.transform.LookAt(line_pointList[item]);
}
else
{
if (lookTarget)
ball.transform.LookAt(lookTarget);
else
ball.transform.LookAt(line_pointList[item]);
}
ball.transform.localPosition = Vector3.Lerp(line_pointList[item - ], line_pointList[item], 1f);
item++;
if (item >= line_pointList.Count)
item = ;
}
} //------------------------------------------------------------------------------
//在scene视图显示
void OnDrawGizmos()//画线
{
Init();
Gizmos.color = Color.yellow;
for (int i = ; i < line_pointList.Count - ; i++)
{
Gizmos.DrawLine(line_pointList[i], line_pointList[i + ]);
}
} }

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

  1. Java_Swing实现小球沿正弦曲线运动的代码

    1 package zuidaimapack_1; import java.awt.*; import javax.swing.*; /** *Java_Swing实现小球沿正弦曲线运动的代码 * @ ...

  2. html5 canvas高级贝塞尔曲线运动动画(好吧这一篇被批的体无完肤!都说看不懂了!没办法加注释了!当然数学不好的我也没办法了,当然这还涉及到一门叫做计算机图形学的学科)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Unity3d场景漫游---iTween实现

    接触U3D以来,我做过的场景漫游实现方式一般有以下几种: Unity3d中的Animation组件,通过设置摄像机的关键点实现场景漫游 第一人称或第三人称控制器 编写摄像机控制脚本 iTween iT ...

  4. 基于SketchUp和Unity3D的虚拟场景漫游和场景互动

    这是上学期的一次课程作业,难度不高但是也一并记录下来,偷懒地拿课程报告改改发上来. 课程要求:使用sketchUp建模,在Unity3D中实现场景漫游和场景互动. 知识点:建模.官方第一人称控制器.网 ...

  5. unity3d简单的相机跟随及视野旋转缩放

    1.实现相机跟随主角运动 一种简单的方法是把Camera直接拖到Player下面作为Player的子物体,另一种方法是取得Camera与Player的偏移向量,并据此设置Camera位置,便能实现简单 ...

  6. php 简单计算权重的方法(适合抽奖类的应用)

    //简单权重计算器 $data222=array(     0=>array('id'=>1,'name'=>'一等奖','weight'=>'3'),     1=>a ...

  7. Unity3D 简单的倒计时

    using System; using UnityEngine; using System.Collections; public class TimeCountdown : MonoBehaviou ...

  8. Unity3d简单的socket通信

    vs2010或其他创建C#工程 C#端代码一: using System; using System.Collections.Generic; using System.Linq; using Sys ...

  9. egret贝塞尔曲线运动

    class MtwGame { public constructor() { } private static _instance: MtwGame; public static get Instan ...

随机推荐

  1. asp.net web api 控制器

    1控制器操作的参数 控制器操作的参数可以是内置类型也可以是自定义类型,无参也是允许的. 2控制器操作返回值 类型 说明 void 操作返回值为void时,Web API返回空HTTP响应,其状态码为2 ...

  2. Python之旅_计算机基础入门

    一.计算机基础 1.Python是编程语言 语言:一种事物与另一种事物沟通的介质. 编程语言:程序员与计算机沟通的介质. 什么是编程:程序员用编程语言把自己的逻辑思想下来,编程的结果就是一堆文件. 为 ...

  3. Mysql数据库mys和ora库的备份与恢复脚本

    !/bin/bash Time=$(date +%Y%md%H%M%S) Back_dir="$HOME/mysqlback/${Time}" function Detect_u_ ...

  4. 大数据学习总结(5)参考elk技术架构

  5. UVA732【DFS+栈】

    题目:已知两个单词,利用一个栈,将第一个单词变成第二个单词,求出所有可能的操作序列. #include <stdio.h> #include<iostream> #includ ...

  6. python Josnp(跨域)

    python Josnp(跨域) 所谓的跨域就是进行不用域名内的请求,好比如说我在A域名想访问B域名的内容就是一种跨域的行为. 但是在我们浏览器端会有一个同源策略的设置,这个同源策略只对Ajax请求有 ...

  7. SpringMVC(十二):SpringMVC 处理输出模型数据之@ModelAttribute

    Spring MVC提供了以下几种途径输出模型数据:1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据:2)Map及Model:处理方法入参 ...

  8. WPF在在设计模式,使用动态样式

    1.问题分析 WPF有时候要用到主题样式,比如颜色主题(红色.黄色之类的)通常是key相同,而value不同,比如会这么写: Background="{DynamicResource Bac ...

  9. [转]pycharm常用快捷键及设置

    PyCharm3.0默认快捷键(翻译的) PyCharm Default Keymap 1.编辑(Editing) Ctrl + Space    基本的代码完成(类.方法.属性)Ctrl + Alt ...

  10. 爬取IP

    import urllib.request import re def url_open(url): req = urllib.request.Request(url,headers={'User-A ...