UNPKG

ag-grid-enterprise

Version:

AG Grid Enterprise Features

151 lines 5.92 kB
"use strict"; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.arcIntersections = exports.cubicSegmentIntersections = exports.segmentIntersection = void 0; var angle_1 = require("../util/angle"); var polyRoots_1 = require("./polyRoots"); /** * Returns the intersection point for the given pair of line segments, or null, * if the segments are parallel or don't intersect. * Based on http://paulbourke.net/geometry/pointlineplane/ */ function segmentIntersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) { var d = (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1); if (d === 0) { // The lines are parallel. return null; } var ua = ((bx2 - bx1) * (ay1 - by1) - (ax1 - bx1) * (by2 - by1)) / d; var ub = ((ax2 - ax1) * (ay1 - by1) - (ay2 - ay1) * (ax1 - bx1)) / d; if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) { return { x: ax1 + ua * (ax2 - ax1), y: ay1 + ua * (ay2 - ay1), }; } return null; // The intersection point is outside either or both segments. } exports.segmentIntersection = segmentIntersection; /** * Returns intersection points of the given cubic curve and the line segment. * Takes in x/y components of cubic control points and line segment start/end points * as parameters. */ function cubicSegmentIntersections(px1, py1, px2, py2, px3, py3, px4, py4, x1, y1, x2, y2) { var e_1, _a; var intersections = []; // Find line equation coefficients. var A = y1 - y2; var B = x2 - x1; var C = x1 * (y2 - y1) - y1 * (x2 - x1); // Find cubic Bezier curve equation coefficients from control points. var bx = bezierCoefficients(px1, px2, px3, px4); var by = bezierCoefficients(py1, py2, py3, py4); var a = A * bx[0] + B * by[0]; // t^3 var b = A * bx[1] + B * by[1]; // t^2 var c = A * bx[2] + B * by[2]; // t var d = A * bx[3] + B * by[3] + C; // 1 var roots = polyRoots_1.cubicRoots(a, b, c, d); try { // Verify that the roots are within bounds of the linear segment. for (var roots_1 = __values(roots), roots_1_1 = roots_1.next(); !roots_1_1.done; roots_1_1 = roots_1.next()) { var t = roots_1_1.value; var tt = t * t; var ttt = t * tt; // Find the cartesian plane coordinates for the parametric root `t`. var x = bx[0] * ttt + bx[1] * tt + bx[2] * t + bx[3]; var y = by[0] * ttt + by[1] * tt + by[2] * t + by[3]; // The parametric cubic roots we found are intersection points // with an infinite line, and so the x/y coordinates above are as well. // Make sure the x/y is also within the bounds of the given segment. var s = void 0; if (x1 !== x2) { s = (x - x1) / (x2 - x1); } else { // the line is vertical s = (y - y1) / (y2 - y1); } if (s >= 0 && s <= 1) { intersections.push({ x: x, y: y }); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (roots_1_1 && !roots_1_1.done && (_a = roots_1.return)) _a.call(roots_1); } finally { if (e_1) throw e_1.error; } } return intersections; } exports.cubicSegmentIntersections = cubicSegmentIntersections; /** * Returns the given coordinates vector multiplied by the coefficient matrix * of the parametric cubic Bézier equation. */ function bezierCoefficients(P1, P2, P3, P4) { return [ // Bézier expressed as matrix operations: -P1 + 3 * P2 - 3 * P3 + P4, 3 * P1 - 6 * P2 + 3 * P3, -3 * P1 + 3 * P2, P1, // | 1 0 0 0| |P4| ]; } /** * Returns intersection points of the arc and the line segment. * Takes in arc parameters and line segment start/end points. */ function arcIntersections(cx, cy, r, startAngle, endAngle, counterClockwise, x1, y1, x2, y2) { // Solving the quadratic equation: // 1. y = k * x + y0 // 2. (x - cx)^2 + (y - cy)^2 = r^2 var k = (y2 - y1) / (x2 - x1); var y0 = y1 - k * x1; var a = Math.pow(k, 2) + 1; var b = 2 * (k * (y0 - cy) - cx); var c = Math.pow(cx, 2) + Math.pow(y0 - cy, 2) - Math.pow(r, 2); var d = Math.pow(b, 2) - 4 * a * c; if (d < 0) { return []; } var i1x = (-b + Math.sqrt(d)) / 2 / a; var i2x = (-b - Math.sqrt(d)) / 2 / a; var intersections = []; [i1x, i2x].forEach(function (x) { var isXInsideLine = x >= Math.min(x1, x2) && x <= Math.max(x1, x2); if (!isXInsideLine) { return; } var y = k * x; var a1 = angle_1.normalizeAngle360(counterClockwise ? endAngle : startAngle); var a2 = angle_1.normalizeAngle360(counterClockwise ? startAngle : endAngle); var intersectionAngle = angle_1.normalizeAngle360(Math.atan2(y, x)); // Order angles clockwise after the start angle // (end angle if counter-clockwise) if (a2 <= a1) { a2 += 2 * Math.PI; } if (intersectionAngle < a1) { intersectionAngle += 2 * Math.PI; } if (intersectionAngle >= a1 && intersectionAngle <= a2) { intersections.push({ x: x, y: y }); } }); return intersections; } exports.arcIntersections = arcIntersections; //# sourceMappingURL=intersection.js.map