C#版贝塞尔曲线代码:包含3点和5点确定曲线

如题,有三个点的曲线(开始点,中间点,结束点)

5个点:(开始点,结束点,三个中间点)

 

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

public class BezierCurve : MonoBehaviour
{
    public Transform _startTra;//起始点
    public Transform _centerTra;//中间点(随意即可)
    public Transform _endTra;//终结点

    //编辑器画线
    void OnDrawGizmos()
    {
        List<Vector3> m_pathPointList = new List<Vector3>();
        m_pathPointList.AddRange(GetPathPoints(_startTra.position, _endTra.position, _centerTra.position, 20));
        Gizmos.color = Color.yellow;
        for (int i = 0; i < m_pathPointList.Count - 1; i++)
        {
            Gizmos.DrawLine(m_pathPointList[i], m_pathPointList[i + 1]);
        }
    }
    //一个额外点的贝萨尔曲线(即抛物线)
    public static Vector3[] GetPathPoints(Vector3 startPos, Vector3 endPos, Vector3 centerPos, int needPointNumber = 20)
    {
        //为了节省性能
        //将其转化成;一个float,可以进行差值运算,否则结果为0
        float number = (float)needPointNumber;
        //定义一个数组,用来存放路径点,他的长度是从0 - needPointNumber的长度,及从0-1
        Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
        //只有在等于needPointNumber时Lerp()中最后一项的值才为1,所有比needPointNumber数多1
        for (int i = 0; i <= needPointNumber; i++)
        {
            //第一层
            Vector3 one1 = Vector3.Lerp(startPos, centerPos, i / number);
            Vector3 one2 = Vector3.Lerp(centerPos, endPos, i / number);
            //目标层
            Vector3 targetPos = Vector3.Lerp(one1, one2, i / number);
            //将目标层放入我们的路径点中
            targetPosArr[i] = targetPos;
        }
        //在for循环结束之后得到所有的路径点
        return targetPosArr;
    }
    /// 
    /// 将目标物体从开始点移动到目标点通过平滑的曲线
    /// 
    /// 你要移动的目标物体
    /// 目标物体的开始点
    /// 目标物体的结束点
    /// 三个中间点
    /// 你最终得到的路径点的中间数,默认是20,数量越大曲线越平滑,越小越线性
    /// 
    public static Vector3[] GetPathPoints(Transform start, Transform end, Transform[] threeCenterPosArr, int needPointNumber = 20)
    {
        //为了节省性能
        //将其转化成;一个float,可以进行差值运算,否则结果为0
        float number = (float)needPointNumber;
        //定义一个数组,用来存放路径点,他的长度是从0 - needPointNumber的长度,及从0-1
        Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
        //只有在等于needPointNumber时Lerp()中最后一项的值才为1,所有比needPointNumber数多1
        for (int i = 0; i <= needPointNumber; i++)
        {
            //第一层
            Vector3 one1 = Vector3.Lerp(start.position, threeCenterPosArr[0].position, i / number);
            Vector3 one2 = Vector3.Lerp(threeCenterPosArr[0].position, threeCenterPosArr[1].position, i / number);
            Vector3 one3 = Vector3.Lerp(threeCenterPosArr[1].position, threeCenterPosArr[2].position, i / number);
            Vector3 one4 = Vector3.Lerp(threeCenterPosArr[2].position, end.position, i / number);
            //第二层
            Vector3 two1 = Vector3.Lerp(one1, one2, i / number);
            Vector3 two2 = Vector3.Lerp(one2, one3, i / number);
            Vector3 two3 = Vector3.Lerp(one3, one4, i / number);
            //第三层
            Vector3 three1 = Vector3.Lerp(two1, two2, i / number);
            Vector3 three2 = Vector3.Lerp(two2, two3, i / number);
            //目标层
            Vector3 targetPos = Vector3.Lerp(three1, three2, i / number);
            //将目标层放入我们的路径点中
            targetPosArr[i] = targetPos;
        }
        //在for循环结束之后得到所有的路径点
        return targetPosArr;
    }
    //额外的重载方法,就不仔细介绍了
    public static Vector3[] GetPathPoints(Vector3 startPos, Vector3 endPos, Vector3[] threeCenterPosArr, int needPointNumber = 20)
    {
        float number = (float)needPointNumber;
        Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
        for (int i = 0; i <= number; i++)
        {
            //第一层
            Vector3 one1 = Vector3.Lerp(startPos, threeCenterPosArr[0], i / number);
            Vector3 one2 = Vector3.Lerp(threeCenterPosArr[0], threeCenterPosArr[1], i / number);
            Vector3 one3 = Vector3.Lerp(threeCenterPosArr[1], threeCenterPosArr[2], i / number);
            Vector3 one4 = Vector3.Lerp(threeCenterPosArr[2], endPos, i / number);
            //第二层
            Vector3 two1 = Vector3.Lerp(one1, one2, i / number);
            Vector3 two2 = Vector3.Lerp(one2, one3, i / number);
            Vector3 two3 = Vector3.Lerp(one3, one4, i / number);
            //第三层
            Vector3 three1 = Vector3.Lerp(two1, two2, i / number);
            Vector3 three2 = Vector3.Lerp(two2, two3, i / number);
            //目标层
            Vector3 targetPos = Vector3.Lerp(three1, three2, i / number);
            //将目标层放入我们的路径点中
            targetPosArr[i] = targetPos;
        }
        return targetPosArr;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章