球性插值

摘要:
///Tt2()函数球面插值//tt3()函数使用球面插值绘制类似的抛物线////publicclassVector3_Slerp_2:MonoBehavior{//////日出//publicTransformsunrise;//////日落//publicTransformsunrise;//////计算中间点的系数///publicflatm_centerFace=0.5f;/////内插中心点的影响因素///˂/publicflatm_moveTowardsValue=1f;////内插点数//publicitm_lineNum=30; privateVector3mStart=Vector3.zero;privateVe ctor3mEnd=矢量3.zero;无效更新(){//tt2();tt3();//tt4();}/////官方用例////privateevoidt1(){//弧的中心Vector3center=*0.5f;//向下移动中心,垂直于弧中心-=newVector3;//插值Vector3riseRelCenter=sun rise.position center;Vector3setRelCenter=sunset.position center;transform.position=Vector3。回转;变换form.position+=中心;}//////球面插值//我的理解///在垂直平面上只执行球面插值////privatevoidttt2(){mStart=sunrise.position;mEnd=sunrison.position;//绘制世界坐标系Debug.DrawLine;Debug.DrawLine;//查找起点和终点的中心点Vector3center=*m_centerFace;///////////////////////://///////\//////1。center、mStart、mEnd形成平面a////////////e调试g.绘图线;调试。绘图线;调试。绘图线;矢量3正常=mE nd mStart;///在垂直平面中仅进行球面插值。矢量3切线=新矢量3中心;///两个坐标轴的正交化。

1,球性插值

代码转载自:http://blog.csdn.net/ZFSR05255134/article/details/51075668

根据文章介绍本人对球面插值理解如图球性插值第1张

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);  
        }  
    }  
}  

其他关于球形插值的参考文章:http://www.ituring.com.cn/article/120745

基本语法 public static Vector3 Slerp(Vector3 from, Vector3 to, float t);

其中参数from为插值起始点坐标,参数to为插值结束点坐标,参数t为插值系数。

功能说明 此方法用于返回从参数from点到参数to点的球形插值向量。例如,设现有Vector3实例A和B(如图14-15所示),则执行如下程序代码后

Vector3 C=Vector3. Slerp (from, to, t);

 当t≤0时,向量C=A;

 当t≥1时,向量C=B;

 当t从0增加到1时,向量C会从起始点A绕着A×B(即向量A和B的叉乘)的方向匀速移动到向量B,此处的匀速是指角度旋转的匀速,即向量C与B的夹角k=e*(1t),如图14-15所示,这样便可确定向量C的方向。而向量C的模长计算公式则为:

;

这样便可以确定向量C了。

 当向量A和B中某个分量的值都为0时,比如它们的y轴分量都为0,即ay=by=0时,则A将绕着y轴在xz平面匀速旋转向B移动,并且在移动过程中C.y的值始终为0。

球性插值第2张

图14-15 Slerp球形插值

实例演示 下面通过实例演示方法Slerp的使用。

using UnityEngine;

using System.Collections;


public class Slerp_ts : MonoBehaviour {

public Transform from_T, to_T;

Vector3 from_v, to_v;

Vector3 slerps = Vector3.zero;

float speed = 0.1f;



void Start () {

    //初始化起始位置

    from_v = from_T.position;

    to_v = to_T.position;

}



void Update () {

    //在1/speed时间内slerps从from_v移动到to_v

    slerps = Vector3.Slerp(from_v,to_v,Time.time*speed);

    //绘制从原点到slerps的红线,并保留100秒以便观察

    //运行时只能在scene视图中查看

    Debug.DrawLine(Vector3.zero,slerps,Color.red,100.0f);

}

}

 在这段代码中,首先声明了3个Vector3变量from_v、to_v和slerps,并在Start方法中对其初始化,然后在方法Update中将方法Vector3.Slerp的返回值赋给slerps,最后绘制一条从世界坐标系原点到slerps的直线。请自行运行程序,查看slerps点的移动轨迹,运行时请在Scene视图而非Game视图中查看,

图14-16是一张运行时截图及注释。

球性插值第3张

免责声明:文章转载自《球性插值》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇第二章:Android Studio概述(一)[学习Android Studio汉化教程]墨者学院WebShell文件上传分析溯源(第2题)Write下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

解决IDEA打包出现中文乱码的问题

解决方案:1.打开IDEA文件中的设置。...

WinSCP命令行操作

WinSCP命令行操作WinSCP是一个在Windows环境下使用SSH的开源图形SFTP客户端。它还支持SCP协议。它的主要功能是在本地和远程计算机之间安全地复制文件。在cmd下直接输入winscp,进入winscp操作界面。查看帮助。直接在下面输入帮助以查看所有可用命令。当第一个参数为“both”时,一个参数与另一个参数同步。未指定目录时,同步当前工作目...

adb

ADB(AndroidDebugBridge)ANR(ApplicationNoResponding)ADB实际上是Android调试桥AndroidDebugBridge的缩写。adb是C/S体系结构的命令行工具。这里我们介绍一些常用的命令:adbdevices,获取设备列表和设备状态[xuxu:~]$adbdevicesList-devicesattac...

vue.js(3)

vue中有两种类型的组件:默认组件[全局组件]和单文件组件5.1.1默认组件vue。组成部分varvm=newVue6.Vue自动化工具需要提前安装和准备一些组件开发工具,以便在了解常见组件后继续学习单文件组件。因此,我们需要首先在系统中构建vue CLI工具。官方网站:https://cli.vuejs.org/zh/VueCLI需要Node.js8.9或...

Vue之项目搭建

常用命令:npminstall-g包名#安装模块-g表示全局安装,如果没有-g,则表示在当前项目安装npmlist#查看当前目录下已安装的node包npmview包名engines#查看包所依赖的Node的版本npmoutdated#检查包是否已经过时,命令会列出所有已过时的包npmupdate包名#更新node包npmuninstall包名#卸载node包...

调用钉钉接口发送消息

1.首先登录指甲显影剂后台https://ding-doc.dingtalk.com/2.选择H5微应用程序创建应用程序;2stringappsecret=“kKsIwqEQJHt3mW69opU6RO9...