{"version":3,"file":"index.umd.cjs","sources":["../src/EquationSolving.ts","../src/Bezier.ts","../src/HighFunction.ts"],"sourcesContent":["/**\r\n * 方程求解\r\n *\r\n * 求解方程 f(x) == 0 在[a, b]上的解\r\n *\r\n * 参考：高等数学 第七版上册 第三章第八节 方程的近似解\r\n * 当f(x)在区间 [a, b] 上连续，且f(a) * f(b) <= 0 时，f(x)在区间 [a, b] 上至少存在一个解使得 f(x) == 0\r\n *\r\n * 当f(x)在区间 [a, b] 上连续，且 (f(a) - y) * (f(b) - y) < 0 时，f(x)在区间 [a, b] 上至少存在一个解使得 f(x) == y\r\n *\r\n * @author feng / http://feng3d.com 05/06/2018\r\n */\r\nexport class EquationSolving\r\n{\r\n    /**\r\n     * 获取数字的(正负)符号\r\n     * @param n 数字\r\n     */\r\n    private getSign(n: number)\r\n    {\r\n        return n > 0 ? '+' : '-';\r\n    }\r\n\r\n    /**\r\n     * 比较 a 与 b 是否相等\r\n     * @param a 值a\r\n     * @param b 值b\r\n     * @param precision 比较精度\r\n     */\r\n    private equalNumber(a: number, b: number, precision = 0.0000001)\r\n    {\r\n        return Math.abs(a - b) < precision;\r\n    }\r\n\r\n    /**\r\n     * 获取近似导函数 f'(x)\r\n     *\r\n     * 导函数定义\r\n     * f'(x) = (f(x + Δx) - f(x)) / Δx , Δx → 0\r\n     *\r\n     * 注：通过测试Δx不能太小，由于方程内存在x的n次方问题（比如0.000000000000001的10次方为0），过小会导致计算机计算进度不够反而导致求导不准确！\r\n     *\r\n     * 另外一种办法是还原一元多次函数，然后求出导函数。\r\n     *\r\n     * @param f 函数\r\n     * @param delta Δx，进过测试该值太小或者过大都会导致求导准确率降低（个人猜测是计算机计算精度问题导致）\r\n     */\r\n    getDerivative(f: (x: number) => number, delta = 0.000000001)\r\n    {\r\n        return (x: number) =>\r\n        {\r\n            const d = (f(x + delta) - f(x)) / delta;\r\n\r\n            return d;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * 函数是否连续\r\n     * @param f 函数\r\n     */\r\n    isContinuous(_f: (x: number) => number)\r\n    {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * 方程 f(x) == 0 在 [a, b] 区间内是否有解\r\n     *\r\n     * 当f(x)在区间 [a, b] 上连续，且f(a) * f(b) <= 0 时，f(x)在区间 [a, b] 上至少存在一个解使得 f(x) == 0\r\n     *\r\n     * @param f 函数f(x)\r\n     * @param a 区间起点\r\n     * @param b 区间终点\r\n     * @param errorcallback  错误回调函数\r\n     *\r\n     * @returns 是否有解\r\n     */\r\n    hasSolution(f: (x: number) => number, a: number, b: number, errorcallback?: (err: Error) => void)\r\n    {\r\n        if (!this.isContinuous(f))\r\n        {\r\n            errorcallback && errorcallback(new Error(`函数 ${f} 在 [${a} ,${b}] 区间内不连续，无法为其求解！`));\r\n\r\n            return false;\r\n        }\r\n        const fa = f(a);\r\n        const fb = f(b);\r\n        if (fa * fb > 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`f(a) * f(b) 值为 ${fa * fb}，不满足 f(a) * f(b) <= 0，无法为其求解！`));\r\n\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * 二分法 求解 f(x) == 0\r\n     *\r\n     * 通过区间中点作为边界来逐步缩小求解区间，最终获得解\r\n     *\r\n     * @param f 函数f(x)\r\n     * @param a 区间起点\r\n     * @param b 区间终点\r\n     * @param precision 求解精度\r\n     * @param errorcallback  错误回调函数\r\n     *\r\n     * @returns 不存在解时返回 undefined ，存在时返回 解\r\n     */\r\n    binary(f: (x: number) => number, a: number, b: number, precision = 0.0000001, errorcallback?: (err: Error) => void): number\r\n    {\r\n        if (!this.hasSolution(f, a, b, errorcallback)) return undefined;\r\n\r\n        let fa = f(a);\r\n        let fb = f(b);\r\n        if (this.equalNumber(fa, 0, precision))\r\n        {\r\n            return a;\r\n        }\r\n        if (this.equalNumber(fb, 0, precision))\r\n        {\r\n            return b;\r\n        }\r\n\r\n        let x: number;\r\n        let fr: number;\r\n        do\r\n        {\r\n            x = (a + b) / 2;\r\n            fr = f(x);\r\n            if (fa * fr < 0)\r\n            {\r\n                b = x;\r\n                fb = fr;\r\n            }\r\n            else\r\n            {\r\n                a = x;\r\n                fa = fr;\r\n            }\r\n        } while (!this.equalNumber(fr, 0, precision));\r\n\r\n        return x;\r\n    }\r\n\r\n    /**\r\n     * 连线法 求解 f(x) == 0\r\n     *\r\n     * 连线法是我自己想的方法，自己取的名字，目前没有找到相应的资料（这方法大家都能够想得到。）\r\n     *\r\n     * 用曲线弧两端的连线来代替曲线弧与X轴交点作为边界来逐步缩小求解区间，最终获得解\r\n     *\r\n     * 通过 A，B两点连线与x轴交点来缩小求解区间最终获得解\r\n     *\r\n     * A，B两点直线方程 f(x) = f(a) + (f(b) - f(a)) / (b - a) * (x-a) ,求 f(x) == 0 解得 x = a - fa * (b - a)/ (fb - fa)\r\n     *\r\n     * @param f 函数f(x)\r\n     * @param a 区间起点\r\n     * @param b 区间终点\r\n     * @param precision 求解精度\r\n     * @param errorcallback  错误回调函数\r\n     *\r\n     * @returns 不存在解时返回 undefined ，存在时返回 解\r\n     */\r\n    line(f: (x: number) => number, a: number, b: number, precision = 0.0000001, errorcallback?: (err: Error) => void): number\r\n    {\r\n        if (!this.hasSolution(f, a, b, errorcallback)) return undefined;\r\n\r\n        let fa = f(a);\r\n        let fb = f(b);\r\n        if (this.equalNumber(fa, 0, precision))\r\n        {\r\n            return a;\r\n        }\r\n        if (this.equalNumber(fb, 0, precision))\r\n        {\r\n            return b;\r\n        }\r\n        let x: number;\r\n        let fr: number;\r\n        do\r\n        {\r\n            //\r\n            x = a - fa * (b - a) / (fb - fa);\r\n            fr = f(x);\r\n            if (fa * fr < 0)\r\n            {\r\n                b = x;\r\n                fb = fr;\r\n            }\r\n            else\r\n            {\r\n                a = x;\r\n                fa = fr;\r\n            }\r\n        } while (!this.equalNumber(fr, 0, precision));\r\n\r\n        return x;\r\n    }\r\n\r\n    /**\r\n     * 切线法 求解 f(x) == 0\r\n     *\r\n     * 用曲线弧一端的切线来代替曲线弧，从而求出方程实根的近似解。\r\n     *\r\n     * 迭代公式： Xn+1 = Xn - f(Xn) / f'(Xn)\r\n     *\r\n     * #### 额外需求\r\n     * 1. f(x)在[a, b]上具有一阶导数 f'(x)\r\n     * 1. f'(x)在[a, b]上保持定号；意味着f(x)在[a, b]上单调\r\n     * 1. f''(x)在[a, b]上保持定号；意味着f'(x)在[a, b]上单调\r\n     *\r\n     * 切记，当无法满足这些额外要求时，该函数将找不到[a, b]上的解！！！！！！！！！！！\r\n     *\r\n     * @param f 函数f(x)\r\n     * @param f1 一阶导函数 f'(x)\r\n     * @param f2 二阶导函数 f''(x)\r\n     * @param a 区间起点\r\n     * @param b 区间终点\r\n     * @param precision 求解精度\r\n     * @param errorcallback  错误回调函数\r\n     *\r\n     * @returns 不存在解与无法使用该函数求解时返回 undefined ，否则返回 解\r\n     */\r\n    tangent(f: (x: number) => number, f1: (x: number) => number, f2: (x: number) => number, a: number, b: number, precision = 0.0000001, errorcallback?: (err: Error) => void): number\r\n    {\r\n        if (!this.hasSolution(f, a, b, errorcallback)) return undefined;\r\n\r\n        const fa = f(a);\r\n        const fb = f(b);\r\n        if (this.equalNumber(fa, 0, precision))\r\n        {\r\n            return a;\r\n        }\r\n        if (this.equalNumber(fb, 0, precision))\r\n        {\r\n            return b;\r\n        }\r\n\r\n        const f1Sign = fb - fa; // f'(x)在[a, b]上保持的定号\r\n        const f1a = f1(a);\r\n        const f1b = f1(b);\r\n\r\n        // f'(x)在[a, b]上保持定号\r\n        if (f1a * f1Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${a}) = ${f1a} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n        if (f1b * f1Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${b}) = ${f1b} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n\r\n        const f2Sign = fb - fa; // f''(x)在[a, b]上保持的定号\r\n        const f2a = f2(a);\r\n        const f2b = f2(b);\r\n        // f''(x)在[a, b]上保持定号\r\n        if (f2a * f2Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${a}) = ${f2a} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n        if (f2b * f2Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${b}) = ${f2b} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n\r\n        let x: number;\r\n        if (f1Sign > 0)\r\n        {\r\n            if (f2Sign > 0)\r\n            { x = b; }\r\n            else\r\n            { x = a; }\r\n        }\r\n        else if (f2Sign > 0)\r\n        {\r\n            x = a;\r\n        }\r\n        else\r\n        {\r\n            x = b;\r\n        }\r\n\r\n        let fx: number;\r\n        do\r\n        {\r\n            fx = f(x);\r\n            const f1x = f1(x);\r\n            const f2x = f2(x);\r\n            // f'(x)在[a, b]上保持定号\r\n            if (f1x * f1Sign <= 0)\r\n            {\r\n                errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${x}) = ${f1x} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n                return undefined;\r\n            }\r\n            // f''(x)在[a, b]上保持定号\r\n            if (f2x * f2Sign <= 0)\r\n            {\r\n                errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${x}) = ${f2x} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n                return undefined;\r\n            }\r\n            // 迭代 Xn+1 = Xn - f(Xn) / f'(Xn)\r\n            x = x - fx / f1x;\r\n        } while (!this.equalNumber(fx, 0, precision));\r\n\r\n        return x;\r\n    }\r\n\r\n    /**\r\n     * 割线法（弦截法） 求解 f(x) == 0\r\n     *\r\n     * 使用 (f(Xn) - f(Xn-1)) / (Xn - Xn-1) 代替切线法迭代公式 Xn+1 = Xn - f(Xn) / f'(Xn) 中的 f'(x)\r\n     *\r\n     * 迭代公式：Xn+1 = Xn - f(Xn) * (Xn - Xn-1) / (f(Xn) - f(Xn-1));\r\n     *\r\n     * 用过点(Xn-1,f(Xn-1))和点(Xn,f(Xn))的割线来近似代替(Xn,f(Xn))处的切线，将这条割线与X轴交点的横坐标作为新的近似解。\r\n     *\r\n     * #### 额外需求\r\n     * 1. f(x)在[a, b]上具有一阶导数 f'(x)\r\n     * 1. f'(x)在[a, b]上保持定号；意味着f(x)在[a, b]上单调\r\n     * 1. f''(x)在[a, b]上保持定号；意味着f'(x)在[a, b]上单调\r\n     *\r\n     * 切记，当无法满足这些额外要求时，该函数将找不到[a, b]上的解！！！！！！！！！！！\r\n     *\r\n     * @param f 函数f(x)\r\n     * @param a 区间起点\r\n     * @param b 区间终点\r\n     * @param precision 求解精度\r\n     * @param errorcallback  错误回调函数\r\n     *\r\n     * @returns 不存在解与无法使用该函数求解时返回 undefined ，否则返回 解\r\n     */\r\n    secant(f: (x: number) => number, a: number, b: number, precision = 0.0000001, errorcallback?: (err: Error) => void): number\r\n    {\r\n        if (!this.hasSolution(f, a, b, errorcallback)) return undefined;\r\n\r\n        const fa = f(a);\r\n        const fb = f(b);\r\n        if (this.equalNumber(fa, 0, precision))\r\n        {\r\n            return a;\r\n        }\r\n        if (this.equalNumber(fb, 0, precision))\r\n        {\r\n            return b;\r\n        }\r\n\r\n        // 此处创建近似导函数以及二次导函数，其实割线法使用在计算f'(x)困难时的，但是 getDerivative 方法解决了这个困难。。。。\r\n        const f1 = this.getDerivative(f, precision);\r\n        const f2 = this.getDerivative(f1, precision);\r\n\r\n        const f1Sign = fb - fa; // f'(x)在[a, b]上保持的定号\r\n        //\r\n        const f1a = f1(a);\r\n        const f1b = f1(b);\r\n\r\n        // f'(x)在[a, b]上保持定号\r\n        if (f1a * f1Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${a}) = ${f1a} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n        if (f1b * f1Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${b}) = ${f1b} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n\r\n        const f2Sign = fb - fa; // f''(x)在[a, b]上保持的定号\r\n        const f2a = f2(a);\r\n        const f2b = f2(b);\r\n        // f''(x)在[a, b]上保持定号\r\n        if (f2a * f2Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${a}) = ${f2a} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n        if (f2b * f2Sign <= 0)\r\n        {\r\n            errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${b}) = ${f2b} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n            return undefined;\r\n        }\r\n\r\n        let x: number;\r\n        if (f1Sign > 0)\r\n        {\r\n            if (f2Sign > 0)\r\n            { x = b; }\r\n            else\r\n            { x = a; }\r\n        }\r\n        else if (f2Sign > 0)\r\n        {\r\n            x = a;\r\n        }\r\n        else\r\n        {\r\n            x = b;\r\n        }\r\n\r\n        // Xn-1\r\n        let xn1 = x;\r\n        let fxn1 = f(xn1);\r\n        // Xn\r\n        let xn = xn1 - precision * f2Sign / Math.abs(f2Sign);\r\n        let fxn = f(xn);\r\n        //\r\n        if (fxn * fxn1 < 0)\r\n        {\r\n            return xn;\r\n        }\r\n        // Xn+1\r\n        let xn$1: number;\r\n        do\r\n        {\r\n            const f1xn = f1(xn);\r\n            // f'(x)在[a, b]上保持定号\r\n            if (f1xn * f1Sign <= 0)\r\n            {\r\n                errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f'(${xn}) = ${f1xn} 在[a, b]上没有保持定号 ${this.getSign(f1Sign)} ，无法使用切线法求解`));\r\n\r\n                return undefined;\r\n            }\r\n            const f2xn = f2(xn);\r\n            // f''(x)在[a, b]上保持定号\r\n            if (f2xn * f2Sign <= 0)\r\n            {\r\n                errorcallback && errorcallback(new Error(`[${a}, ${b}] 上存在解，由于f''(${xn}) = ${f2xn} 在[a, b]上没有保持定号 ${this.getSign(f2Sign)} ，无法使用切线法求解`));\r\n\r\n                return undefined;\r\n            }\r\n            // 迭代 Xn+1 = Xn - f(Xn) * (Xn - Xn-1) / (f(Xn) - f(Xn-1));\r\n            xn$1 = xn - fxn * (xn - xn1) / (fxn - fxn1);\r\n            //\r\n            xn1 = xn;\r\n            fxn1 = fxn;\r\n            xn = xn$1;\r\n            fxn = f(xn);\r\n        } while (!this.equalNumber(fxn, 0, precision));\r\n\r\n        return xn;\r\n    }\r\n}\r\n\r\n/**\r\n * 方程求解\r\n */\r\nexport const equationSolving = new EquationSolving();\r\n\r\n","import { equationSolving } from './EquationSolving';\r\n\r\n/**\r\n * Bézier曲线\r\n * @see https://en.wikipedia.org/wiki/B%C3%A9zier_curve\r\n *\r\n * @author feng / http://feng3d.com 03/06/2018\r\n */\r\nexport class Bezier\r\n{\r\n    /**\r\n     * 线性Bézier曲线\r\n     * 给定不同的点P0和P1，线性Bézier曲线就是这两个点之间的直线。曲线由下式给出\r\n     * ```\r\n     * B(t) = p0 + t * (p1 - p0) = (1 - t) * p0 + t * p1 , 0 <= t && t <= 1\r\n     * ```\r\n     * 相当于线性插值\r\n     *\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     */\r\n    linear(t: number, p0: number, p1: number)\r\n    {\r\n        return p0 + t * (p1 - p0);\r\n        // return (1 - t) * p0 + t * p1;\r\n    }\r\n\r\n    /**\r\n     * 线性Bézier曲线关于t的导数\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     */\r\n    linearDerivative(t: number, p0: number, p1: number)\r\n    {\r\n        return p1 - p0;\r\n    }\r\n\r\n    /**\r\n     * 线性Bézier曲线关于t的二阶导数\r\n     * @param _t 插值度\r\n     * @param _p0 点0\r\n     * @param _p1 点1\r\n     */\r\n    linearSecondDerivative(_t: number, _p0: number, _p1: number)\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * 二次Bézier曲线\r\n     *\r\n     * 二次Bézier曲线是由函数B（t）跟踪的路径，给定点P0，P1和P2，\r\n     * ```\r\n     * B(t) = (1 - t) * ((1 - t) * p0 + t * p1) + t * ((1 - t) * p1 + t * p2) , 0 <= t && t <= 1\r\n     * ```\r\n     * 这可以解释为分别从P0到P1和从P1到P2的线性Bézier曲线上相应点的线性插值。重新排列前面的等式得出：\r\n     * ```\r\n     * B(t) = (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2 , 0 <= t && t <= 1\r\n     * ```\r\n     * Bézier曲线关于t的导数是\r\n     * ```\r\n     * B'(t) = 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1)\r\n     * ```\r\n     * 从中可以得出结论：在P0和P2处曲线的切线在P 1处相交。随着t从0增加到1，曲线沿P1的方向从P0偏离，然后从P1的方向弯曲到P2。\r\n     *\r\n     * Bézier曲线关于t的二阶导数是\r\n     * ```\r\n     * B''(t) = 2 * (p2 - 2 * p1 + p0)\r\n     * ```\r\n     *\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     */\r\n    quadratic(t: number, p0: number, p1: number, p2: number)\r\n    {\r\n        // return this.linear(t, this.linear(t, p0, p1), this.linear(t, p1, p2));\r\n        // return (1 - t) * ((1 - t) * p0 + t * p1) + t * ((1 - t) * p1 + t * p2);\r\n        return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;\r\n    }\r\n\r\n    /**\r\n     * 二次Bézier曲线关于t的导数\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     */\r\n    quadraticDerivative(t: number, p0: number, p1: number, p2: number)\r\n    {\r\n        // return 2 * this.linear(t, this.linearDerivative(t, p0, p1), this.linearDerivative(t, p1, p2));\r\n        return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1);\r\n    }\r\n\r\n    /**\r\n     * 二次Bézier曲线关于t的二阶导数\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     */\r\n    quadraticSecondDerivative(t: number, p0: number, p1: number, p2: number)\r\n    {\r\n        // return 1 * 2 * this.linearDerivative(t, p1 - p0, p2 - p1)\r\n        // return 1 * 2 * ((p2 - p1) - (p1 - p0));\r\n        return 2 * (p2 - 2 * p1 + p0);\r\n    }\r\n\r\n    /**\r\n     * 立方Bézier曲线\r\n     *\r\n     * 平面中或高维空间中（其实一维也是成立的，这里就是使用一维计算）的四个点P0，P1，P2和P3定义了三次Bézier曲线。\r\n     * 曲线开始于P0朝向P1并且从P2的方向到达P3。通常不会通过P1或P2; 这些点只是为了提供方向信息。\r\n     * P1和P2之间的距离在转向P2之前确定曲线向P1移动的“多远”和“多快” 。\r\n     *\r\n     * 对于由点Pi，Pj和Pk定义的二次Bézier曲线，可以将Bpipjpk(t)写成三次Bézier曲线，它可以定义为两条二次Bézier曲线的仿射组合：\r\n     * ```\r\n     * B(t) = (1 - t) * Bp0p1p2(t) + t * Bp1p2p3(t) , 0 <= t && t <= 1\r\n     * ```\r\n     * 曲线的显式形式是：\r\n     * ```\r\n     * B(t) = (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3 , 0 <= t && t <= 1\r\n     * ```\r\n     * 对于P1和P2的一些选择，曲线可以相交，或者包含尖点。\r\n     *\r\n     * 三次Bézier曲线相对于t的导数是\r\n     * ```\r\n     * B'(t) = 3 * (1 - t) * (1 - t) * (p1 - p0) + 6 * (1 - t) * t * (p2 - p1) + 3 * t * t * (p3 - p2);\r\n     * ```\r\n     * 三次Bézier曲线关于t的二阶导数是\r\n     * ```\r\n     * 6 * (1 - t) * (p2 - 2 * p1 + p0) + 6 * t * (p3 - 2 * p2 + p1);\r\n     * ```\r\n     *\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     * @param p3 点3\r\n     */\r\n    cubic(t: number, p0: number, p1: number, p2: number, p3: number)\r\n    {\r\n        // return this.linear(t, this.quadratic(t, p0, p1, p2), this.quadratic(t, p1, p2, p3));\r\n        return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3;\r\n    }\r\n\r\n    /**\r\n     * 三次Bézier曲线关于t的导数\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     * @param p3 点3\r\n     */\r\n    cubicDerivative(t: number, p0: number, p1: number, p2: number, p3: number)\r\n    {\r\n        // return 3 * this.linear(t, this.quadraticDerivative(t, p0, p1, p2), this.quadraticDerivative(t, p1, p2, p3));\r\n        return 3 * (1 - t) * (1 - t) * (p1 - p0) + 6 * (1 - t) * t * (p2 - p1) + 3 * t * t * (p3 - p2);\r\n    }\r\n\r\n    /**\r\n     * 三次Bézier曲线关于t的二阶导数\r\n     * @param t 插值度\r\n     * @param p0 点0\r\n     * @param p1 点1\r\n     * @param p2 点2\r\n     */\r\n    cubicSecondDerivative(t: number, p0: number, p1: number, p2: number, p3: number)\r\n    {\r\n        // return 3 * this.linear(t, this.quadraticSecondDerivative(t, p0, p1, p2), this.quadraticSecondDerivative(t, p1, p2, p3));\r\n        return 6 * (1 - t) * (p2 - 2 * p1 + p0) + 6 * t * (p3 - 2 * p2 + p1);\r\n    }\r\n\r\n    /**\r\n     * n次Bézier曲线\r\n     *\r\n     * 一般定义\r\n     *\r\n     * Bézier曲线可以定义为任意度n。\r\n     *\r\n     * @param t 插值度\r\n     * @param ps 点列表 ps.length == n+1\r\n     * @param processs 收集中间过程数据，可用作Bézier曲线动画数据\r\n     */\r\n    bn(t: number, ps: number[], processs: number[][] = null)\r\n    {\r\n        ps = ps.concat();\r\n        if (processs)\r\n        {\r\n            processs.push(ps.concat());\r\n        }\r\n        // n次Bézier递推\r\n        for (let i = ps.length - 1; i > 0; i--)\r\n        {\r\n            for (let j = 0; j < i; j++)\r\n            {\r\n                ps[j] = (1 - t) * ps[j] + t * ps[j + 1];\r\n            }\r\n            if (processs)\r\n            {\r\n                ps.length = ps.length - 1;\r\n                processs.push(ps.concat());\r\n            }\r\n        }\r\n\r\n        return ps[0];\r\n    }\r\n\r\n    /**\r\n     * n次Bézier曲线关于t的导数\r\n     *\r\n     * 一般定义\r\n     *\r\n     * Bézier曲线可以定义为任意度n。\r\n     *\r\n     * @param t 插值度\r\n     * @param ps 点列表 ps.length == n+1\r\n     */\r\n    bnDerivative(t: number, ps: number[])\r\n    {\r\n        if (ps.length < 2)\r\n        {\r\n            return 0;\r\n        }\r\n        ps = ps.concat();\r\n        // 进行\r\n        for (let i = 0, n = ps.length - 1; i < n; i++)\r\n        {\r\n            ps[i] = ps[i + 1] - ps[i];\r\n        }\r\n        //\r\n        ps.length = ps.length - 1;\r\n        const v = ps.length * this.bn(t, ps);\r\n\r\n        return v;\r\n    }\r\n\r\n    /**\r\n     * n次Bézier曲线关于t的二阶导数\r\n     *\r\n     * 一般定义\r\n     *\r\n     * Bézier曲线可以定义为任意度n。\r\n     *\r\n     * @param t 插值度\r\n     * @param ps 点列表 ps.length == n+1\r\n     */\r\n    bnSecondDerivative(t: number, ps: number[])\r\n    {\r\n        if (ps.length < 3)\r\n        {\r\n            return 0;\r\n        }\r\n        ps = ps.concat();\r\n        // 进行\r\n        for (let i = 0, n = ps.length - 1; i < n; i++)\r\n        {\r\n            ps[i] = ps[i + 1] - ps[i];\r\n        }\r\n        //\r\n        ps.length = ps.length - 1;\r\n        const v = ps.length * this.bnDerivative(t, ps);\r\n\r\n        return v;\r\n    }\r\n\r\n    /**\r\n     * n次Bézier曲线关于t的dn阶导数\r\n     *\r\n     * Bézier曲线可以定义为任意度n。\r\n     *\r\n     * @param t 插值度\r\n     * @param dn 求导次数\r\n     * @param ps 点列表     ps.length == n+1\r\n     */\r\n    bnND(t: number, dn: number, ps: number[])\r\n    {\r\n        if (ps.length < dn + 1)\r\n        {\r\n            return 0;\r\n        }\r\n        let factorial = 1;\r\n        ps = ps.concat();\r\n        for (let j = 0; j < dn; j++)\r\n        {\r\n            // 进行\r\n            for (let i = 0, n = ps.length - 1; i < n; i++)\r\n            {\r\n                ps[i] = ps[i + 1] - ps[i];\r\n            }\r\n            //\r\n            ps.length = ps.length - 1;\r\n            factorial *= ps.length;\r\n        }\r\n        const v = factorial * this.bn(t, ps);\r\n\r\n        return v;\r\n    }\r\n\r\n    /**\r\n     * 获取曲线在指定插值度上的值\r\n     * @param t 插值度\r\n     * @param ps 点列表\r\n     */\r\n    getValue(t: number, ps: number[]): number\r\n    {\r\n        if (ps.length === 2)\r\n        {\r\n            return this.linear(t, ps[0], ps[1]);\r\n        }\r\n        if (ps.length === 3)\r\n        {\r\n            return this.quadratic(t, ps[0], ps[1], ps[2]);\r\n        }\r\n        if (ps.length === 4)\r\n        {\r\n            return this.cubic(t, ps[0], ps[1], ps[2], ps[3]);\r\n        }\r\n\r\n        return this.bn(t, ps);\r\n        // var t1 = 1 - t;\r\n        // return t1 * t1 * t1 * ps[0] + 3 * t1 * t1 * t * ps[1] + 3 * t1 * t * t * ps[2] + t * t * t * ps[3];\r\n    }\r\n\r\n    /**\r\n     * 获取曲线在指定插值度上的导数(斜率)\r\n     * @param t 插值度\r\n     * @param ps 点列表\r\n     */\r\n    getDerivative(t: number, ps: number[]): number\r\n    {\r\n        if (ps.length === 2)\r\n        {\r\n            return this.linearDerivative(t, ps[0], ps[1]);\r\n        }\r\n        if (ps.length === 3)\r\n        {\r\n            return this.quadraticDerivative(t, ps[0], ps[1], ps[2]);\r\n        }\r\n        if (ps.length === 4)\r\n        {\r\n            return this.cubicDerivative(t, ps[0], ps[1], ps[2], ps[3]);\r\n        }\r\n\r\n        return this.bnDerivative(t, ps);\r\n        // return 3 * (1 - t) * (1 - t) * (ps[1] - ps[0]) + 6 * (1 - t) * t * (ps[2] - ps[1]) + 3 * t * t * (ps[3] - ps[2]);\r\n    }\r\n\r\n    /**\r\n     * 获取曲线在指定插值度上的二阶导数\r\n     * @param t 插值度\r\n     * @param ps 点列表\r\n     */\r\n    getSecondDerivative(t: number, ps: number[]): number\r\n    {\r\n        if (ps.length === 2)\r\n        {\r\n            return this.linearSecondDerivative(t, ps[0], ps[1]);\r\n        }\r\n        if (ps.length === 3)\r\n        {\r\n            return this.quadraticSecondDerivative(t, ps[0], ps[1], ps[2]);\r\n        }\r\n        if (ps.length === 4)\r\n        {\r\n            return this.cubicSecondDerivative(t, ps[0], ps[1], ps[2], ps[3]);\r\n        }\r\n\r\n        return this.bnSecondDerivative(t, ps);\r\n        // return 3 * (1 - t) * (1 - t) * (ps[1] - ps[0]) + 6 * (1 - t) * t * (ps[2] - ps[1]) + 3 * t * t * (ps[3] - ps[2]);\r\n    }\r\n\r\n    /**\r\n     * 查找区间内极值列表\r\n     *\r\n     * @param ps 点列表\r\n     * @param numSamples 采样次数，用于分段查找极值\r\n     * @param precision  查找精度\r\n     *\r\n     * @returns 极值列表 {} {ts: 极值插值度列表,vs: 极值值列表}\r\n     */\r\n    getExtremums(ps: number[], numSamples = 10, precision = 0.0000001)\r\n    {\r\n        const samples: number[] = [];\r\n        for (let i = 0; i <= numSamples; i++)\r\n        {\r\n            samples.push(this.getDerivative(i / numSamples, ps));\r\n        }\r\n        // 查找存在解的分段\r\n        //\r\n        const resultTs: number[] = [];\r\n        const resultVs: number[] = [];\r\n        for (let i = 0, n = numSamples; i < n; i++)\r\n        {\r\n            if (samples[i] * samples[i + 1] < 0)\r\n            {\r\n                const guessT = equationSolving.line((x) => this.getDerivative(x, ps), i / numSamples, (i + 1) / numSamples, precision);\r\n                resultTs.push(guessT);\r\n                resultVs.push(this.getValue(guessT, ps));\r\n            }\r\n        }\r\n\r\n        return { ts: resultTs, vs: resultVs };\r\n    }\r\n\r\n    /**\r\n     * 获取单调区间列表\r\n     *\r\n     * @param ps\r\n     * @param numSamples\r\n     * @param precision\r\n     * @returns {} {ts: 区间节点插值度列表,vs: 区间节点值列表}\r\n     */\r\n    getMonotoneIntervals(ps: number[], numSamples = 10, precision = 0.0000001)\r\n    {\r\n        // 区间内的单调区间\r\n        const monotoneIntervalTs = [0, 1];\r\n        const monotoneIntervalVs = [ps[0], ps[ps.length - 1]];\r\n        // 预先计算好极值\r\n        const extremums = this.getExtremums(ps, numSamples, precision);\r\n        for (let i = 0; i < extremums.ts.length; i++)\r\n        {\r\n            // 增加单调区间\r\n            monotoneIntervalTs.splice(i + 1, 0, extremums.ts[i]);\r\n            monotoneIntervalVs.splice(i + 1, 0, extremums.vs[i]);\r\n        }\r\n\r\n        return { ts: monotoneIntervalTs, vs: monotoneIntervalVs };\r\n    }\r\n\r\n    /**\r\n     * 获取目标值所在的插值度T\r\n     *\r\n     * @param targetV 目标值\r\n     * @param ps 点列表\r\n     * @param numSamples 分段数量，用于分段查找，用于解决寻找多个解、是否无解等问题；过少的分段可能会造成找不到存在的解决，过多的分段将会造成性能很差。\r\n     * @param precision  查找精度\r\n     *\r\n     * @returns 返回解数组\r\n     */\r\n    getTFromValue(targetV: number, ps: number[], numSamples = 10, precision = 0.0000001)\r\n    {\r\n        // 获取单调区间\r\n        const monotoneIntervals = this.getMonotoneIntervals(ps, numSamples, precision);\r\n        const monotoneIntervalTs = monotoneIntervals.ts;\r\n        const monotoneIntervalVs = monotoneIntervals.vs;\r\n\r\n        // 存在解的单调区间\r\n        const results: number[] = [];\r\n        // 遍历单调区间\r\n        for (let i = 0, n = monotoneIntervalVs.length - 1; i < n; i++)\r\n        {\r\n            if ((monotoneIntervalVs[i] - targetV) * (monotoneIntervalVs[i + 1] - targetV) <= 0)\r\n            {\r\n                const fx = (x) => this.getValue(x, ps) - targetV;\r\n\r\n                // 连线法\r\n                const result = equationSolving.line(fx, monotoneIntervalTs[i], monotoneIntervalTs[i + 1], precision);\r\n                results.push(result);\r\n            }\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * 分割曲线\r\n     *\r\n     * 在曲线插值度t位置分割为两条连接起来与原曲线完全重合的曲线\r\n     *\r\n     * @param t 分割位置（插值度）\r\n     * @param ps 被分割曲线点列表\r\n     * @returns 返回两条曲线组成的数组\r\n     */\r\n    split(t: number, ps: number[])\r\n    {\r\n        // 获取曲线的动画过程\r\n        const processs: number[][] = [];\r\n        bezier.bn(t, ps, processs);\r\n\r\n        // 第一条曲线\r\n        const fps: number[] = [];\r\n        // 第二条曲线\r\n        const sps: number[] = [];\r\n        // 使用当前t值进行分割曲线\r\n        for (let i = processs.length - 1; i >= 0; i--)\r\n        {\r\n            if (i === processs.length - 1)\r\n            {\r\n                // 添加关键点\r\n                fps.push(processs[i][0]);\r\n                fps.push(processs[i][0]);\r\n            }\r\n            else\r\n            {\r\n                // 添加左右控制点\r\n                fps.unshift(processs[i][0]);\r\n                sps.push(processs[i].pop());\r\n            }\r\n        }\r\n\r\n        return [fps, sps];\r\n    }\r\n\r\n    /**\r\n     * 合并曲线\r\n     *\r\n     * 合并两条连接的曲线为一条曲线并且可以还原为分割前的曲线\r\n     *\r\n     * @param fps 第一条曲线点列表\r\n     * @param sps 第二条曲线点列表\r\n     * @param mergeType 合并方式。mergeType = 0时进行还原合并，还原拆分之前的曲线；mergeType = 1时进行拟合合并，合并后的曲线会经过两条曲线的连接点；\r\n     */\r\n    merge(fps: number[], sps: number[], mergeType = 0)\r\n    {\r\n        fps = fps.concat();\r\n        sps = sps.concat();\r\n        const processs: number[][] = [];\r\n        let t: number;\r\n        // 上条曲线\r\n        let pps: number[];\r\n        // 当前曲线\r\n        let ps: number[];\r\n        for (let i = 0, n = fps.length; i < n; i++)\r\n        {\r\n            ps = processs[i] = [];\r\n            if (i === 0)\r\n            {\r\n                processs[i][0] = fps.pop();\r\n                sps.shift();\r\n            }\r\n            else if (i === 1)\r\n            {\r\n                // 计算t值\r\n                processs[i][0] = fps.pop();\r\n                processs[i][1] = sps.shift();\r\n                t = (processs[i - 1][0] - processs[i][0]) / (processs[i][1] - processs[i][0]);\r\n            }\r\n            else\r\n            {\r\n                pps = processs[i - 1];\r\n                // 前面增加点\r\n                const nfp = fps.pop();\r\n                // 后面增加点\r\n                const nsp = sps.shift();\r\n                // 从前往后计算\r\n                const ps0: number[] = [];\r\n                ps0[0] = nfp;\r\n                for (let j = 0, n = pps.length; j < n; j++)\r\n                {\r\n                    ps0[j + 1] = ps0[j] + (pps[j] - ps0[j]) / t;\r\n                }\r\n                // 从后往前计算\r\n                const ps1: number[] = [];\r\n                ps1[pps.length] = nsp;\r\n                for (let j = pps.length - 1; j >= 0; j--)\r\n                {\r\n                    ps1[j] = ps1[j + 1] - (ps1[j + 1] - pps[j]) / (1 - t);\r\n                }\r\n                // 拟合合并,合并前后两个方向的计算\r\n                if (mergeType === 1)\r\n                {\r\n                    for (let j = 0, n = ps0.length - 1; j <= n; j++)\r\n                    {\r\n                        ps[j] = (ps0[j] * (n - j) + ps1[j] * j) / n;\r\n                    }\r\n                }\r\n                else if (mergeType === 0)\r\n                {\r\n                    // 还原合并，前半段使用从前往后计算，后半段使用从后往前计算\r\n                    for (let j = 0, n = ps0.length - 1; j <= n; j++)\r\n                    {\r\n                        if (j < n / 2)\r\n                        {\r\n                            ps[j] = ps0[j];\r\n                        }\r\n                        else if (j > n / 2)\r\n                        {\r\n                            ps[j] = ps1[j];\r\n                        }\r\n                        else\r\n                        {\r\n                            ps[j] = (ps0[j] + ps1[j]) / 2;\r\n                        }\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    throw `合并类型 mergeType ${mergeType} 错误!`;\r\n                }\r\n            }\r\n        }\r\n\r\n        return processs.pop();\r\n    }\r\n\r\n    /**\r\n     * 获取曲线样本数据\r\n     *\r\n     * 这些点可用于连线来拟合曲线。\r\n     *\r\n     * @param ps 点列表\r\n     * @param num 采样次数 ，采样点分别为[0,1/num,2/num,....,(num-1)/num,1]\r\n     */\r\n    getSamples(ps: number[], num = 100)\r\n    {\r\n        const results: number[] = [];\r\n\r\n        for (let i = 0; i <= num; i++)\r\n        {\r\n            const p = this.getValue(i / num, ps);\r\n\r\n            results.push(p);\r\n        }\r\n\r\n        return results;\r\n    }\r\n}\r\n\r\n/**\r\n * Bézier曲线\r\n */\r\nexport const bezier = new Bezier();\r\n","/**\r\n * 高次函数\r\n *\r\n * 处理N次函数定义，求值，方程求解问题\r\n *\r\n * n次函数定义\r\n * f(x) = a0 * pow(x, n) + a1 * pow(x, n - 1) +.....+ an_1 * pow(x, 1) + an\r\n *\r\n * 0次 f(x) = a0;\r\n * 1次 f(x) = a0 * x + a1;\r\n * 2次 f(x) = a0 * x * x + a1 * x + a2;\r\n * ......\r\n *\r\n * @author feng / http://feng3d.com 05/06/2018\r\n */\r\nexport class HighFunction\r\n{\r\n    private as: number[];\r\n\r\n    /**\r\n     * 构建函数\r\n     * @param as 函数系数 a0-an 数组\r\n     */\r\n    constructor(as: number[])\r\n    {\r\n        this.as = as;\r\n    }\r\n\r\n    /**\r\n     * 获取函数 f(x) 的值\r\n     * @param x x坐标\r\n     */\r\n    getValue(x: number)\r\n    {\r\n        let v = 0;\r\n        const as = this.as;\r\n        for (let i = 0, n = as.length; i < n; i++)\r\n        {\r\n            v = v * x + as[i];\r\n        }\r\n\r\n        return v;\r\n    }\r\n}\r\n"],"names":["n"],"mappings":"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"}