bbox.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import * as vec2 from './vector.js';
  2. import * as curve from './curve.js';
  3. var mathMin = Math.min;
  4. var mathMax = Math.max;
  5. var mathSin = Math.sin;
  6. var mathCos = Math.cos;
  7. var PI2 = Math.PI * 2;
  8. var start = vec2.create();
  9. var end = vec2.create();
  10. var extremity = vec2.create();
  11. export function fromPoints(points, min, max) {
  12. if (points.length === 0) {
  13. return;
  14. }
  15. var p = points[0];
  16. var left = p[0];
  17. var right = p[0];
  18. var top = p[1];
  19. var bottom = p[1];
  20. for (var i = 1; i < points.length; i++) {
  21. p = points[i];
  22. left = mathMin(left, p[0]);
  23. right = mathMax(right, p[0]);
  24. top = mathMin(top, p[1]);
  25. bottom = mathMax(bottom, p[1]);
  26. }
  27. min[0] = left;
  28. min[1] = top;
  29. max[0] = right;
  30. max[1] = bottom;
  31. }
  32. export function fromLine(x0, y0, x1, y1, min, max) {
  33. min[0] = mathMin(x0, x1);
  34. min[1] = mathMin(y0, y1);
  35. max[0] = mathMax(x0, x1);
  36. max[1] = mathMax(y0, y1);
  37. }
  38. var xDim = [];
  39. var yDim = [];
  40. export function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
  41. var cubicExtrema = curve.cubicExtrema;
  42. var cubicAt = curve.cubicAt;
  43. var n = cubicExtrema(x0, x1, x2, x3, xDim);
  44. min[0] = Infinity;
  45. min[1] = Infinity;
  46. max[0] = -Infinity;
  47. max[1] = -Infinity;
  48. for (var i = 0; i < n; i++) {
  49. var x = cubicAt(x0, x1, x2, x3, xDim[i]);
  50. min[0] = mathMin(x, min[0]);
  51. max[0] = mathMax(x, max[0]);
  52. }
  53. n = cubicExtrema(y0, y1, y2, y3, yDim);
  54. for (var i = 0; i < n; i++) {
  55. var y = cubicAt(y0, y1, y2, y3, yDim[i]);
  56. min[1] = mathMin(y, min[1]);
  57. max[1] = mathMax(y, max[1]);
  58. }
  59. min[0] = mathMin(x0, min[0]);
  60. max[0] = mathMax(x0, max[0]);
  61. min[0] = mathMin(x3, min[0]);
  62. max[0] = mathMax(x3, max[0]);
  63. min[1] = mathMin(y0, min[1]);
  64. max[1] = mathMax(y0, max[1]);
  65. min[1] = mathMin(y3, min[1]);
  66. max[1] = mathMax(y3, max[1]);
  67. }
  68. export function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
  69. var quadraticExtremum = curve.quadraticExtremum;
  70. var quadraticAt = curve.quadraticAt;
  71. var tx = mathMax(mathMin(quadraticExtremum(x0, x1, x2), 1), 0);
  72. var ty = mathMax(mathMin(quadraticExtremum(y0, y1, y2), 1), 0);
  73. var x = quadraticAt(x0, x1, x2, tx);
  74. var y = quadraticAt(y0, y1, y2, ty);
  75. min[0] = mathMin(x0, x2, x);
  76. min[1] = mathMin(y0, y2, y);
  77. max[0] = mathMax(x0, x2, x);
  78. max[1] = mathMax(y0, y2, y);
  79. }
  80. export function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max) {
  81. var vec2Min = vec2.min;
  82. var vec2Max = vec2.max;
  83. var diff = Math.abs(startAngle - endAngle);
  84. if (diff % PI2 < 1e-4 && diff > 1e-4) {
  85. min[0] = x - rx;
  86. min[1] = y - ry;
  87. max[0] = x + rx;
  88. max[1] = y + ry;
  89. return;
  90. }
  91. start[0] = mathCos(startAngle) * rx + x;
  92. start[1] = mathSin(startAngle) * ry + y;
  93. end[0] = mathCos(endAngle) * rx + x;
  94. end[1] = mathSin(endAngle) * ry + y;
  95. vec2Min(min, start, end);
  96. vec2Max(max, start, end);
  97. startAngle = startAngle % (PI2);
  98. if (startAngle < 0) {
  99. startAngle = startAngle + PI2;
  100. }
  101. endAngle = endAngle % (PI2);
  102. if (endAngle < 0) {
  103. endAngle = endAngle + PI2;
  104. }
  105. if (startAngle > endAngle && !anticlockwise) {
  106. endAngle += PI2;
  107. }
  108. else if (startAngle < endAngle && anticlockwise) {
  109. startAngle += PI2;
  110. }
  111. if (anticlockwise) {
  112. var tmp = endAngle;
  113. endAngle = startAngle;
  114. startAngle = tmp;
  115. }
  116. for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
  117. if (angle > startAngle) {
  118. extremity[0] = mathCos(angle) * rx + x;
  119. extremity[1] = mathSin(angle) * ry + y;
  120. vec2Min(min, extremity, min);
  121. vec2Max(max, extremity, max);
  122. }
  123. }
  124. }