• Unity贝塞尔曲线


    贝塞尔曲线,简单就是对点之间连续进行插值,最后剩下两个点之后的计算结果

    即如点A,B,C,D,E,对这些点进行两两插值,如A1=AB,即A1是对A和B进行插值后的结果

    A1=AB,B1=BC,C1=CD,D1=DE

    A2=A1B1,B2=B1C1,C2=C1D1

    A3=A2B2,B3=B2C2

    Result=A3B3

    这里贴上我认为的比较好的一个仁兄的博客地址:https://blog.csdn.net/qq_35539447/article/details/80486247

    下面是我的代码

    using JetBrains.Annotations;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Bezier : MonoBehaviour
    {
        /// <summary>
        /// 三个控制点的贝塞尔曲线
        /// </summary>
        /// <param name="handles"></param>
        /// <param name="vertexCount"></param>
        /// <returns>返回贝塞尔曲线路径点表</returns>
        public static List<Vector3> BezierCurveWithThree(Transform[] handles,int vertexCount)
        {
            List<Vector3> pointList = new List<Vector3>();
            for (float ratio = 0; ratio <= 1; ratio += 1.0f / vertexCount)
            {
                Vector3 tangentLineVertex1 = Vector3.Lerp(handles[0].position, handles[1].position, ratio);
                Vector3 tangentLineVertex2 = Vector3.Lerp(handles[1].position, handles[2].position, ratio);
                Vector3 bezierPoint = Vector3.Lerp(tangentLineVertex1, tangentLineVertex2, ratio);
                pointList.Add(bezierPoint);
            }
            pointList.Add(handles[2].position);
    
            return pointList;
        }
    
        /// <summary>
        /// 超过三个控制点的贝塞尔曲线
        /// </summary>
        /// <param name="handlesPositions"></param>
        /// <param name="vertexCount"></param>
        public static List<Vector3> BezierCurveWithUnlimitPoints(Transform[] handlesPositions,int vertexCount)
        {
            List<Vector3> pointList = new List<Vector3>();
            for (float ratio = 0; ratio <= 1; ratio += 1.0f / vertexCount)
            {
                pointList.Add(UnlimitBezierCurve(handlesPositions, ratio));
            }
            pointList.Add(handlesPositions[handlesPositions.Length - 1].position);
    
            return pointList;
        }
        public static Vector3 UnlimitBezierCurve(Transform[] trans, float t)
        {
            Vector3[] temp = new Vector3[trans.Length];
            for (int i = 0; i < temp.Length; i++)
            {
                temp[i] = trans[i].position;
            }
            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];
        }
    }

    贝塞尔曲线动态组件代码

    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using UnityEngine;
    
    public class BezierController : MonoBehaviour
    {
        public bool isRunning;
        public bool isShowGizmos;
        public bool isShowLineRenderer;
        public bool isShowFixedPoints;
        [Header("控制手柄")]
        public Transform[] handles;
        Vector3[] handlesOriginalPoint;//控制带你的原始位置
        public int vertexCount;
        List<Vector3> pointList = new List<Vector3>();
        [Header("固定点距离点集合")]
        public List<Vector3> fixedSpacePoints = new List<Vector3>();
        public float fixedSpace;
        [Header("线渲染工具")]
        public LineRenderer lineRenderer;
    
        private void Start()
        {
            handlesOriginalPoint = new Vector3[handles.Length];
            for(int i = 0; i < handles.Length; i++)
            {
                handlesOriginalPoint[i] = handles[i].position;
            }
            Running();
        }
        
        private void Update()
        {
            if (CheckHandlesMove()&&isRunning)
            {
                Running();
            }
        }
    
        void Running()
        {
            pointList = Bezier.BezierCurveWithUnlimitPoints(handles, vertexCount);
            fixedSpacePoints = MathTools.GetEqualySpacePoints(pointList, fixedSpace);
    
            if (isShowLineRenderer) {
                lineRenderer.positionCount = pointList.Count;
                lineRenderer.SetPositions(pointList.ToArray());
            }
        }
    
        //获取路径点
        public List<Vector3> GetPointList()
        {
            return Bezier.BezierCurveWithUnlimitPoints(handles, vertexCount);
        }
    
        //获取固定间隔距离位置
        public List<Vector3> GetFixedSpacePoints()
        {
            CheckHandlesMove();
            List<Vector3> list = Bezier.BezierCurveWithUnlimitPoints(handles, vertexCount);
            return MathTools.GetEqualySpacePoints(list, fixedSpace);
        }
    
        //控制点是否发生更新: 是否改变了控制点的数量或者控制点是否发生了位移
        bool CheckHandlesMove()
        {
            bool hasMove = false;
    
            if(handlesOriginalPoint==null)handlesOriginalPoint = new Vector3[]{};
            if (handlesOriginalPoint.Length != handles.Length)
            {
                handlesOriginalPoint = new Vector3[handles.Length];
                for (int i = 0; i < handles.Length; i++)
                {
                    handlesOriginalPoint[i] = handles[i].position;
                }
                return true;
            }
    
            for(int i = 0; i < handles.Length; i++)
            {
                if(handles[i].position!= handlesOriginalPoint[i])
                {
                    hasMove = true;
                    break;
                }
            }
            return hasMove;
        }
    
        private void OnDrawGizmos()
        {
            if (isShowGizmos) {
                if (handles.Length > 3)
                {
                    #region 无限制顶点数
    
                    Gizmos.color = Color.green;
    
                    for (int i = 0; i < handles.Length - 1; i++)
                    {
                        Gizmos.DrawLine(handles[i].position, handles[i + 1].position);
                    }
    
                    Gizmos.color = Color.red;
    
                    Vector3[] temp = new Vector3[handles.Length];
                    for (int i = 0; i < temp.Length; i++)
                    {
                        temp[i] = handles[i].position;
                    }
                    int n = temp.Length - 1;
                    for (float ratio = 0.5f / vertexCount; ratio < 1; ratio += 1.0f / vertexCount)
                    {
                        for (int i = 0; i < n - 2; i++)
                        {
                            Gizmos.DrawLine(Vector3.Lerp(temp[i], temp[i + 1], ratio), Vector3.Lerp(temp[i + 2], temp[i + 3], ratio));
                        }
                    }
                    #endregion
                }
                else
                {
                    #region 顶点数为3
    
                    Gizmos.color = Color.green;
    
                    Gizmos.DrawLine(handles[0].position, handles[1].position);
    
                    Gizmos.color = Color.green;
    
                    Gizmos.DrawLine(handles[1].position, handles[2].position);
    
                    Gizmos.color = Color.red;
    
                    for (float ratio = 0.5f / vertexCount; ratio < 1; ratio += 1.0f / vertexCount)
                    {
    
                        Gizmos.DrawLine(Vector3.Lerp(handles[0].position, handles[1].position, ratio), Vector3.Lerp(handles[1].position, handles[2].position, ratio));
    
                    }
    
                    #endregion
                }
            }
    
            if (isShowFixedPoints) {
                #region 显示固定距离的点列表
                Gizmos.color = Color.green;
                foreach (Vector3 point in fixedSpacePoints)
                {
                    Gizmos.DrawSphere(point, 0.3f);
                }
                #endregion
            }
    
        }
    }

    上面的MathTool看我的另一个博客文章unity数学工具

  • 相关阅读:
    设计模式(08):结构型模式(二) 桥接模式(Bridge)
    设计模式(07):结构型模式(一) 适配器模式(Adapter)
    设计模式(06):创建型模式(五) 原型模式(Prototype)
    node.js获取cookie
    排序算法[转]
    Observer(观察者)设计模式[转]
    c#发送Http请求
    win+R下的命令
    display:inline、block、inline-block的区别
    Redis安装
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/13943197.html
Copyright © 2020-2023  润新知