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} 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.} min * @param {Array.} 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.} min * @param {Array.} 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.} min * @param {Array.} 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.} min * @param {Array.} 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;