123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- var vec2 = require("./vector");
- var curve = require("./curve");
- /**
- * @author Yi Shen(https://github.com/pissang)
- */
- var mathMin = Math.min;
- var mathMax = Math.max;
- var mathSin = Math.sin;
- var mathCos = Math.cos;
- var PI2 = Math.PI * 2;
- var start = vec2.create();
- var end = vec2.create();
- var extremity = vec2.create();
- /**
- * 从顶点数组中计算出最小包围盒,写入`min`和`max`中
- * @module zrender/core/bbox
- * @param {Array<Object>} points 顶点数组
- * @param {number} min
- * @param {number} max
- */
- function fromPoints(points, min, max) {
- if (points.length === 0) {
- return;
- }
- var p = points[0];
- var left = p[0];
- var right = p[0];
- var top = p[1];
- var bottom = p[1];
- var i;
- for (i = 1; i < points.length; i++) {
- p = points[i];
- left = mathMin(left, p[0]);
- right = mathMax(right, p[0]);
- top = mathMin(top, p[1]);
- bottom = mathMax(bottom, p[1]);
- }
- min[0] = left;
- min[1] = top;
- max[0] = right;
- max[1] = bottom;
- }
- /**
- * @memberOf module:zrender/core/bbox
- * @param {number} x0
- * @param {number} y0
- * @param {number} x1
- * @param {number} y1
- * @param {Array.<number>} min
- * @param {Array.<number>} max
- */
- function fromLine(x0, y0, x1, y1, min, max) {
- min[0] = mathMin(x0, x1);
- min[1] = mathMin(y0, y1);
- max[0] = mathMax(x0, x1);
- max[1] = mathMax(y0, y1);
- }
- var xDim = [];
- var yDim = [];
- /**
- * 从三阶贝塞尔曲线(p0, p1, p2, p3)中计算出最小包围盒,写入`min`和`max`中
- * @memberOf module:zrender/core/bbox
- * @param {number} x0
- * @param {number} y0
- * @param {number} x1
- * @param {number} y1
- * @param {number} x2
- * @param {number} y2
- * @param {number} x3
- * @param {number} y3
- * @param {Array.<number>} min
- * @param {Array.<number>} max
- */
- function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
- var cubicExtrema = curve.cubicExtrema;
- var cubicAt = curve.cubicAt;
- var i;
- var n = cubicExtrema(x0, x1, x2, x3, xDim);
- min[0] = Infinity;
- min[1] = Infinity;
- max[0] = -Infinity;
- max[1] = -Infinity;
- for (i = 0; i < n; i++) {
- var x = cubicAt(x0, x1, x2, x3, xDim[i]);
- min[0] = mathMin(x, min[0]);
- max[0] = mathMax(x, max[0]);
- }
- n = cubicExtrema(y0, y1, y2, y3, yDim);
- for (i = 0; i < n; i++) {
- var y = cubicAt(y0, y1, y2, y3, yDim[i]);
- min[1] = mathMin(y, min[1]);
- max[1] = mathMax(y, max[1]);
- }
- min[0] = mathMin(x0, min[0]);
- max[0] = mathMax(x0, max[0]);
- min[0] = mathMin(x3, min[0]);
- max[0] = mathMax(x3, max[0]);
- min[1] = mathMin(y0, min[1]);
- max[1] = mathMax(y0, max[1]);
- min[1] = mathMin(y3, min[1]);
- max[1] = mathMax(y3, max[1]);
- }
- /**
- * 从二阶贝塞尔曲线(p0, p1, p2)中计算出最小包围盒,写入`min`和`max`中
- * @memberOf module:zrender/core/bbox
- * @param {number} x0
- * @param {number} y0
- * @param {number} x1
- * @param {number} y1
- * @param {number} x2
- * @param {number} y2
- * @param {Array.<number>} min
- * @param {Array.<number>} max
- */
- function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
- var quadraticExtremum = curve.quadraticExtremum;
- var quadraticAt = curve.quadraticAt; // Find extremities, where derivative in x dim or y dim is zero
- var tx = mathMax(mathMin(quadraticExtremum(x0, x1, x2), 1), 0);
- var ty = mathMax(mathMin(quadraticExtremum(y0, y1, y2), 1), 0);
- var x = quadraticAt(x0, x1, x2, tx);
- var y = quadraticAt(y0, y1, y2, ty);
- min[0] = mathMin(x0, x2, x);
- min[1] = mathMin(y0, y2, y);
- max[0] = mathMax(x0, x2, x);
- max[1] = mathMax(y0, y2, y);
- }
- /**
- * 从圆弧中计算出最小包围盒,写入`min`和`max`中
- * @method
- * @memberOf module:zrender/core/bbox
- * @param {number} x
- * @param {number} y
- * @param {number} rx
- * @param {number} ry
- * @param {number} startAngle
- * @param {number} endAngle
- * @param {number} anticlockwise
- * @param {Array.<number>} min
- * @param {Array.<number>} max
- */
- function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max) {
- var vec2Min = vec2.min;
- var vec2Max = vec2.max;
- var diff = Math.abs(startAngle - endAngle);
- if (diff % PI2 < 1e-4 && diff > 1e-4) {
- // Is a circle
- min[0] = x - rx;
- min[1] = y - ry;
- max[0] = x + rx;
- max[1] = y + ry;
- return;
- }
- start[0] = mathCos(startAngle) * rx + x;
- start[1] = mathSin(startAngle) * ry + y;
- end[0] = mathCos(endAngle) * rx + x;
- end[1] = mathSin(endAngle) * ry + y;
- vec2Min(min, start, end);
- vec2Max(max, start, end); // Thresh to [0, Math.PI * 2]
- startAngle = startAngle % PI2;
- if (startAngle < 0) {
- startAngle = startAngle + PI2;
- }
- endAngle = endAngle % PI2;
- if (endAngle < 0) {
- endAngle = endAngle + PI2;
- }
- if (startAngle > endAngle && !anticlockwise) {
- endAngle += PI2;
- } else if (startAngle < endAngle && anticlockwise) {
- startAngle += PI2;
- }
- if (anticlockwise) {
- var tmp = endAngle;
- endAngle = startAngle;
- startAngle = tmp;
- } // var number = 0;
- // var step = (anticlockwise ? -Math.PI : Math.PI) / 2;
- for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
- if (angle > startAngle) {
- extremity[0] = mathCos(angle) * rx + x;
- extremity[1] = mathSin(angle) * ry + y;
- vec2Min(min, extremity, min);
- vec2Max(max, extremity, max);
- }
- }
- }
- exports.fromPoints = fromPoints;
- exports.fromLine = fromLine;
- exports.fromCubic = fromCubic;
- exports.fromQuadratic = fromQuadratic;
- exports.fromArc = fromArc;
|