UNPKG

@antv/g2plot

Version:

G2 Plot, a market of plots built with the Grammar of Graphics'

307 lines 9.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrixUtil = tslib_1.__importStar(require("@antv/matrix-util")); var _ = tslib_1.__importStar(require("@antv/util")); function magnitude(v) { var sum = 0; _.each(v, function (value) { sum += value * value; }); return Math.sqrt(sum); } function dotProduct2D(va, vb) { return va.x * vb.y + va.y * vb.x; } exports.dotProduct2D = dotProduct2D; function angleTo(va, vb) { var magA = magnitude(va); var magB = magnitude(vb); var dot = dotProduct2D(va, vb); var angle = Math.acos(dot / magA / magB); return angle; } exports.angleTo = angleTo; function crossProduct2D(va, vb) { var magA = magnitude(va); var magB = magnitude(vb); var dot = dotProduct2D(va, vb); var angle = Math.acos(dot / magA / magB); return magA * magB * Math.sin(angle); } exports.crossProduct2D = crossProduct2D; function crossProduct3D(va, vb) { var ax = va.x, ay = va.y, az = va.z; var bx = vb.x, by = vb.y, bz = vb.z; var x = ay * bz - az * by; var y = az * bx - ax * bz; var z = ax * by - ay * bx; return { x: x, y: y, z: z }; } exports.crossProduct3D = crossProduct3D; function sub2D(va, vb) { return { x: va.x - vb.x, y: va.y - vb.y }; } exports.sub2D = sub2D; function applyMatrix(point, matrix, tag) { if (tag === void 0) { tag = 1; } var vector = [point.x, point.y, tag]; matrixUtil.vec3.transformMat3(vector, vector, matrix); return { x: vector[0], y: vector[1], }; } exports.applyMatrix = applyMatrix; function isBetween(value, min, max) { return value >= min && value <= max; } exports.isBetween = isBetween; var tolerance = 0.001; function getLineIntersect(p0, p1, p2, p3) { var E = { x: p2.x - p0.x, y: p2.y - p0.y, }; var D0 = { x: p1.x - p0.x, y: p1.y - p0.y, }; var D1 = { x: p3.x - p2.x, y: p3.y - p2.y, }; var kross = D0.x * D1.y - D0.y * D1.x; var sqrKross = kross * kross; var sqrLen0 = D0.x * D0.x + D0.y * D0.y; var sqrLen1 = D1.x * D1.x + D1.y * D1.y; var point = null; if (sqrKross > tolerance * sqrLen0 * sqrLen1) { var s = (E.x * D1.y - E.y * D1.x) / kross; var t = (E.x * D0.y - E.y * D0.x) / kross; if (isBetween(s, 0, 1) && isBetween(t, 0, 1)) { point = { x: p0.x + s * D0.x, y: p0.y + s * D0.y, }; } } return point; } exports.getLineIntersect = getLineIntersect; function isPointInPolygon(p, polygon) { /** 射线法 */ var inside = false; for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { var xi = polygon[i].x; var yi = polygon[i].y; var xj = polygon[j].x; var yj = polygon[j].y; var intersect = yi > p.y !== yj > p.y && p.x <= ((xj - xi) * (p.y - yi)) / (yj - yi) + xi; if (intersect) { inside = !inside; } } return inside; } exports.isPointInPolygon = isPointInPolygon; function sqr(v) { return v * v; } function dist2(a, b) { return Math.sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } exports.dist2 = dist2; function distBetweenPoints(a, b) { return Math.sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } exports.distBetweenPoints = distBetweenPoints; function distBetweenPointLine(p, p1, p2) { var l2 = dist2(p1, p2); if (l2 === 0) { return dist2(p, p1); } var t = ((p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y)) / l2; t = Math.max(0, Math.min(1, t)); var distSquare = dist2(p, { x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y) }); return Math.sqrt(distSquare); } exports.distBetweenPointLine = distBetweenPointLine; // todo:待优化 https://blog.csdn.net/WilliamSun0122/article/details/77994526 function minDistBetweenPointPolygon(p, polygon) { var min = Infinity; /** vertice to vertice */ _.each(polygon, function (v) { var dist = Math.sqrt(dist2(v, p)); if (min > dist) { min = dist; } }); /** vertice to edge */ for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { var xi = polygon[i].x; var yi = polygon[i].y; var xj = polygon[j].x; var yj = polygon[j].y; var dist = distBetweenPointLine(p, { x: xi, y: yi }, { x: xj, y: yj }); if (min > dist) { min = dist; } } return min; } function isPolygonIntersection(polyA, polyB) { for (var _i = 0, polyA_1 = polyA; _i < polyA_1.length; _i++) { var p = polyA_1[_i]; var inside = isPointInPolygon(p, polyB); if (inside) { return true; } } return false; } exports.isPolygonIntersection = isPolygonIntersection; function minDistBetweenConvexPolygon(polyA, polyB) { if (isPolygonIntersection(polyA, polyB)) { return 0; } var minA = Infinity; var minB = Infinity; _.each(polyA, function (v) { var localMin = minDistBetweenPointPolygon(v, polyB); if (minA > localMin) { minA = localMin; } }); _.each(polyB, function (v) { var localMin = minDistBetweenPointPolygon(v, polyA); if (minB > localMin) { minB = localMin; } }); return Math.min(minA, minB); } exports.minDistBetweenConvexPolygon = minDistBetweenConvexPolygon; function bboxOnRotate(shape) { var bbox = shape.getBBox(); var x = bbox.minX; var y = bbox.minY; /* * step1: 获得旋转后的shape包围盒 * 将包围盒对齐到原点,apply旋转矩阵 * 移回原来的位置 */ var bboxWidth = bbox.tr.x - bbox.tl.x; var bboxHeight = bbox.bl.y - bbox.tl.y; // const matrix = shape.getTotalMatrix(); var matrix = shape.attr('matrix'); var ulMatrix = [matrix[0], matrix[1], 0, matrix[3], matrix[4], 0, 0, 0, 1]; var top_left = applyMatrix({ x: 0, y: 0 }, ulMatrix); top_left.x += x; top_left.y += y; var top_right = applyMatrix({ x: bboxWidth, y: 0 }, ulMatrix); top_right.x += x; top_right.y += y; var bottom_left = applyMatrix({ x: 0, y: bboxHeight }, ulMatrix); bottom_left.x += x; bottom_left.y += y; var bottom_right = applyMatrix({ x: bboxWidth, y: bboxHeight }, ulMatrix); bottom_right.x += x; bottom_right.y += y; /** step2:根据旋转后的画布位置重新计算包围盒,以免图形进行旋转后上下颠倒 */ var points = [top_left, top_right, bottom_left, bottom_right]; points.sort(function (a, b) { return a.y - b.y; }); var minY = points[0].y; var maxY = points[points.length - 1].y; var tops = [points[0], points[1]]; var bottoms = [points[2], points[3]]; var topLeft = tops[0].x < tops[1].x ? tops[0] : tops[1]; var topRight = tops[0].x < tops[1].x ? tops[1] : tops[0]; var bottomLeft = bottoms[0].x < bottoms[1].x ? bottoms[0] : bottoms[1]; var bottomRight = bottoms[0].x < bottoms[1].x ? bottoms[1] : bottoms[0]; points.sort(function (a, b) { return a.x - b.x; }); var minX = points[0].x; var maxX = points[points.length - 1].x; var node = { width: maxX - minX, height: maxY - minY, left: minX, right: maxX, top: minY, bottom: maxY, topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight, centerX: minX + (maxX - minX) / 2, centerY: minY + (maxY - minY) / 2, }; return node; } exports.bboxOnRotate = bboxOnRotate; /** * 线简化算法 */ var THRESHOLD = 2; function lineSimplification(points) { if (points.length < 5) { return points; } return DouglasPeucker(points, THRESHOLD); } exports.lineSimplification = lineSimplification; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm function DouglasPeucker(points, threshold) { var result; var max = -Infinity; var index = 0; var endIndex = points.length - 1; for (var i = 1; i < endIndex; i++) { var point = points[i]; var line = { start: points[0], end: points[endIndex] }; var dist = distBetweenPointLine(point, line.start, line.end); if (dist > max) { max = dist; index = i; } } if (max > threshold) { var list1 = DouglasPeucker(points.slice(0, index + 1), threshold); var list2 = DouglasPeucker(points.slice(index, points.length), threshold); result = list1.concat(list2); } else { result = [points[0], points[points.length - 1]]; } return result; } /** 统计的以后迁出去,暂时先放这里 */ function getMedian(array) { var list = _.clone(array); list.sort(function (a, b) { return a - b; }); var half = Math.floor(list.length / 2); if (list.length % 2) { return list[half]; } return (list[half - 1] + list[half]) / 2.0; } exports.getMedian = getMedian; function getMean(array) { var sum = 0; _.each(array, function (num) { sum += num; }); return sum / array.length; } exports.getMean = getMean; function sturges(values) { return Math.ceil(Math.log(values.length) / Math.LN2) + 1; } exports.sturges = sturges; //# sourceMappingURL=math.js.map