quadratic.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var line_1 = require("./line");
  4. var util_1 = require("./util");
  5. var bezier_1 = require("./bezier");
  6. // 差值公式
  7. function quadraticAt(p0, p1, p2, t) {
  8. var onet = 1 - t;
  9. return onet * onet * p0 + 2 * t * onet * p1 + t * t * p2;
  10. }
  11. // 求极值
  12. function extrema(p0, p1, p2) {
  13. var a = p0 + p2 - 2 * p1;
  14. if (util_1.isNumberEqual(a, 0)) {
  15. return [0.5];
  16. }
  17. var rst = (p0 - p1) / a;
  18. if (rst <= 1 && rst >= 0) {
  19. return [rst];
  20. }
  21. return [];
  22. }
  23. function derivativeAt(p0, p1, p2, t) {
  24. return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1);
  25. }
  26. // 分割贝塞尔曲线
  27. function divideQuadratic(x1, y1, x2, y2, x3, y3, t) {
  28. // 划分点
  29. var xt = quadraticAt(x1, x2, x3, t);
  30. var yt = quadraticAt(y1, y2, y3, t);
  31. // 分割的第一条曲线的控制点
  32. var controlPoint1 = line_1.default.pointAt(x1, y1, x2, y2, t);
  33. // 分割的第二条曲线的控制点
  34. var controlPoint2 = line_1.default.pointAt(x2, y2, x3, y3, t);
  35. return [
  36. [x1, y1, controlPoint1.x, controlPoint1.y, xt, yt],
  37. [xt, yt, controlPoint2.x, controlPoint2.y, x3, y3],
  38. ];
  39. }
  40. // 使用迭代法取贝塞尔曲线的长度
  41. function quadraticLength(x1, y1, x2, y2, x3, y3, iterationCount) {
  42. if (iterationCount === 0) {
  43. return (util_1.distance(x1, y1, x2, y2) + util_1.distance(x2, y2, x3, y3) + util_1.distance(x1, y1, x3, y3)) / 2;
  44. }
  45. var quadratics = divideQuadratic(x1, y1, x2, y2, x3, y3, 0.5);
  46. var left = quadratics[0];
  47. var right = quadratics[1];
  48. left.push(iterationCount - 1);
  49. right.push(iterationCount - 1);
  50. return quadraticLength.apply(null, left) + quadraticLength.apply(null, right);
  51. }
  52. exports.default = {
  53. box: function (x1, y1, x2, y2, x3, y3) {
  54. var xExtrema = extrema(x1, x2, x3)[0];
  55. var yExtrema = extrema(y1, y2, y3)[0];
  56. // 控制点不加入 box 的计算
  57. var xArr = [x1, x3];
  58. var yArr = [y1, y3];
  59. if (xExtrema !== undefined) {
  60. xArr.push(quadraticAt(x1, x2, x3, xExtrema));
  61. }
  62. if (yExtrema !== undefined) {
  63. yArr.push(quadraticAt(y1, y2, y3, yExtrema));
  64. }
  65. return util_1.getBBoxByArray(xArr, yArr);
  66. },
  67. length: function (x1, y1, x2, y2, x3, y3) {
  68. return quadraticLength(x1, y1, x2, y2, x3, y3, 3);
  69. },
  70. nearestPoint: function (x1, y1, x2, y2, x3, y3, x0, y0) {
  71. return bezier_1.nearestPoint([x1, x2, x3], [y1, y2, y3], x0, y0, quadraticAt);
  72. },
  73. pointDistance: function (x1, y1, x2, y2, x3, y3, x0, y0) {
  74. var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0);
  75. return util_1.distance(point.x, point.y, x0, y0);
  76. },
  77. interpolationAt: quadraticAt,
  78. pointAt: function (x1, y1, x2, y2, x3, y3, t) {
  79. return {
  80. x: quadraticAt(x1, x2, x3, t),
  81. y: quadraticAt(y1, y2, y3, t),
  82. };
  83. },
  84. divide: function (x1, y1, x2, y2, x3, y3, t) {
  85. return divideQuadratic(x1, y1, x2, y2, x3, y3, t);
  86. },
  87. tangentAngle: function (x1, y1, x2, y2, x3, y3, t) {
  88. var dx = derivativeAt(x1, x2, x3, t);
  89. var dy = derivativeAt(y1, y2, y3, t);
  90. var angle = Math.atan2(dy, dx);
  91. return util_1.piMod(angle);
  92. },
  93. };
  94. //# sourceMappingURL=quadratic.js.map