Unity 工具类 之 贝塞尔 Bezier 曲线

目录

Unity 工具类 之 贝塞尔 Bezier 曲线

一、简单介绍

二、原理与分类

三、公式与原理图演示

五、注意事项

六、样例使用步骤(三次贝塞尔方程曲线)

七、代码


一、简单介绍

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

二、原理与分类

贝塞尔曲线返回点的贝塞尔函数,使用线性插值的概念作为基础。

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

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

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

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

三、公式与原理图演示

1.线性贝塞尔公式:

给定点P0、P1,线性贝兹曲线只是一条两点之间的直线。这条线由下式给出:

其等同于线性插值。

2.二次贝塞尔公式:

二次方贝兹曲线的路径由给定点P0、P1、P2控制,这条线由下式给出:

3.三次贝塞尔方程:

P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是用来充当控制点。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。

曲线的参数形式为:

4.一般参数形式的贝塞尔方程:

N阶贝兹曲线可如下推断。给定点P0、P1、…、Pn,其贝兹曲线即:

如上公式可如下递归表达: 用表示由点P0、P1、…、Pn所决定的贝兹曲线。

五、注意事项

1、通过两个低阶的贝塞尔曲线插值的堆叠总能够获得更高阶的贝塞尔曲线,通俗的来说通过对两条低阶的贝塞尔曲线插值,你可以求得一条高一阶的贝塞尔曲线。

2、二次贝塞尔曲线是点对点的两个线性贝塞尔曲线的线性插值,三次贝塞尔曲线是两条二次贝塞尔曲线的线性插值。

六、样例使用步骤(三次贝塞尔方程曲线)

1、打开Unity,新建一个场景,里面 添加一些球体,作为贝塞尔曲线点,如下图

2、新建贝塞尔接口脚本,和调用脚本,调用脚本挂载到 BezierDemo 物体上,并把球体依次赋值,如下图

3、运行场景,三次贝塞尔曲线效果,如下图

七、代码

1、BezierDemo 代码

using UnityEngine;[RequireComponent(typeof(LineRenderer))]
public class BezierDemo : MonoBehaviour
{// 三次贝塞尔控制点public Transform[] controlPoints;// LineRenderer private LineRenderer lineRenderer;private int layerOrder = 0;// 设置贝塞尔插值个数private int _segmentNum = 50;   void Start(){if (!lineRenderer){lineRenderer = GetComponent<LineRenderer>();}lineRenderer.sortingLayerID = layerOrder;}void Update(){DrawThreePowerCurve();}Vector3[] points3;void DrawThreePowerCurve(){// 获取三次贝塞尔方程曲线points3 = BezierUtils.GetThreePowerBeizerList(controlPoints[0].position, controlPoints[1].position, controlPoints[2].position, controlPoints[3].position, _segmentNum);// 设置 LineRenderer 的点个数,并赋值点值lineRenderer.positionCount = (_segmentNum);lineRenderer.SetPositions(points3);}}

2、BezierUtils 代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class BezierUtils
{/// <summary>/// 线性贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点/// </summary>/// <param name="t"></param>T值/// <param name="p0"></param>起始点/// <param name="p1"></param>控制点/// <returns></returns>根据T值计算出来的贝赛尔曲线点private static Vector3 CalculateLineBezierPoint(float t, Vector3 p0, Vector3 p1){float u = 1 - t;Vector3 p = u * p0;p +=  t * p1;return p;}/// <summary>/// 二次贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点/// </summary>/// <param name="t"></param>T值/// <param name="p0"></param>起始点/// <param name="p1"></param>控制点/// <param name="p2"></param>目标点/// <returns></returns>根据T值计算出来的贝赛尔曲线点private static Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2){float u = 1 - t;float tt = t * t;float uu = u * u;Vector3 p = uu * p0;p += 2 * u * t * p1;p += tt * p2;return p;}/// <summary>/// 三次贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点/// </summary>/// <param name="t">插量值</param>/// <param name="p0">起点</param>/// <param name="p1">控制点1</param>/// <param name="p2">控制点2</param>/// <param name="p3">尾点</param>/// <returns></returns>private static Vector3 CalculateThreePowerBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3){float u = 1 - t;float tt = t * t;float uu = u * u;float ttt = tt * t;float uuu = uu * u;Vector3 p = uuu * p0;p += 3 * t * uu * p1;p += 3 * tt * u * p2;p += ttt * p3;return p;}/// <summary>/// 获取存储贝塞尔曲线点的数组/// </summary>/// <param name="startPoint"></param>起始点/// <param name="controlPoint"></param>控制点/// <param name="endPoint"></param>目标点/// <param name="segmentNum"></param>采样点的数量/// <returns></returns>存储贝塞尔曲线点的数组public static Vector3[] GetLineBeizerList(Vector3 startPoint,  Vector3 endPoint, int segmentNum){Vector3[] path = new Vector3[segmentNum];for (int i = 1; i <= segmentNum; i++){float t = i / (float)segmentNum;Vector3 pixel = CalculateLineBezierPoint(t, startPoint, endPoint);path[i - 1] = pixel;Debug.Log(path[i - 1]);}return path;}/// <summary>/// 获取存储的二次贝塞尔曲线点的数组/// </summary>/// <param name="startPoint"></param>起始点/// <param name="controlPoint"></param>控制点/// <param name="endPoint"></param>目标点/// <param name="segmentNum"></param>采样点的数量/// <returns></returns>存储贝塞尔曲线点的数组public static Vector3[] GetCubicBeizerList(Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, int segmentNum){Vector3[] path = new Vector3[segmentNum];for (int i = 1; i <= segmentNum; i++){float t = i / (float)segmentNum;Vector3 pixel = CalculateCubicBezierPoint(t, startPoint,controlPoint, endPoint);path[i - 1] = pixel;Debug.Log(path[i - 1]);}return path;}/// <summary>/// 获取存储的三次贝塞尔曲线点的数组/// </summary>/// <param name="startPoint"></param>起始点/// <param name="controlPoint1"></param>控制点1/// <param name="controlPoint2"></param>控制点2/// <param name="endPoint"></param>目标点/// <param name="segmentNum"></param>采样点的数量/// <returns></returns>存储贝塞尔曲线点的数组public static Vector3[] GetThreePowerBeizerList(Vector3 startPoint, Vector3 controlPoint1, Vector3 controlPoint2 , Vector3 endPoint, int segmentNum){Vector3[] path = new Vector3[segmentNum];for (int i = 1; i <= segmentNum; i++){float t = i / (float)segmentNum;Vector3 pixel = CalculateThreePowerBezierPoint(t, startPoint,controlPoint1, controlPoint2, endPoint);path[i - 1] = pixel;Debug.Log(path[i - 1]);}return path;}
}

Unity 工具类 之 贝塞尔 Bezier 曲线相关推荐

  1. Unity 工具类 之 Blender 的下载和简单使用(为捏脸做准备)

    Unity 工具类 之 Blender 的下载和使用(为捏脸做准备) 目录 Unity 工具类 之 Blender 的下载和使用 一.简单介绍 二.下载地址 三.安装 四.简单使用 1.设置成中文界面 ...

  2. Unity 工具类 之 Excel 转换为 json、csv、xml、lua格式

    Unity 工具类 之 Excel 转换为 json.csv.xml.csv 格式 目录 Unity 工具类 之 Excel 转换为 json.csv.xml.csv 格式 一.介绍 二.操作原理 三 ...

  3. Unity 工具类 之 编辑扩展器 之 简单的音效管理编辑扩展器面板实现

    Unity 工具类 之 编辑扩展器 之 简单的音效管理编辑扩展器面板实现 目录 Unity 工具类 之 编辑扩展器 之 简单的音效管理编辑扩展器面板实现 一.简单介绍 二.实现原理 三.注意事项 四. ...

  4. Unity 工具类 之 WWW/UnityWebRequest 下载压缩文件(zip),解压到本地且加载使用解压数据的简单案例(内也含压缩文件例子)

    Unity 工具类 之 WWW/UnityWebRequest 网络下载压缩文件(zip),解压到本地,且加载使用解压数据的简单案例(内也含压缩文件例子) 目录 Unity 工具类 之 WWW/Uni ...

  5. Unity 工具类 之 简单快速 获取当前所在位置,所在城市,经纬度等

    Unity  工具类 之 简单快速 获取当前所在位置,所在城市,经纬度等 目录 Unity  工具类 之 简单快速 获取当前所在位置,所在城市,经纬度等 一.方法提要: 二.使用注意: 三.json ...

  6. 贝塞尔Bezier曲线的使用

    1 简介   贝塞尔曲线就是这样的一条曲线,它是依据N个位置任意的点坐标绘制出的一条光滑曲线.那么,我们可以直观地认为,为了得到一条贝塞尔曲线,我们只要输入起点.终点及控制点既可.变化参数t都是位于[ ...

  7. Unity工具类扩展——UGUI代码/脚本自动化生成 (一)

    [为什么要做自动化工具] 工具类的创建是为了解决实际问题或者优化既有流程,我们来先看看一些项目里面经常遇到的问题. 下面这个工具就是可以直接创建一个功能的基础脚本类,就不用每次去复制上次的代码了.然后 ...

  8. unity工具类篇 unity 计时器

    一.计时器的主要功能 在规定时间内倒计时 显示倒计时时间 显示正计时时间 暂停.继续 时间速率影响 获取倒计时剩余时间 倒计时结束的回调 二.计时器实现 using UnityEngine;publi ...

  9. Unity 工具类 之 UnityWebRequest 常用功能封装

    using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using U ...

最新文章

  1. Windows 脚本系列之四—映射网络盘脚本
  2. python爬虫获取的网页数据为什么要加[0-使用 Python 爬取网页数据
  3. kmeans中的k的含义_聚类分析:kmeans 算法簇个数的确定
  4. vue 封装dialog_自己封装dialog组件
  5. @RequiredArgsConstructor用法
  6. 在SAP C4C TI(Thing Inspector)页面里添加自定义UI
  7. python实现多语言语种识别_用Python进行语言检测
  8. JavaScript 设计模式核⼼原理与应⽤实践 之 开篇:前端工程师的成长论
  9. dockerfile、docker compose、k8s区别
  10. 设置和开通freebsd远程登录
  11. 远程办公的破冰行动!
  12. 在unity商店中寻找资源_Unity资产商店:五月疯狂促销活动正在进行中!
  13. mysql中ddl和ddm_DDL与DML问题
  14. 电压源 电流源 置零时的作用
  15. 【技法操作】UI界面设计,用PS绘制闹钟页面教程
  16. 易企秀 伪静态 linux,最新仿易企秀V15.1完整版开源版源码分享,修复采集功能,新增同行站模板采集功能等等...
  17. 建模人必备的C4D素材网站,解决你的创作问题
  18. 最新Java资源整理,大多数人的选择
  19. [ESP32][esp-idf] AP+STA实现无线桥接 中转wifi信号 路由器
  20. 安装sql错误:系统找不到指定路径

热门文章

  1. 计算机专业考研双非大学排名,【大学分析】去年计算机爆炸的双非浙江工业大学,今年分数大幅下降!...
  2. CPE跟无线路由器的区别,头大
  3. 360手机卫士会影响Widget的运行
  4. CNS级公众号推文汇总
  5. windows自带的字体和简介
  6. 黑马程序员之 --- 集合
  7. UART项目验证(二) spec阅读
  8. 魔兽世界9.0格拉萨恩的宝箱怎么得 格拉萨恩的宝箱获取方法
  9. STC51单片机11——EEPROM测试
  10. SpringMVC(一)