vis.js is a dynamic, browser-based visualization library
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.

115 lines
3.0 KiB

  1. /**
  2. * Created by Alex on 3/20/2015.
  3. */
  4. import BaseEdge from './baseEdge'
  5. class BezierBaseEdge extends BaseEdge {
  6. constructor(options, body, labelModule) {
  7. super(options, body, labelModule);
  8. }
  9. /**
  10. * This function uses binary search to look for the point where the bezier curve crosses the border of the node.
  11. *
  12. * @param nearNode
  13. * @param ctx
  14. * @param viaNode
  15. * @param nearNode
  16. * @param ctx
  17. * @param viaNode
  18. * @param nearNode
  19. * @param ctx
  20. * @param viaNode
  21. */
  22. _findBorderPositionBezier(nearNode, ctx, viaNode = this._getViaCoordinates()) {
  23. console.log(nearNode, ctx, viaNode)
  24. var maxIterations = 10;
  25. var iteration = 0;
  26. var low = 0;
  27. var high = 1;
  28. var pos, angle, distanceToBorder, distanceToPoint, difference;
  29. var threshold = 0.2;
  30. var node = this.to;
  31. var from = false;
  32. if (nearNode.id === this.from.id) {
  33. node = this.from;
  34. from = true;
  35. }
  36. while (low <= high && iteration < maxIterations) {
  37. var middle = (low + high) * 0.5;
  38. pos = this.getPoint(middle, viaNode);
  39. angle = Math.atan2((node.y - pos.y), (node.x - pos.x));
  40. distanceToBorder = node.distanceToBorder(ctx, angle);
  41. distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2));
  42. difference = distanceToBorder - distanceToPoint;
  43. console.log(pos, difference, middle)
  44. if (Math.abs(difference) < threshold) {
  45. break; // found
  46. }
  47. else if (difference < 0) { // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
  48. if (from == false) {
  49. low = middle;
  50. }
  51. else {
  52. high = middle;
  53. }
  54. }
  55. else {
  56. if (from == false) {
  57. high = middle;
  58. }
  59. else {
  60. low = middle;
  61. }
  62. }
  63. iteration++;
  64. }
  65. pos.t = middle;
  66. return pos;
  67. }
  68. /**
  69. * Calculate the distance between a point (x3,y3) and a line segment from
  70. * (x1,y1) to (x2,y2).
  71. * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
  72. * @param {number} x1
  73. * @param {number} y1
  74. * @param {number} x2
  75. * @param {number} y2
  76. * @param {number} x3
  77. * @param {number} y3
  78. * @private
  79. */
  80. _getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via) { // x3,y3 is the point
  81. let xVia, yVia;
  82. xVia = via.x;
  83. yVia = via.y;
  84. let minDistance = 1e9;
  85. let distance;
  86. let i, t, x, y;
  87. let lastX = x1;
  88. let lastY = y1;
  89. for (i = 1; i < 10; i++) {
  90. t = 0.1 * i;
  91. x = Math.pow(1 - t, 2) * x1 + (2 * t * (1 - t)) * xVia + Math.pow(t, 2) * x2;
  92. y = Math.pow(1 - t, 2) * y1 + (2 * t * (1 - t)) * yVia + Math.pow(t, 2) * y2;
  93. if (i > 0) {
  94. distance = this._getDistanceToLine(lastX, lastY, x, y, x3, y3);
  95. minDistance = distance < minDistance ? distance : minDistance;
  96. }
  97. lastX = x;
  98. lastY = y;
  99. }
  100. return minDistance;
  101. }
  102. }
  103. export default BezierBaseEdge;