国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

Vector3.Slerp 球形插值詳解

2019-11-09 15:16:38
字體:
供稿:網(wǎng)友
首先上官方的文檔信息,方面還沒有看過的同學學習。        static function Vector3Slerp (Vector3 from, Vector3to, float t)         Description描述(翻譯信息來自 U_鷹)        Spherically interpolates between two vectors.        球形插值在兩個向量之間。我感覺叫“弧線插值”更直觀一些。        Interpolates from towards to by amount t. The returned vector'smagnitude will be interpolated between magnitudesof from and to.         通過t數(shù)值在from和to之間插值。返回的向量的長度將被插值到from到to的長度之間。    另外官方API上面還給了一個例子如下[C#] 純文本查看 復制代碼?
 010203040506070809101112131415161718192021[/font][/size][/align][align=left][size=4][font=宋體]//在日出和日落之間動畫弧線using UnityEngine;using System.Collections; public class example : MonoBehaviour {        publicTransform sunrise;        publicTransform sunset;        voidUpdate()         {                //弧線的中心                Vector3 center = sunrise.position + sunset.position *                 0.5f;                //向下移動中心,垂直于弧線                center -=new Vector3(0, 1, 0);                //相對于中心在弧線上插值                Vector3 riseRelCenter = sunrise.position - center;                Vector3 setRelCenter = sunset.position - center;                transform.position = Vector3.Slerp(riseRelCenter,                                      setRelCenter, Time.time);                transform.position += center;        }}
下面進入對這個函數(shù)的詳細解釋。    初識這個函數(shù)的同學們對這個函數(shù)都不是很理解,既然是球形插值了,那么為什么用這個函數(shù)的時候卻這么復雜呢,又要找中心點,又要中心點偏移的弄了半天。其實這是從這個函數(shù)的實現(xiàn)方法所決定的。咱們還是上例子來看比較清楚。首先定義兩個向量 a(2,1,0); b(-2,1,0);然后咱們以這兩個坐標點和原點來構(gòu)建一個三角形,如下圖所示:咱們以a和b兩個向量來做插值,假設分10等份,代碼比較簡單,如下代碼[C#] 純文本查看 復制代碼?
 1234[/font][/align][align=left][font=宋體]       for (inti = 1; i < 10; ++i)        {            Vector3 drawVec = Vector3.Slerp(a, b, 0.1f * i);            Debug.DrawLine(Vector3.zero, drawVec, Color.yellow);        }
可以看到咱們并沒有像官方給的例子那樣,做那么多的操作,效果也是杠杠滴!但是,你不能被表象所欺騙,這樣的效果雖然可以,但是卻無法控制插值的曲線,也就是那個弧度,雖然你可以調(diào)整向量a和向量b的值來調(diào)節(jié)弧度,比方說a(1,1,0),b(-1,1,0)效果如下,可以看到弧度已經(jīng)明顯變平很多。但是我們在實際運用這個函數(shù)的時候往往向量a和向量b是固定的,我們想要的是控制這個弧度,那么怎么辦呢,其實也就是改變畫這個弧度的中心點位置。上面兩個示意圖上面中心點我們都是用的坐標原點,我們現(xiàn)在想要在不改變a和a的情況下來改變插值的弧度,就只能自己找出一個中心點,這也就是官方實例中求中心點的由來了。[C#] 純文本查看 復制代碼?
 0102030405060708091011[/font][/align][align=left][font=宋體]       //弧線的中心        Vector3 center = (a + b) * 0.5f;        //我們把中心點向下移動中心,垂直于弧線        center -=new Vector3(0, 0.5f, 0);        // 求出新的中心點到向量a和向量b的        Vector3 vecA = a - center;        Vector3 vecB = b - center;        for(int i = 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的話不論你怎么插值,其實都是從坐標原點進行的插值,你是控制不了插值的弧度的。)從上面的效果圖我們可以看到插值出來的弧度開始和結(jié)束點并不是a、b兩點,而是這兩個點向下的偏移量,而這個偏移量正好是向量conter的負值,所以我們在求出drawVec之后需要對其做修正處理。在求出drawVec之后加上下面的代碼[C#] 純文本查看 復制代碼?
 drawVec += center;
然后再看效果圖現(xiàn)在的效果圖就是我們想要的插值效果了,要想控制弧度,只用調(diào)節(jié)centor的偏移量就可以了。比方說我們加上這樣一條center -= newVector3(0, 2f, 0);可以看到效果如下這個弧度是不是就更平了呢。好,看到現(xiàn)在還沒有睡著的同學們,我只能說一句你們有福了,下面可是大餐哦。上面咱們介紹的都是有局限性的,比方說向量a和向量b對于Y軸可是左右對稱的,并且X,Y軸的值也是相等的,這在實際運用中可是非常不常見的,現(xiàn)在咱們對向量a做一個比較小的改動看看,把向量a改為(2,1,0),那么效果如下所示哇咔咔,居然還是好好的球形插值啊,哈哈,各位同學別激動,咱們把向量a的Y軸也調(diào)整一下看看,把a改為(2,4,0)效果如下圖所示哇咔咔。。效果是不是非常明顯啊,說好的球形插值呢?怎么成了這個樣子!!哈哈,各位同學別著急啊,咱們這個球形插值和核心其實就是center點的位置,只要我們求的這個center點的位置在a和b連線中心點的垂線上面,那么就是一個完整的左右對稱的插值了。下面咱們加入如下代碼[C#] 純文本查看 復制代碼?
 1Vector3 centorPRoject = Vector3.Project(centor, mStart - mEnd);// 中心點在兩點之間的投影     centor = Vector3.MoveTowards(centor, centorProject, 1f);// 沿著投影方向移動移動距離(距離越大弧度越小)
效果如下所示(中心的垂線和起始兩條線用藍色標示出來了)所以我們完整的運用Vector3.Slerp的代碼應該是這樣子滴[C#] 純文本查看 復制代碼?
 0102030405060708091011121314151617181920[/font][/align][align=left][font=宋體]//在日出和日落之間動畫弧線using UnityEngine;using System.Collections; public class 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;        }}
看到這里各位同學是不是覺得已經(jīng)掌握了Vector3.Slerp了呢?O(∩_∩)O哈哈~NONONO!!!!咱們上面的實例還是有局限性滴,誰告訴你了Vector3的Z軸必須是0了?,咱們對a和b的Z軸在做修改。a((2, 4, -1)),b((-1, 1, 2)),看下效果圖哇咔咔。。是不是又出問題了?還需要改代碼?NO!這是因為我們鎖定了視角方向來看的,看上面的2D選項是不是已經(jīng)選擇了啊,哈哈。那么既然Z軸有值了我們就不能已平面視角來看了,等我們把2D鎖定給關閉了轉(zhuǎn)換個視角看看。這樣看是不是就順眼多了呢?哈哈,至此我們的講解總算結(jié)束了,大家可以洗洗了,哈哈。。。等下!誰說可以睡了?我可沒說哦,難道大家對我說的都這么信嗎?有句古話說的好啊,盡信書則不如無書。。[C#] 純文本查看 復制代碼?
 centor = Vector3.MoveTowards(centor, centorProject, 1f);// 沿著投影方向移動移動距離(距離越大弧度越小)
在這句代碼中我寫了個注釋(距離越大弧度越小)那么誰能告訴我距離越小會怎么樣呢?大家是不是覺得距離越小弧度就越大呢?嘿嘿。。這就掉坑里了吧。   這個距離的小是相對的,盡量是不能小于0.01的,至于為啥是0.01呢,我就試了下0.01和0.001。。。哈哈。。就是這么不負責。。   如果這個距離小于0.01的話插值的方向就是不可控了,至于為什么呢?因為過于小的話就是a到b兩點之間的一條線了,垂直于一條線的平面可是海里去了,誰知道在哪里呢。所以大家在用的時候切記這點啊,不能過于追求極限導致結(jié)果不可控。還有。。我是不是比較啰嗦啊。。上面我說的是距離啊,是距離,不是值,這個值是可以為負值的啊,負值的話插值的弧線就在這邊了,轉(zhuǎn)個向而已。好了,講解總算是可以結(jié)束了。累死我了。。哇咔咔。。下面是測試源碼,有興趣的同學玩玩吧[C#] 純文本查看 復制代碼?
 0102030405060708091011121314151617181920212223242526272829[/size][/font][/align][align=left][font=宋體][size=14.0pt]   private Vector3 mStart =new Vector3(2, 4, -1);    privateVector3 mEnd = newVector3(-1, 1, 2);    // Update is called once per frame    privatevoid 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(int i = 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);         }    }

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 绍兴县| 灵寿县| 漳州市| 昭通市| 翁牛特旗| 新龙县| 马公市| 壶关县| 昭平县| 甘德县| 洱源县| 稻城县| 商河县| 沙坪坝区| 信宜市| 新余市| 汝城县| 鄂托克前旗| 社会| 兰考县| 嘉义县| 武鸣县| 栾城县| 封丘县| 柳江县| 思茅市| 伊通| 准格尔旗| 宣武区| 平遥县| 滦南县| 资兴市| 东丽区| 罗平县| 柘荣县| 巴青县| 张家川| 郓城县| 宁南县| 贵溪市| 岱山县|