贝塞尔曲线

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BezieTool
{
    /// 
    /// 根据T值计算贝塞尔曲线
    /// 
    /// T值
    /// 起始点
    /// 控制点
    /// 目标点
    ///  根据T值计算出来的贝塞尔曲线点
    private static Vector3 CalculateBezierPoint(float t, Vector3 p0,Vector3 p1,Vector3 p2)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        Vector3 p = uu * p0;
        p += 2 * u * t * p1;
        p += tt * p2;
        return p;
    }

    /// 
    /// 获取存储贝塞尔曲线的数组
    /// 
    /// 起始点
    /// 控制点
    /// 目标点
    /// 采样点的数量
    ///  存储贝塞尔曲线的数组
    public static Vector3[] GetBeizePointList(Vector3 startPoint,Vector3 controlPoint, Vector3 endPoint,int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i= 1;i<=segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculateBezierPoint(t, startPoint, controlPoint, endPoint);
            path[i - 1] = pixel;
        }

        return path;
    }


    /// 
    /// 根据T值计算贝塞尔曲线
    /// 
    /// T值
    /// 起始点
    /// 控制点
    /// 目标点
    ///  根据T值计算出来的贝塞尔曲线点
    private static Vector3 CalculateBezierPoint3(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {
        float u = 1 - t;
        float uu = (1-t) * (1-t);
        float uuu  = (1 - t) * (1 - t) * (1 - t);
        float tt = t * t;
        float ttt = t * t*t;
        Vector3 p = uu * p0;
        p = p0 * uuu + 3 * p1 * t * uu + 3*p2*tt*u + p3 * ttt;
       
        return p;
    }

    /// 
    /// 获取存储贝塞尔曲线的数组
    /// 
    /// 起始点
    /// 控制点
    /// 目标点
    /// 采样点的数量
    ///  存储贝塞尔曲线的数组
    public static Vector3[] GetBeizePointList3(Vector3 startPoint, Vector3 controlPoint1, Vector3 controlPoint2, Vector3 endPoint, int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i = 1; i <= segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculateBezierPoint3(t, startPoint, controlPoint1, controlPoint2 ,endPoint);
            path[i - 1] = pixel;
        }

        return path;
    }


    //传入顶点集合,得到高阶的贝塞尔曲线,顶点数量不限
    //vertexCount 为构建曲线的顶点数,此数值越大曲线越平滑
    public static Vector3[] GetBezierCurveWithUnlimitPoints(Vector3[] vertex, int vertexCount)
    {
        List pointList = new List();
        pointList.Clear();
        for (float ratio = 0; ratio <= 1; ratio += 1.0f / vertexCount)
        {
            pointList.Add(UnlimitBezierCurve(vertex, ratio));
        }
        pointList.Add(vertex[vertex.Length - 1]);

        return pointList.ToArray();
    }

    public static Vector3 UnlimitBezierCurve(Vector3[] vecs, float t)
    {
        Vector3[] temp = new Vector3[vecs.Length];
        for (int i = 0; i < temp.Length; i++)
        {
            temp[i] = vecs[i];
        }
        //顶点集合有多长,曲线的每一个点就需要计算多少次。
        int n = temp.Length - 1;
        for (int i = 0; i < n; i++)
        {
            //依次计算各两个相邻的顶点的插值,并保存,每次计算都会进行降阶。剩余多少阶计算多少次。直到得到最后一条线性曲线。
            for (int j = 0; j < n - i; j++)
            {
                temp[j] = Vector3.Lerp(temp[j], temp[j + 1], t);
            }
        }
        //返回当前比例下曲线的点
        return temp[0];
    }

}



 public void PlayBezie()
    {

        Debug.Log("xxxx----PlayBezie");
        Vector3 startPoint = transform.position;
        Vector3 controlPotint = new Vector3(startPoint.x+2, startPoint.y+2, startPoint.z);
        Vector3 controlPotint2 = new Vector3(startPoint.x + 3, startPoint.y + 5, startPoint.z);
        Vector3 endPoint = new Vector3(startPoint.x + 6, startPoint.y, startPoint.z);
        path = null;

        Vector3[] ctro = { startPoint, controlPotint, controlPotint2, endPoint };
        path = null;
         path = BezieTool.GetBeizePointList(startPoint, controlPotint, endPoint, 100);
        //path = BezieTool.GetBezierCurveWithUnlimitPoints(ctro, 100);

        bezieMove = true;

    }
    public void UpateBeziePos()
    {
        if (bezieMove)
        {
            timeNum += Time.deltaTime;
            //if(timeNum >0.03f)
            {
                transform.position = path[index];

                timeNum = 0;
                index += 1;

                if (index == path.Length)
                {
                    bezieMove = false;
                    index = 0;
                }


            }
        }
    }

 

你可能感兴趣的:(unity3d)