export function getRotatedRectIntersect()

in src/helpers/intersect-helpers.js [7:104]


export function getRotatedRectIntersect(
  defSvgRotatedRectElement: any,
  src: any,
  trg: any,
  includesArrow: boolean,
  viewWrapperElem: HTMLDivElement
) {
  const response = getDefaultIntersectResponse();
  const arrowSize = getArrowSize(viewWrapperElem);
  const clientRect = defSvgRotatedRectElement.getBoundingClientRect();

  const widthAttr = defSvgRotatedRectElement.getAttribute('width');
  const heightAttr = defSvgRotatedRectElement.getAttribute('height');
  const w = widthAttr ? parseFloat(widthAttr) : clientRect.width;
  const h = heightAttr ? parseFloat(heightAttr) : clientRect.height;
  const trgX = trg.x || 0;
  const trgY = trg.y || 0;
  const srcX = src.x || 0;
  const srcY = src.y || 0;

  const top = trgY - h / 2;
  const bottom = trgY + h / 2;
  const left = trgX - w / 2;
  const right = trgX + w / 2;

  const line = shape('line', { x1: srcX, y1: srcY, x2: trgX, y2: trgY });

  // define rectangle
  const rect = {
    topLeft: new Point2D(left, top),
    bottomRight: new Point2D(right, bottom),
  };

  // convert rectangle corners to polygon (list of points)
  const poly = [
    rect.topLeft,
    new Point2D(rect.bottomRight.x, rect.topLeft.y),
    rect.bottomRight,
    new Point2D(rect.topLeft.x, rect.bottomRight.y),
  ];

  // find center point of rectangle
  const center = rect.topLeft.lerp(rect.bottomRight, 0.5);

  // get the rotation
  const transform = defSvgRotatedRectElement.getAttribute('transform');
  let rotate = transform
    ? transform.replace(/(rotate.[0-9]*.)|[^]/g, '$1')
    : null;
  let angle = 0;

  if (rotate) {
    // get the number
    rotate = rotate.replace(/^rotate\(|\)$/g, '');
    // define rotation in radians
    angle = (parseFloat(rotate) * Math.PI) / 180.0;
  }

  // create matrix for rotating around center of rectangle
  const rotation = Matrix2D.rotationAt(angle, center);
  // create new rotated polygon
  const rotatedPoly = poly.map(p => p.transform(rotation));

  // find intersections
  const pathIntersect = Intersection.intersectLinePolygon(
    line.params[0],
    line.params[1],
    rotatedPoly
  );

  if (pathIntersect.points.length > 0) {
    let arrowWidth = 0; //arrowSize.width;
    let arrowHeight = 0; //arrowSize.height;
    const xIntersect = pathIntersect.points[0].x;
    const yIntersect = pathIntersect.points[0].y;

    if (xIntersect > left && xIntersect < right && yIntersect > trgY) {
      // arrow points to the bottom of the node
      arrowHeight = arrowSize.height;
    } else if (xIntersect > left && xIntersect < right && yIntersect < trgY) {
      // arrow points to the top of the node
      arrowHeight = -arrowSize.height;
    } else if (yIntersect > top && yIntersect < bottom && xIntersect < trgX) {
      // arrow points to the left of the node
      arrowWidth = -arrowSize.width;
    } else {
      // arrow points to the right of the node
      arrowWidth = arrowSize.width;
    }

    response.xOff = trgX - xIntersect - (includesArrow ? arrowWidth / 1.25 : 0);
    response.yOff =
      trgY - yIntersect - (includesArrow ? arrowHeight / 1.25 : 0);
    response.intersect = pathIntersect.points[0];
  }

  return response;
}