* @function LevelRenderer.Tool.Curve.prototype.cubicRootAt * @description 计算三次贝塞尔方程根,使用盛金公式 * @param {number} p0 - 点p0。 * @param {number} p1 - 点p1。 * @param {number} p2 - 点p2。 * @param {number} p3 - 点p3。 * @param {number} val - 值。 * @param {Array. } roots -
(p0, p1, p2, p3, val, roots)
| 129 | * @returns {number} 有效根。 |
| 130 | */ |
| 131 | cubicRootAt(p0, p1, p2, p3, val, roots) { |
| 132 | // Evaluate roots of cubic functions |
| 133 | var a = p3 + 3 * (p1 - p2) - p0; |
| 134 | var b = 3 * (p2 - p1 * 2 + p0); |
| 135 | var c = 3 * (p1 - p0); |
| 136 | var d = p0 - val; |
| 137 | |
| 138 | var A = b * b - 3 * a * c; |
| 139 | var B = b * c - 9 * a * d; |
| 140 | var C = c * c - 3 * b * d; |
| 141 | |
| 142 | var n = 0; |
| 143 | |
| 144 | if (this.isAroundZero(A) && this.isAroundZero(B)) { |
| 145 | if (this.isAroundZero(b)) { |
| 146 | roots[0] = 0; |
| 147 | } else { |
| 148 | let t1 = -c / b; //t1, t2, t3, b is not zero |
| 149 | if (t1 >= 0 && t1 <= 1) { |
| 150 | roots[n++] = t1; |
| 151 | } |
| 152 | } |
| 153 | } else { |
| 154 | var disc = B * B - 4 * A * C; |
| 155 | |
| 156 | if (this.isAroundZero(disc)) { |
| 157 | var K = B / A; |
| 158 | let t1 = -b / a + K; // t1, a is not zero |
| 159 | let t2 = -K / 2; // t2, t3 |
| 160 | if (t1 >= 0 && t1 <= 1) { |
| 161 | roots[n++] = t1; |
| 162 | } |
| 163 | if (t2 >= 0 && t2 <= 1) { |
| 164 | roots[n++] = t2; |
| 165 | } |
| 166 | } else if (disc > 0) { |
| 167 | let discSqrt = Math.sqrt(disc); |
| 168 | let Y1 = A * b + 1.5 * a * (-B + discSqrt); |
| 169 | let Y2 = A * b + 1.5 * a * (-B - discSqrt); |
| 170 | if (Y1 < 0) { |
| 171 | Y1 = -Math.pow(-Y1, this.ONE_THIRD); |
| 172 | } else { |
| 173 | Y1 = Math.pow(Y1, this.ONE_THIRD); |
| 174 | } |
| 175 | if (Y2 < 0) { |
| 176 | Y2 = -Math.pow(-Y2, this.ONE_THIRD); |
| 177 | } else { |
| 178 | Y2 = Math.pow(Y2, this.ONE_THIRD); |
| 179 | } |
| 180 | let t1 = (-b - (Y1 + Y2)) / (3 * a); |
| 181 | if (t1 >= 0 && t1 <= 1) { |
| 182 | roots[n++] = t1; |
| 183 | } |
| 184 | } else { |
| 185 | var T = (2 * A * b - 3 * a * B) / (2 * Math.sqrt(A * A * A)); |
| 186 | var theta = Math.acos(T) / 3; |
| 187 | var ASqrt = Math.sqrt(A); |
| 188 | var tmp = Math.cos(theta); |
no test coverage detected