Unity Vector3.Slerp() 球形插值详解之二
来源:互联网 发布:java实现猜数字游戏 编辑:程序博客网 时间:2024/05/16 08:14
using UnityEngine;using System.Collections;/// <summary>/// 在日出和日落之间动画弧线/// 网上看到有人对Vector3.Slerp()的详解,但是经过962f之力将他的思路看明白。/// 受到启发,就有了自己对Vector3.Slerp()的理解。tt2()函数、tt3()函数是自己的写的,tt4()是别人的。/// tt2()函数球形插值/// tt3()函数利用球形插值绘制类似抛物线。/// </summary>public class Vector3_Slerp_2 : MonoBehaviour{ /// <summary> /// 日出 /// </summary> public Transform sunrise; /// <summary> /// 日落 /// </summary> public Transform sunset; /// <summary> /// 计算中间点的一个因素 /// </summary> public float m_centerFac = 0.5f; /// <summary> /// 插值中心点的影响因素 /// </summary> public float m_moveTowardsValue = 1f; /// <summary> /// 插值的个数 /// </summary> public int m_lineNum = 30; private Vector3 mStart = Vector3.zero; private Vector3 mEnd = Vector3.zero; void Update() { //tt2(); tt3(); //tt4(); } /// <summary> /// 官方用例 /// </summary> private void tt1() { //弧线的中心 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; } /// <summary> /// 球面插值 /// 自己的理解 /// 只在垂直平面上做球面插值。 /// </summary> private void tt2() { mStart = sunrise.position; mEnd = sunset.position; /// 绘制世界坐标系 Debug.DrawLine(new Vector3(-100, 0, 0), new Vector3(100, 0, 0), Color.green); Debug.DrawLine(new Vector3(0, -100, 0), new Vector3(0, 100, 0), Color.green); Debug.DrawLine(new Vector3(0, 0, -100), new Vector3(0, 0, 100), Color.green); /// 求出起始点与终点的中心点 Vector3 center = (mStart + mEnd) * m_centerFac; //////////////////////////////////// /// 1. center、mStart、mEnd 构成一个平面A //////////////////////////////////// Debug.DrawLine(new Vector3(center.x, 0f, center.z), center, Color.white); /// 绘制一个三角形 Debug.DrawLine(new Vector3(center.x, 0f, center.z), mStart, Color.white); Debug.DrawLine(new Vector3(center.x, 0f, center.z), mEnd, Color.white); Debug.DrawLine(mStart, mEnd, Color.white); Vector3 normal = mEnd - mStart; ///只在垂直平面上做球面插值。 Vector3 tangent = new Vector3(center.x, 0f, center.z) - center; /// 两个坐标轴的正交化。 Vector3.OrthoNormalize(ref normal, ref tangent); float moveTowardsValue = (mEnd - mStart).magnitude * m_moveTowardsValue; Vector3 center2 = center + tangent * moveTowardsValue; //////////////////////////////////// /// 2. 两个坐标轴的正交化后 center2、mStart、mEnd 构成一个平面B, /// 3. 平面B与平面A是同一平面。 //////////////////////////////////// Debug.DrawLine(center2, mStart, Color.blue); Debug.DrawLine(center2, mEnd, Color.blue); Debug.Log(string.Format("{0} : {1}", Vector3.Distance(center2, mStart), Vector3.Distance(center2, mEnd))); for (int i = 1; i < m_lineNum; ++i) { Vector3 drawVec = Vector3.Slerp(mEnd - center2, mStart - center2, 1f / m_lineNum * i); drawVec += center2; Debug.DrawLine(center2, drawVec, Color.yellow); } /// 绘制起始点与终点的中心点到计算出的插值的中心点 Debug.DrawLine(center, center2, Color.black); } /// <summary> /// 利用球面插值模拟抛物线 /// 自己的理解 /// </summary> private void tt3() { mStart = sunrise.position; mEnd = sunset.position; /// 绘制世界坐标系 Debug.DrawLine(new Vector3(-100, 0, 0), new Vector3(100, 0, 0), Color.green); Debug.DrawLine(new Vector3(0, -100, 0), new Vector3(0, 100, 0), Color.green); Debug.DrawLine(new Vector3(0, 0, -100), new Vector3(0, 0, 100), Color.green); /// 求出起始点与终点的中心点 Vector3 center = mEnd + (mStart - mEnd) * m_centerFac; //////////////////////////////////// /// 1. center、mStart、mEnd 构成一个平面A //////////////////////////////////// Debug.DrawLine(new Vector3(center.x, mEnd.y, center.z), center, Color.white); /// 绘制一个三角形 Debug.DrawLine(new Vector3(center.x, mEnd.y, center.z), mStart, Color.white); Debug.DrawLine(new Vector3(center.x, mEnd.y, center.z), mEnd, Color.white); Debug.DrawLine(mStart, mEnd, Color.white); Vector3 normal = mStart - mEnd; ///只在垂直平面上做球面插值。 Vector3 tangent = new Vector3(center.x, mEnd.y, center.z) - center; /// 两个坐标轴的正交化。 Vector3.OrthoNormalize(ref normal, ref tangent); float moveTowardsValue = (mEnd - mStart).magnitude * m_moveTowardsValue; //Vector3 center2 = center + tangent * moveTowardsValue; Vector3 center2 = center - Vector3.up * moveTowardsValue; //////////////////////////////////// /// 2. 两个坐标轴的正交化后 center2、mStart、mEnd 构成一个平面B, /// 3. 平面B与平面A是同一平面。 //////////////////////////////////// Debug.DrawLine(center2, mStart, Color.blue); Debug.DrawLine(center2, mEnd, Color.blue); Debug.Log(string.Format("{0}:{1} -- {2}:{3}", Vector3.Distance(center2, mStart), Vector3.Distance(center2, mEnd), Vector3.Distance(mEnd, mStart), Vector3.Distance(center2, center))); for (int i = 1; i < m_lineNum; ++i) { Vector3 drawVec = Vector3.Slerp(mEnd - center2, mStart - center2, 1f / m_lineNum * i); drawVec += center2; Debug.DrawLine(center2, drawVec, Color.yellow); } /// 绘制起始点与终点的中心点到计算出的插值的中心点 Debug.DrawLine(center, center2, Color.black); } /// <summary> /// 球面插值 /// http://www.manew.com/thread-43314-1-1.html 文章用例 /// </summary> private void tt4() { mStart = sunrise.position; mEnd = sunset.position; Debug.DrawLine(new Vector3(-100, 0, 0), new Vector3(100, 0, 0), Color.green); Debug.DrawLine(new Vector3(0, -100, 0), new Vector3(0, 100, 0), Color.green); Debug.DrawLine(new Vector3(0, 0, -100), new Vector3(0, 0, 100), Color.green); Debug.DrawLine(Vector3.zero, mStart, Color.white); Debug.DrawLine(Vector3.zero, mEnd, Color.white); Debug.DrawLine(mStart, mEnd, Color.white); /// 求出起始点与终点的中心点 Vector3 centor = (mStart + mEnd) * 0.5f; Debug.DrawLine(Vector3.zero, centor, Color.blue); Vector3 centorProject = Vector3.Project(centor, mStart - mEnd); // 中心点在两点之间的投影 centor = Vector3.MoveTowards(centor, centorProject, m_moveTowardsValue); // 沿着投影方向移动移动距离(距离越大弧度越小) 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 < m_lineNum; ++i) { Vector3 drawVec = Vector3.Slerp(mEnd - centor, mStart - centor, 1f / m_lineNum * i); drawVec += centor; Debug.DrawLine(centor, drawVec, Color.yellow); //Debug.DrawLine(centor, drawVec, 5 == i ? Color.blue : Color.yellow); } }}
0 0
- Unity Vector3.Slerp() 球形插值详解之二
- Unity Vector3.Slerp() 球形插值详解
- Unity 之Vector3的球形插值Slerp详解
- Unity之Vector3.Slerp球形插值原理介绍
- Vector3.Slerp 球形插值详解
- Vector3.Slerp 球形插值详解
- Vector3.Slerp 球形插值详解
- Quaternion.Slerp 球形插值
- slerp插值的实现
- Vector3.Slerp的使用
- Unity 插值运算 Vector3.Lerp(transform.position, targetPos, smoothing * Time.deltaTime);
- Unity之Vector3D:重现Vector3
- unity Vector3
- Unity之EditorGUILayout-Vector2、Vector3、Vector4-八
- Unity Manual之Vector3 三维向量
- Unity之Vector3.Lerp线性插值原理介绍
- Unity Quaternion.Slerp部分运用
- [unity基础知识]之Unity3d之Vector3 学习与应用
- OpenGL基础图形编程(四)基础程序结构
- 写给自己的话
- 定高条块:.bar
- 伪代码模拟TranslateMessage内部实现
- LeetCode *** 100. Same Tree
- Unity Vector3.Slerp() 球形插值详解之二
- @synthesize和@dynamic区别
- 测试知多少
- 下拉导航栏消失,上拉导航栏出现的问题
- C++指针的工作方式(1)
- vs将普通工程修改为com组件工程
- C#学习---C#简介
- windows下如何安装yaf框架。
- lintcode: Permutations II