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

namespace TFramework
{
    /// <summary>
    /// 贝塞尔曲线
    /// </summary>
    public class BezierCurve
    {
        static List<Vector2> vector2s = new List<Vector2>();
        static List<Vector3> vector3s = new List<Vector3>();

        /// <summary>
        /// 阶乘
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
       private static long Factoral(int n)
        {
            long result = 1;
            for (int i = 2; i <= n; i++)
                result *= i;
            return result;
        }

        /// <summary>
        /// 计算组合数
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        private static long BinomialCoeffcient(int n,int k)=> Factoral(n) / Factoral(k) * Factoral(n - k);

        /// <summary>
        /// 获取Vector2贝塞尔曲线上的点
        /// </summary>
        /// <param name="t">范围值（0~1）</param>
        /// <param name="controlPoints">控制点</param>
        /// <returns></returns>
        public static Vector2 CalculateVector2BezierPoint(float t,IEnumerable<Vector2> controlPoints)
        {
            Vector2 point = Vector2.zero;
            vector2s.Clear();
            vector2s.AddRange(controlPoints);
            int n = vector2s.Count - 1;
            for(int i=0;i<=n;i++)
            {
                float binomialCoefficient = BinomialCoeffcient(n, i);
                float term = binomialCoefficient * Mathf.Pow(1 - t, n - i) * Mathf.Pow(t, i);
                point += term * vector2s[i];
            }
            return point;
        }

        /// <summary>
        /// 获取Vector3贝塞尔曲线上的点
        /// </summary>
        /// <param name="t">范围值（0~1）</param>
        /// <param name="controlPoints">控制点</param>
        /// <returns></returns>
        public static Vector3 CalculateVector3BezierPoint(float t, IEnumerable<Vector3> controlPoints)
        {
            Vector3 point = Vector3.zero;
            vector3s.Clear();
            vector3s.AddRange(controlPoints);
            int n = vector3s.Count - 1;
            for (int i = 0; i <= n; i++)
            {
                float binomialCoefficient = BinomialCoeffcient(n, i);
                float term = binomialCoefficient * Mathf.Pow(1 - t, n - i) * Mathf.Pow(t, i);
                point += term * vector3s[i];
            }
            return point;
        }
    }
}
