edge.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.isNodeInSegment = exports.crossPointInSegment = exports.distToSegment = exports.distToSegmentSquared = exports.isInSegment = void 0;
  4. // 这个里面的函数有些在core中已经存在,为了解耦关系,没有引用
  5. var SegmentDirection;
  6. (function (SegmentDirection) {
  7. SegmentDirection["HORIZONTAL"] = "horizontal";
  8. SegmentDirection["VERTICAL"] = "vertical";
  9. })(SegmentDirection || (SegmentDirection = {}));
  10. /**
  11. * 判断一个点是否在线段中
  12. * @param point 判断的点
  13. * @param start 线段的起点
  14. * @param end 线段的终点
  15. * @param deviation 误差范围
  16. * @returns boolean
  17. */
  18. exports.isInSegment = function (point, start, end, deviation) {
  19. if (deviation === void 0) { deviation = 0; }
  20. var distance = exports.distToSegment(point, start, end);
  21. return distance <= deviation;
  22. };
  23. function sqr(x) {
  24. return x * x;
  25. }
  26. function dist2(v, w) {
  27. return sqr(v.x - w.x) + sqr(v.y - w.y);
  28. }
  29. exports.distToSegmentSquared = function (p, v, w) {
  30. var l2 = dist2(v, w);
  31. if (l2 === 0)
  32. return dist2(p, v);
  33. var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
  34. t = Math.max(0, Math.min(1, t));
  35. return dist2(p, {
  36. x: v.x + t * (w.x - v.x),
  37. y: v.y + t * (w.y - v.y),
  38. });
  39. };
  40. exports.distToSegment = function (point, start, end) { return Math.sqrt(exports.distToSegmentSquared(point, start, end)); };
  41. /* 获取节点bbox */
  42. var getNodeBBox = function (node) {
  43. var x = node.x, y = node.y, width = node.width, height = node.height;
  44. var bBox = {
  45. minX: x - width / 2,
  46. minY: y - height / 2,
  47. maxX: x + width / 2,
  48. maxY: y + height / 2,
  49. x: x,
  50. y: y,
  51. width: width,
  52. height: height,
  53. centerX: x,
  54. centerY: y,
  55. };
  56. return bBox;
  57. };
  58. /* 判断线段的方向 */
  59. var segmentDirection = function (start, end) {
  60. var direction;
  61. if (start.x === end.x) {
  62. direction = SegmentDirection.VERTICAL;
  63. }
  64. else if (start.y === end.y) {
  65. direction = SegmentDirection.HORIZONTAL;
  66. }
  67. return direction;
  68. };
  69. // 节点是够在线段内,求出节点与线段的交点
  70. exports.crossPointInSegment = function (node, start, end) {
  71. var bBox = getNodeBBox(node);
  72. var direction = segmentDirection(start, end);
  73. var maxX = Math.max(start.x, end.x);
  74. var minX = Math.min(start.x, end.x);
  75. var maxY = Math.max(start.y, end.y);
  76. var minY = Math.min(start.y, end.y);
  77. var x = node.x, y = node.y, width = node.width, height = node.height;
  78. if (direction === SegmentDirection.HORIZONTAL) {
  79. // 同一水平线
  80. if (maxX >= bBox.maxX && minX <= bBox.minX) {
  81. return {
  82. startCrossPoint: {
  83. x: start.x > end.x ? x + (width / 2) : x - (width / 2),
  84. y: start.y,
  85. },
  86. endCrossPoint: {
  87. x: start.x > end.x ? x - (width / 2) : x + (width / 2),
  88. y: start.y,
  89. },
  90. };
  91. }
  92. }
  93. else if (direction === SegmentDirection.VERTICAL) {
  94. // 同一垂直线
  95. if (maxY >= bBox.maxY && minY <= bBox.minY) {
  96. return {
  97. startCrossPoint: {
  98. x: start.x,
  99. y: start.y > end.y ? y + (height / 2) : y - (height / 2),
  100. },
  101. endCrossPoint: {
  102. x: start.x,
  103. y: start.y > end.y ? y - (height / 2) : y + (height / 2),
  104. },
  105. };
  106. }
  107. }
  108. };
  109. // 节点是否在线段内
  110. // eslint-disable-next-line max-len
  111. exports.isNodeInSegment = function (node, polyline, deviation) {
  112. if (deviation === void 0) { deviation = 0; }
  113. var x = node.x, y = node.y;
  114. var pointsList = polyline.pointsList;
  115. for (var i = 0; i < pointsList.length - 1; i++) {
  116. if (exports.isInSegment({ x: x, y: y }, pointsList[i], pointsList[i + 1], deviation)) {
  117. var bBoxCross = exports.crossPointInSegment(node, pointsList[i], pointsList[i + 1]);
  118. if (bBoxCross) {
  119. return {
  120. crossIndex: i + 1,
  121. crossPoints: bBoxCross,
  122. };
  123. }
  124. }
  125. }
  126. return {
  127. crossIndex: -1,
  128. crossPoints: {
  129. startCrossPoint: { x: 0, y: 0 },
  130. endCrossPoint: { x: 0, y: 0 },
  131. },
  132. };
  133. };