You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * INTERSEC
  3. *********************************************************
  4. * @licstart The following is the entire license notice for the
  5. * JavaScript code in this page.
  6. *
  7. * Copyright (C) 2021 Ophir LOJKINE
  8. *
  9. *
  10. * The JavaScript code in this page is free software: you can
  11. * redistribute it and/or modify it under the terms of the GNU
  12. * General Public License (GNU GPL) as published by the Free Software
  13. * Foundation, either version 3 of the License, or (at your option)
  14. * any later version. The code is distributed WITHOUT ANY WARRANTY;
  15. * without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  17. *
  18. * As additional permission under GNU GPL version 3 section 7, you
  19. * may distribute non-source (e.g., minimized or compacted) forms of
  20. * that code without the copy of the GNU GPL normally required by
  21. * section 4, provided you include this license notice and a URL
  22. * through which recipients can access the Corresponding Source.
  23. *
  24. * @licend
  25. */
  26. if (!SVGGraphicsElement.prototype.transformedBBox || !SVGGraphicsElement.prototype.transformedBBoxContains) {
  27. [pointInTransformedBBox,
  28. transformedBBoxIntersects] = (function () {
  29. var get_transform_matrix = function (elem) {
  30. // Returns the first translate or transform matrix or makes one
  31. var transform = null;
  32. for (var i = 0; i < elem.transform.baseVal.numberOfItems; ++i) {
  33. var baseVal = elem.transform.baseVal[i];
  34. // quick tests showed that even if one changes only the fields e and f or uses createSVGTransformFromMatrix
  35. // the brower may add a SVG_TRANSFORM_MATRIX instead of a SVG_TRANSFORM_TRANSLATE
  36. if (baseVal.type === SVGTransform.SVG_TRANSFORM_MATRIX) {
  37. transform = baseVal;
  38. break;
  39. }
  40. }
  41. if (transform == null) {
  42. transform = elem.transform.baseVal.createSVGTransformFromMatrix(Tools.svg.createSVGMatrix());
  43. elem.transform.baseVal.appendItem(transform);
  44. }
  45. return transform.matrix;
  46. }
  47. var transformRelative = function (m,t) {
  48. return [
  49. m.a*t[0]+m.c*t[1],
  50. m.b*t[0]+m.d*t[1]
  51. ]
  52. }
  53. var transformAbsolute = function (m,t) {
  54. return [
  55. m.a*t[0]+m.c*t[1]+m.e,
  56. m.b*t[0]+m.d*t[1]+m.f
  57. ]
  58. }
  59. SVGGraphicsElement.prototype.transformedBBox = function (scale=1) {
  60. bbox = this.getBBox();
  61. tmatrix = get_transform_matrix(this);
  62. tmatrix.e /= scale;
  63. tmatrix.f /= scale;
  64. return {
  65. r: transformAbsolute(tmatrix,[bbox.x/scale,bbox.y/scale]),
  66. a: transformRelative(tmatrix,[bbox.width/scale,0]),
  67. b: transformRelative(tmatrix,[0,bbox.height/scale])
  68. }
  69. }
  70. SVGSVGElement.prototype.transformedBBox = function (scale=1) {
  71. bbox = {
  72. x: this.x.baseVal.value,
  73. y: this.y.baseVal.value,
  74. width: this.width.baseVal.value,
  75. height: this.height.baseVal.value
  76. };
  77. tmatrix = get_transform_matrix(this);
  78. tmatrix.e /= scale;
  79. tmatrix.f /= scale;
  80. return {
  81. r: transformAbsolute(tmatrix,[bbox.x/scale,bbox.y/scale]),
  82. a: transformRelative(tmatrix,[bbox.width/scale,0]),
  83. b: transformRelative(tmatrix,[0,bbox.height/scale])
  84. }
  85. }
  86. var pointInTransformedBBox = function ([x,y],{r,a,b}) {
  87. var d = [x-r[0],y-r[1]];
  88. var idet = (a[0]*b[1]-a[1]*b[0]);
  89. var c1 = (d[0]*b[1]-d[1]*b[0]) / idet;
  90. var c2 = (d[1]*a[0]-d[0]*a[1]) / idet;
  91. return (c1>=0 && c1<=1 && c2>=0 && c2<=1)
  92. }
  93. SVGGraphicsElement.prototype.transformedBBoxContains = function (x,y) {
  94. return pointInTransformedBBox([x, y], this.transformedBBox())
  95. }
  96. function transformedBBoxIntersects(bbox_a,bbox_b) {
  97. var corners = [
  98. bbox_b.r,
  99. [bbox_b.r[0] + bbox_b.a[0], bbox_b.r[1] + bbox_b.a[1]],
  100. [bbox_b.r[0] + bbox_b.b[0], bbox_b.r[1] + bbox_b.b[1]],
  101. [bbox_b.r[0] + bbox_b.a[0] + bbox_b.b[0], bbox_b.r[1] + bbox_b.a[1] + bbox_b.b[1]]
  102. ]
  103. return corners.every(function(corner) {
  104. return pointInTransformedBBox(corner, bbox_a);
  105. })
  106. }
  107. SVGGraphicsElement.prototype.transformedBBoxIntersects= function (bbox) {
  108. return transformedBBoxIntersects(this.transformedBBox(),bbox)
  109. }
  110. return [pointInTransformedBBox,
  111. transformedBBoxIntersects]
  112. })();
  113. }