贝塞尔曲线

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

public class BezieTool
{
    /// <summary>
    /// 根据T值计算贝塞尔曲线
    /// </summary>
    /// <param name="t">T值</param>
    /// <param name="p0">起始点</param>
    /// <param name="p1">控制点</param>
    /// <param name="p2">目标点</param>
    /// <returns></returns> 根据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;
    }

    /// <summary>
    /// 获取存储贝塞尔曲线的数组
    /// </summary>
    /// <param name="startPoint">起始点</param>
    /// <param name="controlPoint">控制点</param>
    /// <param name="endPoint">目标点</param>
    /// <param name="segmentNum">采样点的数量</param>
    /// <returns></returns> 存储贝塞尔曲线的数组
    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;
    }


    /// <summary>
    /// 根据T值计算贝塞尔曲线
    /// </summary>
    /// <param name="t">T值</param>
    /// <param name="p0">起始点</param>
    /// <param name="p1">控制点</param>
    /// <param name="p2">目标点</param>
    /// <returns></returns> 根据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;
    }

    /// <summary>
    /// 获取存储贝塞尔曲线的数组
    /// </summary>
    /// <param name="startPoint">起始点</param>
    /// <param name="controlPoint">控制点</param>
    /// <param name="endPoint">目标点</param>
    /// <param name="segmentNum">采样点的数量</param>
    /// <returns></returns> 存储贝塞尔曲线的数组
    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<Vector3> pointList = new List<Vector3>();
        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;
                }


            }
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值