找回密码
 注册帐号

扫一扫,访问微社区

抢楼 抢楼 本帖为抢楼帖,欢迎抢楼! 

基础知识 Vector3.Slerp API示例解析

14
回复
4262
查看
[ 复制链接 ]
7日久生情
4215/5000
排名
53
昨日变化

5

主题

111

帖子

4215

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
10189
好友
0
蛮牛币
9140
威望
0
注册时间
2013-12-12
在线时间
1245 小时
最后登录
2020-9-26
2015-4-15 12:30:37 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
最近在整理Unity中一些可以用来移动物体的方法,在平滑移动中使用到了Vector3.Slerp()函数,对其实现方式深感疑惑,尤其是官方给的例子,先上代码
[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Transform sunrise;
    public Transform sunset;
    public float journeyTime = 1.0F;
    private float startTime;
    void Start() {
        startTime = Time.time;
    }
    void Update() {
        Vector3 center = (sunrise.position + sunset.position) * 0.5F;
        center -= new Vector3(0, 1, 0);
        Vector3 riseRelCenter = sunrise.position - center;
        Vector3 setRelCenter = sunset.position - center;
        float fracComplete = (Time.time - startTime) / journeyTime;
        transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);
        transform.position += center;
    }
}




疑惑主要是在Update()里面的方法如何实现弧线运动,原来只是天真的以为只要使用了Slerp函数,Unity就会自动进行弧线插值。其实不然,如果只是用transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete)控制运动的话,那么物体在两个点之间只是在做普通的直线运动。
那么,接下来就分享一下,通过画图展示我对此算法的理解。
Serp.jpg


我们通过构造一个圆来分析
Center为sunrise.position和sunset.position的中心点
center -= new Vector3(0, 1, 0);将center点下移动到圆心O点
Vector3 riseRelCenter = sunrise.position - center;
Vector3 setRelCenter = sunset.position - center;
将起始点和结束点同样分别向下移动到E、F
transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);
从向量OE旋转到向量OF,进行球形插值,我的理解是插值轨迹为弧OEF(需要说明的是O并不是弧OEF的所在圆圆心。弧OEF为弧OAB向下平移所得)
transform.position += center; 将弧OEF按vector3(0,1,0)向上平移后,运动轨迹就是图示中最上面的圆弧,为物体运动的最终轨迹。


这里我们考虑一下,当修改vector(0,1,0)中y的大小时,会改变运动轨迹的圆心位置。我们可以通过辅助圆分析得到以下结论:当y的值越大时,弧度越小;相反减小y的值,弧度增加。


参与人数 1鲜花 +2 收起 理由
小可小飞 + 2 很给力!

查看全部评分总评分 : 鲜花 +2

回复

使用道具 举报

7日久生情
3884/5000
排名
1208
昨日变化

76

主题

793

帖子

3884

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
45146
好友
6
蛮牛币
761
威望
0
注册时间
2014-9-16
在线时间
2065 小时
最后登录
2020-9-27
QQ
2015-4-15 12:55:57 显示全部楼层
不错,学习了!!!{:86:}
回复

使用道具 举报

7日久生情
3440/5000
排名
242
昨日变化

1

主题

121

帖子

3440

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
46282
好友
2
蛮牛币
5534
威望
0
注册时间
2014-9-23
在线时间
1294 小时
最后登录
2020-7-28
QQ
2015-4-29 17:16:34 显示全部楼层
高手!
————————————————————————
回复

使用道具 举报

7日久生情
2546/5000
排名
275
昨日变化

3

主题

110

帖子

2546

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
48
好友
1
蛮牛币
7033
威望
20
注册时间
2013-5-29
在线时间
481 小时
最后登录
2017-12-27
2015-6-4 11:09:20 显示全部楼层
不错啊 赞一个
回复

使用道具 举报

6蛮牛粉丝
1405/1500
排名
2167
昨日变化

14

主题

292

帖子

1405

积分

Rank: 6Rank: 6Rank: 6

UID
21079
好友
1
蛮牛币
632
威望
0
注册时间
2014-4-12
在线时间
457 小时
最后登录
2020-9-23
2015-8-14 11:06:21 显示全部楼层
后面的解析的不够相信,看着蒙蒙的感觉。
回复

使用道具 举报

排名
39866
昨日变化

0

主题

6

帖子

24

积分

Rank: 1

UID
19852
好友
0
蛮牛币
27
威望
0
注册时间
2014-4-1
在线时间
12 小时
最后登录
2020-4-24
2016-1-12 15:08:13 显示全部楼层
完蛋,你这是完全不理解向量加减法的意义啊!
回复

使用道具 举报

7日久生情
4215/5000
排名
53
昨日变化

5

主题

111

帖子

4215

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
10189
好友
0
蛮牛币
9140
威望
0
注册时间
2013-12-12
在线时间
1245 小时
最后登录
2020-9-26
楼主 2016-1-12 18:19:06 显示全部楼层
po826017 发表于 2016-1-12 15:08
完蛋,你这是完全不理解向量加减法的意义啊!

哦  如果是这样的话      求指教                                                
回复

使用道具 举报

排名
48144
昨日变化

0

主题

3

帖子

14

积分

Rank: 1

UID
55133
好友
0
蛮牛币
16
威望
0
注册时间
2014-11-13
在线时间
5 小时
最后登录
2016-2-19
QQ
2016-2-18 18:02:40 显示全部楼层
love_lieren 发表于 2016-1-12 18:19
哦  如果是这样的话      求指教

如果构造的那个圆的半径小于两点之间距离的一半怎么找到EF?
回复

使用道具 举报

排名
48144
昨日变化

0

主题

3

帖子

14

积分

Rank: 1

UID
55133
好友
0
蛮牛币
16
威望
0
注册时间
2014-11-13
在线时间
5 小时
最后登录
2016-2-19
QQ
2016-2-18 18:03:37 显示全部楼层
love_lieren 发表于 2016-1-12 18:19
哦  如果是这样的话      求指教

我完全你不懂,但你还是一知半解。
回复

使用道具 举报

7日久生情
4215/5000
排名
53
昨日变化

5

主题

111

帖子

4215

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
10189
好友
0
蛮牛币
9140
威望
0
注册时间
2013-12-12
在线时间
1245 小时
最后登录
2020-9-26
楼主 2016-2-19 09:35:24 显示全部楼层
tankmi 发表于 2016-2-18 18:02
如果构造的那个圆的半径小于两点之间距离的一半怎么找到EF?

这只是一个官方的用法示例。sunrise.position 和 sunset.position两个点的坐标位置肯定是知道的,如何构造这个圆弧是你的主观行为,你只要将center点位置下移距离大于sunrise.position 和 sunset.position两个点之间的距离就可以正常构造出这个圆。还有一种情况会产生你说的问题就是当球形插值轨迹是一个大于180度的优弧,但我认为Slerp内部算法不会产生一种这样的运动轨迹。
回复

使用道具 举报

排名
39866
昨日变化

0

主题

6

帖子

24

积分

Rank: 1

UID
19852
好友
0
蛮牛币
27
威望
0
注册时间
2014-4-1
在线时间
12 小时
最后登录
2020-4-24
2016-4-26 16:50:15 显示全部楼层
本帖最后由 po826017 于 2016-4-26 17:01 编辑
love_lieren 发表于 2016-1-12 18:19
哦  如果是这样的话      求指教

首先道个歉,一直没上,所以没看到。
首先你要明白向量加减法的意义,如下:
http://baike.baidu.com/pic/%E5%90%91%E9%87%8F%E5%8A%A0%E5%87%8F/9575773/0/b3b7d0a20cf431ad4cdf9f4a4936acaf2edd98b0?fr=lemma&ct=single#aid=0&pic=b3b7d0a20cf431ad4cdf9f4a4936acaf2edd98b0
然后,这块:
Vector3 riseRelCenter = sunrise.position - center;
Vector3 setRelCenter = sunset.position - center;
你可以认为sunrise.position,sunset.position,center都是起始点为(0,0,0)的向量,那么riseRelCenter和setRelCenter  其实是起始点为O,终点为sunrise.position,sunset.position的两个向量。所以Slerp运行的轨迹并不是OE到OF的半圆,而是很小的一段O-sunrise.position到O-sunset.position的小圆弧。

再有就是,Slerp的计算是这样的:先记riseRelCenter 的长度为lengthR,setRelCenter 的长度为lengthS。
从点riseRelCenter 线性过渡到点setRelCenter 计算得到一个点为direction,把长度lengthR线性过渡到lengthS计算得到一个长度为length,然后Slerp的结果是:方向为direction,长度为length的一个向量(当然你也可以认为这是一个位置)。

题外:上传图片原来这么麻烦的,将就着看吧,图片貌似还出不来。
回复

使用道具 举报

7日久生情
4215/5000
排名
53
昨日变化

5

主题

111

帖子

4215

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
10189
好友
0
蛮牛币
9140
威望
0
注册时间
2013-12-12
在线时间
1245 小时
最后登录
2020-9-26
楼主 2016-4-27 10:24:05 显示全部楼层
po826017 发表于 2016-4-26 16:50
首先道个歉,一直没上,所以没看到。
首先你要明白向量加减法的意义,如下:
http://baike.baidu.com/pic/ ...

感谢回复
看了下基本理解了你的想法。按你的理解我觉得sunrise.position  sunset.position  center这三个值还是觉得应该理解成点而非向量,因为实际中很少使用原点去构造向量,一般都是空间中的两个点相减去表示一个向量。而[size=0.9375em]riseRelCenter, setRelCente则表示的向量。你说的通过lengthR到lengthS之间的线性计算方式,我觉得slerp函数返回的还是一个三维空间中的点,因为要把这个值赋值给线性运动的物体。里面具体算法我去google下。
有时候可能对点和向量的应用有一些模糊,问题出在sunrise.position - center; 对此的理解出现了偏差,由此把问题想的过于复杂了些。但我最开始说的OEF并不是指的是半圆而是OAB向下平移而得。


回复

使用道具 举报

排名
39866
昨日变化

0

主题

6

帖子

24

积分

Rank: 1

UID
19852
好友
0
蛮牛币
27
威望
0
注册时间
2014-4-1
在线时间
12 小时
最后登录
2020-4-24
2016-4-27 15:41:31 显示全部楼层
love_lieren 发表于 2016-4-27 10:24
感谢回复
看了下基本理解了你的想法。按你的理解我觉得sunrise.position  sunset.position  center这三个 ...

各人有各人的理解方式吧,只要能正确理解就好,只是对我来说,用向量理解容易让自己明白而已。还有就是提醒下,最后还是要加上center的,就是transform.position += center;这步也得理解好,不能忽视了。
回复

使用道具 举报

0

主题

2

帖子

2

积分

Rank: 1

UID
148575
好友
0
蛮牛币
16
威望
0
注册时间
2016-5-14
在线时间
0 小时
最后登录
2016-5-14
2016-5-14 15:33:43 显示全部楼层
嗯哼,百度至此,啊哈最近百度也不好过啊,自作孽...,欣赏了一下楼主的文笔,同时向您学习,回过头来我看到了11楼,(请原谅我如此称谓你)的思路,在此感谢各位的倾囊相授,但是一知半解,然后我去外面逛了一下找到了相关的公式,花了点时间对照维基百科的图,公式,以及参照楼主提供的图以及11楼的思路,我理解了,那么,请允许我简单的说明一下,代码中的减Center中心点就为了转换一下Sunrise 和Sunset的坐标系至楼主图的O坐标系,如此做的原因就是为了能套用维基百科所述的公式.如此我们就能明白11楼所述的思路是正确的,但是他的说法让我这种新手理解起来是有难度的,在此提供我的一点浅薄学识,希望能有大神提供更加通俗易懂的文章来供后来学习者理解和学习!
回复

使用道具 举报

0

主题

2

帖子

2

积分

Rank: 1

UID
148575
好友
0
蛮牛币
16
威望
0
注册时间
2016-5-14
在线时间
0 小时
最后登录
2016-5-14
2016-5-14 15:34:17 显示全部楼层
https://en.wikipedia.org/wiki/Slerp
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

蛮牛教育10.1大促销!全站6折扣!