Vector3.Slerp 球形插值详解

首先上官方的文档信息,方面还没有看过的同学学习。

        static function Vector3 Slerp (Vector3 from, Vector3to, float t)
        Spherically interpolates between two vectors.
        球形插值在两个向量之间。
    我感觉叫“弧线插值”更直观一些。
        Interpolates from towards to by amount t. The returned vector's magnitude will be interpolated between magnitudesof from and to.

通过t数值在from和to之间插值。返回的向量的长度将被插值到from到to的长度之间。

    另外官方API上面还给了一个例子如下
//在日出和日落之间动画弧线
usingUnityEngine;
usingSystem.Collections;publicclass example : MonoBehaviour
{publicTransform sunrise;publicTransform sunset;voidUpdate() {//弧线的中心Vector3 center = sunrise.position + sunset.position *                 0.5f;//向下移动中心,垂直于弧线center -= newVector3(0, 1, 0);//相对于中心在弧线上插值Vector3 riseRelCenter = sunrise.position - center;Vector3 setRelCenter = sunset.position - center;transform.position = Vector3.Slerp(riseRelCenter,setRelCenter, Time.time);transform.position += center;}
}

下面进入对这个函数的详细解释。

    初识这个函数的同学们对这个函数都不是很理解,既然是球形插值了,那么为什么用这个函数的时候却这么复杂呢,又要找中心点,又要中心点偏移的弄了半天。其实这是从这个函数的实现方法所决定的。咱们还是上例子来看比较清楚。

首先定义两个向量  a(2,1,0); b(-2,1,0);  然后咱们以这两个坐标点和原点来构建一个三角形,如下图所示:

咱们以a和b两个向量来做插值,假设分10等份,代码比较简单,如下代码
for(inti = 1; i < 10; ++i){Vector3 drawVec = Vector3.Slerp(a, b, 0.1f * i);Debug.DrawLine(Vector3.zero, drawVec, Color.yellow);}
可以看到咱们并没有像官方给的例子那样,做那么多的操作,效果也是杠杠滴!
但是,你不能被表象所欺骗,这样的效果虽然可以,但是却无法控制插值的曲线,也就是那个弧度,虽然你可以调整向量a和向量b的值来调节弧度,比方说a(1,1,0),b(-1,1,0)效果如下,可以看到弧度已经明显变平很多。
但是我们在实际运用这个函数的时候往往向量a和向量b是固定的,我们想要的是控制这个弧度,那么怎么办呢,其实也就是改变画这个弧度的中心点位置。上面两个示意图上面中心点我们都是用的坐标原点,我们现在想要在不改变a和a的情况下来改变插值的弧度,就只能自己找出一个中心点,这也就是官方实例中求中心点的由来了。
//弧线的中心Vector3 center = (a + b) * 0.5f;//我们把中心点向下移动中心,垂直于弧线center -= newVector3(0, 0.5f, 0);// 求出新的中心点到向量a和向量b的Vector3 vecA = a - center;Vector3 vecB = b - center;for(inti = 0; i <= 10; ++i){Vector3 drawVec = Vector3.Slerp(vecA, vecB, 0.1f * i);Debug.DrawLine(center, drawVec, Color.yellow);}
求出中心点后我们再来画一个示意图看看
(至于为什么要 求出新的中心点到向量a和向量b的vecA和vecB是因为,我们在球形插值的时候要的是两个vector3,而这个vector3是要向量a和向量b到中心点的向量,如果我们不求出vecA和vecB的话不论你怎么插值,其实都是从坐标原点进行的插值,你是控制不了插值的弧度的。)
从上面的效果图我们可以看到插值出来的弧度开始和结束点并不是a、b两点,而是这两个点向下的偏移量,而这个偏移量正好是向量conter的负值,所以我们在求出drawVec之后需要对其做修正处理。
在求出drawVec之后加上下面的代码
drawVec += center;
然后再看效果图
现在的效果图就是我们想要的插值效果了,要想控制弧度,只用调节centor的偏移量就可以了。
比方说我们加上这样一条
center -= new Vector3(0, 2f, 0);
可以看到效果如下
这个弧度是不是就更平了呢。
好,看到现在还没有睡着的同学们,我只能说一句你们有福了,下面可是大餐哦。
上面咱们介绍的都是有局限性的,比方说向量a和向量b对于Y轴可是左右对称的,并且X,Y轴的值也是相等的,这在实际运用中可是非常不常见的,现在咱们对向量a做一个比较小的改动看看,把向量a改为(2,1,0),那么效果如下所示
哇咔咔,居然还是好好的球形插值啊,哈哈,各位同学别激动,咱们把向量a的Y轴也调整一下看看,把a改为(2,4,0)效果如下图所示
哇咔咔。。效果是不是非常明显啊,说好的球形插值呢?怎么成了这个样子!!哈哈,各位同学别着急啊,咱们这个球形插值和核心其实就是center点的位置,只要我们求的这个center点的位置在a和b连线中心点的垂线上面,那么就是一个完整的左右对称的插值了。
下面咱们加入如下代码
Vector3 centorProject = Vector3.Project(centor, mStart - mEnd); // 中心点在两点之间的投影centor = Vector3.MoveTowards(centor, centorProject, 1f); // 沿着投影方向移动移动距离(距离越大弧度越小)
效果如下所示(中心的垂线和起始两条线用蓝色标示出来了)
所以我们完整的运用Vector3.Slerp的代码应该是这样子滴
//在日出和日落之间动画弧线
usingUnityEngine;
usingSystem.Collections;publicclass example : MonoBehaviour
{publicTransform sunrise;publicTransform sunset;voidUpdate() {//弧线的中心Vector3 center = sunrise.position + sunset.position * 0.5f;Vector3 centorProject = Vector3.Project(centor, sunrise.position - sunset.position); // 中心点在两点之间的投影centor = Vector3.MoveTowards(centor, centorProject, 1f); // 沿着投影方向移动移动距离(距离越大弧度越小)                //相对于中心在弧线上插值Vector3 riseRelCenter = sunrise.position - center;Vector3 setRelCenter = sunset.position - center;transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, Time.time);transform.position += center;}
}
看到这里各位同学是不是觉得已经掌握了Vector3.Slerp了呢?O(∩_∩)O哈哈~
NONONO!!!!
咱们上面的实例还是有局限性滴,谁告诉你了Vector3的Z轴必须是0了?,咱们对a和b的Z轴在做修改。a((2, 4, -1)),b((-1, 1, 2)),看下效果图
哇咔咔。。是不是又出问题了?还需要改代码?NO!这是因为我们锁定了视角方向来看的,看上面的2D 选项是不是已经选择了啊,哈哈。那么既然Z轴有值了我们就不能已平面视角来看了,等我们把2D锁定给关闭了转换个视角看看。
这样看是不是就顺眼多了呢?哈哈,至此我们的讲解总算结束了,大家可以洗洗了,哈哈。。。
等下!谁说可以睡了?我可没说哦,难道大家对我说的都这么信吗?有句古话说的好啊,尽信书则不如无书。。
// 沿着投影方向移动移动距离(距离越大弧度越小)
centor = Vector3.MoveTowards(centor, centorProject, 1f);
在这句代码中我写了个注释(距离越大弧度越小)那么谁能告诉我距离越小会怎么样呢?大家是不是觉得距离越小弧度就越大呢?嘿嘿。。这就掉坑里了吧。
    这个距离的小是相对的,尽量是不能小于0.01的,至于为啥是0.01呢,我就试了下0.01和0.001。。。哈哈。。就是这么不负责。。
    如果这个距离小于0.01的话插值的方向就是不可控了,至于为什么呢?因为过于小的话就是a到b两点之间的一条线了,垂直于一条线的平面可是海里去了,谁知道在哪里呢。所以大家在用的时候切记这点啊,不能过于追求极限导致结果不可控。还有。。我是不是比较啰嗦啊。。上面我说的是距离啊,是距离,不是值,这个值是可以为负值的啊,负值的话插值的弧线就在这边了,转个向而已。
好了,讲解总算是可以结束了。累死我了。。哇咔咔。。
下面是测试源码,有兴趣的同学玩玩吧
privateVector3 mStart = newVector3(2, 4, -1);privateVector3 mEnd = newVector3(-1, 1, 2);// Update is called once per frameprivatevoid Update(){Debug.DrawLine(newVector3(-100, 0, 0), newVector3(100, 0, 0), Color.green);Debug.DrawLine(newVector3(0, -100, 0), newVector3(0, 100, 0), Color.green);Debug.DrawLine(Vector3.zero, mStart, Color.red);Debug.DrawLine(Vector3.zero, mEnd, Color.red);Debug.DrawLine(mStart, mEnd, Color.red);Vector3 centor = (mStart + mEnd) * 0.5f;Vector3 centorProject = Vector3.Project(centor, mStart - mEnd); // 中心点在两点之间的投影centor = Vector3.MoveTowards(centor, centorProject, 1f);        // 沿着投影方向移动移动距离(距离越大弧度越小)Debug.DrawLine(centor, mStart, Color.blue);Debug.DrawLine(centor, mEnd, Color.blue);Debug.Log(string.Format("{0} : {1}", Vector3.Distance(centor, mStart), Vector3.Distance(centor, mEnd)));for(inti = 1; i < 10; ++i){Vector3 drawVec = Vector3.Slerp(mEnd - centor, mStart - centor, 0.1f * i);drawVec += centor;Debug.DrawLine(centor, drawVec, 5 == i ? Color.blue : Color.yellow);}}
转载:http://www.manew.com/thread-43314-1-1.html

Unity 之Vector3的球形插值Slerp详解相关推荐

  1. pandas dataframe缺失值(np.nan)处理:识别缺失情况、删除、0值填补、均值填补、中位数填补、加缺失标签、插值填充详解及实例

    pandas dataframe缺失值(np.nan)处理:识别缺失情况.删除.0值填补.均值填补.中位数填补.加缺失标签.插值填充详解及实例 isnull().natna().isna().fill ...

  2. 数学建模——一维、二维插值模型详解Python代码

    数学建模--一维.二维插值模型详解Python代码 一.一维插值 # -*-coding:utf-8 -*- import numpy as np from scipy import interpol ...

  3. Unity 之 打包参数 -- Player面板属性详解

    Unity 之 Project Setting -- Player 面板属性详解 前言 一,Player 1.1 属性说明 1.2 效果展示 二,ICON(图标) 2.1 属性说明 2.2 使用示例 ...

  4. Unity Shader中各部分定义内容详解

    Unity Shader中各部分定义内容详解 样板 Shader "Practice/Unlit/SimpleUnlit" {Properties{_MainTex (" ...

  5. Unity快速入门之二 GUI Transform 详解

    Unity快速入门之一 3D基础概念.Camera.Canvas RenderMode的几种方式对比_翕翕堂 Unity快速入门之二 GUI Transform 详解_翕翕堂 Unity快速入门之三 ...

  6. Unity 之 UGUI RectTransform矩形变换组件详解

    Unity 之 UGUI RectTransform矩形变换组件详解 1,属性面板 2,详细信息 3,代码操作 4,使用实例 4.1 传说中的自适应 4.2 锚点的另一种使用方式: 4.3 蓝图和原始 ...

  7. 【20220207】【信号处理】三次样条插值原理详解

    方程组的求解本文不做介绍. 一.三次样条插值 1. 定义 三次样条插值(Cublic Spline Interpolation),简称 Spline 插值,是通过一系列样本点的光滑曲线,数学上通过求解 ...

  8. Unity文件、文件引用、Meta详解

    原文链接:https://blog.uwa4d.com/archives/USparkle_inf_UnityEngine.html 这是侑虎科技第381篇原创文章,感谢作者陈广忠供稿.欢迎转发分享, ...

  9. [新手必备]Unity推箱子小游戏C#代码详解(第一篇-代码部分)

    完整项目请参考博客:https://blog.csdn.net/qq_41676090/article/details/96300302 本文为推箱子小游戏C#代码详解第一篇的代码部分,主要讲解 Sy ...

最新文章

  1. 手动配置lnmp环境
  2. Python深度学习:基于PyTorch [Deep Learning with Python and PyTorch]
  3. 获取多张表中的数据_趣说:什么是数据结构和算法
  4. android dimensions.xml,android – Value等于match_parent或fill_parent在dimensions.xml?
  5. java模块_Java 9 揭秘(2. 模块化系统)
  6. fcc无线充电认证_FCC规定了无线路由器固件,轮椅和胰岛素的开放状态以及更多新闻
  7. kafka java_Java操作Kafka
  8. geetest文件夹什么意思_手机文件夹是英文不敢删?只要找出这5个文件夹,能腾出大量内存...
  9. bzoj1113[Poi2008]海报PLA
  10. [导入]Nebula3学习笔记(5): IO系统
  11. 478.在圆内随机生成点
  12. 下载小红书无水印照片
  13. 档案管理制度计算机管理制度,计算机管理档案制度
  14. 优秀IT顾问的七大能力之一--专业技术能力
  15. 车牌识别一体机 尊贵
  16. VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-S CALE IMAGE RECOGNITION-论文笔记
  17. 大型电商平台设计实例:电商平台总体设计和业务模型设计
  18. 【获奖案例巡展】信创先锋之星——云上贵州信创工程中心大数据中台
  19. ChatGPT与文心一言对比思考
  20. Android调用聚 合 API

热门文章

  1. 面试官:对于 JavaScript 的加载问题你怎杨理解?
  2. 乐观锁和悲观锁的理解及如何实现,乐观锁的实现方式。看完你就明白了!
  3. 新兴元宇宙META PANDA——IDO抢购倒计时
  4. 蓝桥杯STM32F103RB通用定时器(一)定时功能
  5. “西游记之大圣归来”关键词提取-textrank
  6. 生信分析,通过ensemblID检索对应protein序列
  7. Centos7.4升级内核为5.1 亲测可用
  8. 华为的鸿蒙系统都有哪些手机,曝鸿蒙系统首批升级名单,华为中高端系列都有,荣耀还要等等?...
  9. 使用腾讯云存储桶(COS)托管静态网站
  10. 【EI/Scopus双检索】国内多所高校协办,计算机多主题征稿,AHPCAI 2021诚邀您投稿参会!...