* @return {Cubic[]} the non-inflecting pieces of this cubic * * returns an array containing 0, 1 or 2 cubics split resulting * from splitting this cubic at its inflection points. * this cubic is (potentially) altered and returned in the list.
()
| 385 | * this cubic is (potentially) altered and returned in the list. |
| 386 | */ |
| 387 | splitInflections() { |
| 388 | const a = Vector.sub(this.c0, this.p0); |
| 389 | const b = Vector.sub(Vector.sub(this.c1, this.c0), a); |
| 390 | const c = Vector.sub( |
| 391 | Vector.sub(Vector.sub(this.p1, this.c1), a), |
| 392 | Vector.mult(b, 2) |
| 393 | ); |
| 394 | |
| 395 | const cubics = []; |
| 396 | |
| 397 | // find the derivative coefficients |
| 398 | let A = b.x * c.y - b.y * c.x; |
| 399 | if (A !== 0) { |
| 400 | let B = a.x * c.y - a.y * c.x; |
| 401 | let C = a.x * b.y - a.y * b.x; |
| 402 | const disc = B * B - 4 * A * C; |
| 403 | if (disc >= 0) { |
| 404 | if (A < 0) { |
| 405 | A = -A; |
| 406 | B = -B; |
| 407 | C = -C; |
| 408 | } |
| 409 | |
| 410 | const Q = Math.sqrt(disc); |
| 411 | const t0 = (-B - Q) / (2 * A); // the first inflection point |
| 412 | let t1 = (-B + Q) / (2 * A); // the second inflection point |
| 413 | |
| 414 | // test if the first inflection point lies on the curve |
| 415 | if (t0 > 0 && t0 < 1) { |
| 416 | // split at the first inflection point |
| 417 | cubics.push(this.split(t0)); |
| 418 | // scale t2 into the second part |
| 419 | t1 = 1 - (1 - t1) / (1 - t0); |
| 420 | } |
| 421 | |
| 422 | // test if the second inflection point lies on the curve |
| 423 | if (t1 > 0 && t1 < 1) { |
| 424 | // split at the second inflection point |
| 425 | cubics.push(this.split(t1)); |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | cubics.push(this); |
| 431 | return cubics; |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | /** |
no test coverage detected