Spaces:
Running
Running
| /** | |
| * INTERSEC | |
| ********************************************************* | |
| * @licstart The following is the entire license notice for the | |
| * JavaScript code in this page. | |
| * | |
| * Copyright (C) 2021 Ophir LOJKINE | |
| * | |
| * | |
| * The JavaScript code in this page is free software: you can | |
| * redistribute it and/or modify it under the terms of the GNU | |
| * General Public License (GNU GPL) as published by the Free Software | |
| * Foundation, either version 3 of the License, or (at your option) | |
| * any later version. The code is distributed WITHOUT ANY WARRANTY; | |
| * without even the implied warranty of MERCHANTABILITY or FITNESS | |
| * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
| * | |
| * As additional permission under GNU GPL version 3 section 7, you | |
| * may distribute non-source (e.g., minimized or compacted) forms of | |
| * that code without the copy of the GNU GPL normally required by | |
| * section 4, provided you include this license notice and a URL | |
| * through which recipients can access the Corresponding Source. | |
| * | |
| * @licend | |
| */ | |
| if ( | |
| !SVGGraphicsElement.prototype.transformedBBox || | |
| !SVGGraphicsElement.prototype.transformedBBoxContains | |
| ) { | |
| [pointInTransformedBBox, transformedBBoxIntersects] = (function () { | |
| var get_transform_matrix = function (elem) { | |
| // Returns the first translate or transform matrix or makes one | |
| var transform = null; | |
| for (var i = 0; i < elem.transform.baseVal.numberOfItems; ++i) { | |
| var baseVal = elem.transform.baseVal[i]; | |
| // quick tests showed that even if one changes only the fields e and f or uses createSVGTransformFromMatrix | |
| // the brower may add a SVG_TRANSFORM_MATRIX instead of a SVG_TRANSFORM_TRANSLATE | |
| if (baseVal.type === SVGTransform.SVG_TRANSFORM_MATRIX) { | |
| transform = baseVal; | |
| break; | |
| } | |
| } | |
| if (transform == null) { | |
| transform = elem.transform.baseVal.createSVGTransformFromMatrix( | |
| Tools.svg.createSVGMatrix(), | |
| ); | |
| elem.transform.baseVal.appendItem(transform); | |
| } | |
| return transform.matrix; | |
| }; | |
| var transformRelative = function (m, t) { | |
| return [m.a * t[0] + m.c * t[1], m.b * t[0] + m.d * t[1]]; | |
| }; | |
| var transformAbsolute = function (m, t) { | |
| return [m.a * t[0] + m.c * t[1] + m.e, m.b * t[0] + m.d * t[1] + m.f]; | |
| }; | |
| SVGGraphicsElement.prototype.transformedBBox = function (scale = 1) { | |
| bbox = this.getBBox(); | |
| tmatrix = get_transform_matrix(this); | |
| tmatrix.e /= scale; | |
| tmatrix.f /= scale; | |
| return { | |
| r: transformAbsolute(tmatrix, [bbox.x / scale, bbox.y / scale]), | |
| a: transformRelative(tmatrix, [bbox.width / scale, 0]), | |
| b: transformRelative(tmatrix, [0, bbox.height / scale]), | |
| }; | |
| }; | |
| SVGSVGElement.prototype.transformedBBox = function (scale = 1) { | |
| bbox = { | |
| x: this.x.baseVal.value, | |
| y: this.y.baseVal.value, | |
| width: this.width.baseVal.value, | |
| height: this.height.baseVal.value, | |
| }; | |
| tmatrix = get_transform_matrix(this); | |
| tmatrix.e /= scale; | |
| tmatrix.f /= scale; | |
| return { | |
| r: transformAbsolute(tmatrix, [bbox.x / scale, bbox.y / scale]), | |
| a: transformRelative(tmatrix, [bbox.width / scale, 0]), | |
| b: transformRelative(tmatrix, [0, bbox.height / scale]), | |
| }; | |
| }; | |
| var pointInTransformedBBox = function ([x, y], { r, a, b }) { | |
| var d = [x - r[0], y - r[1]]; | |
| var idet = a[0] * b[1] - a[1] * b[0]; | |
| var c1 = (d[0] * b[1] - d[1] * b[0]) / idet; | |
| var c2 = (d[1] * a[0] - d[0] * a[1]) / idet; | |
| return c1 >= 0 && c1 <= 1 && c2 >= 0 && c2 <= 1; | |
| }; | |
| SVGGraphicsElement.prototype.transformedBBoxContains = function (x, y) { | |
| return pointInTransformedBBox([x, y], this.transformedBBox()); | |
| }; | |
| function transformedBBoxIntersects(bbox_a, bbox_b) { | |
| var corners = [ | |
| bbox_b.r, | |
| [bbox_b.r[0] + bbox_b.a[0], bbox_b.r[1] + bbox_b.a[1]], | |
| [bbox_b.r[0] + bbox_b.b[0], bbox_b.r[1] + bbox_b.b[1]], | |
| [ | |
| bbox_b.r[0] + bbox_b.a[0] + bbox_b.b[0], | |
| bbox_b.r[1] + bbox_b.a[1] + bbox_b.b[1], | |
| ], | |
| ]; | |
| return corners.every(function (corner) { | |
| return pointInTransformedBBox(corner, bbox_a); | |
| }); | |
| } | |
| SVGGraphicsElement.prototype.transformedBBoxIntersects = function (bbox) { | |
| return transformedBBoxIntersects(this.transformedBBox(), bbox); | |
| }; | |
| return [pointInTransformedBBox, transformedBBoxIntersects]; | |
| })(); | |
| } | |