
using System;

namespace MyParking.Shared
{
    /// <summary>
    /// 提供与具体业务和坐标系无关的基础插值功能。
    /// </summary>
    public static class InterpolationMath
    {
        /// <summary>
        /// 将插值比例限制到[0, 1]闭区间。
        /// </summary>
        public static double Clamp01(double value)
        {
            EnsureFinite(value, nameof(value));

            if (value <= 0.0)
            {
                return 0.0;
            }

            if (value >= 1.0)
            {
                return 1.0;
            }

            return value;
        }

        /// <summary>
        /// 对两个标量执行线性插值。
        /// ratio为0时返回start，ratio为1时返回end；本方法不限制ratio，
        /// 因此也支持区间外的线性外插。
        /// </summary>
        public static double Lerp(
            double start,
            double end,
            double ratio)
        {
            EnsureFinite(start, nameof(start));
            EnsureFinite(end, nameof(end));
            EnsureFinite(ratio, nameof(ratio));

            return start + ratio * (end - start);
        }

        /// <summary>
        /// 验证输入是可用于插值计算的有限数值。
        /// </summary>
        private static void EnsureFinite(double value, string parameterName)
        {
            if (double.IsNaN(value) || double.IsInfinity(value))
            {
                throw new ArgumentOutOfRangeException(
                    parameterName,
                    "插值参数必须是有限数值。");
            }
        }
    }
}
