0

I hate to ask other people on questions like this, but I'm not a trig expert and I need a little help with calculating some positions for line intersects.

Using Javascript and a set of known rectangular nodes with some known width and height (x and y positions of nodes represent the center of each node), I would like to calculate the line offsets for the line's start and end points such that the line only touches the edge of the nodes.

[_____]---->[_____]

The ascii art above shows 2 rectangular nodes with an arrow between. The arrow doesn't intersect the nodes at either the start or the end. This is easy to calculate assuming the line will always be horizontal or vertical, however if the line is at an angle then I'd still like the line to only touch the edges.

Assume the ascii art below has an arrow pointed at the target node (denoted by the pipe symbol)

[_____]
    \
     \|
   [______]

Known variables:

  • Source (1): {x, y, w, h}
  • Target (2): {x, y, w, h}
  • Theta of line (Math.atan(y2-y1, x2-x1))

Desired output:

  • Point of intersection on source node
  • Point of intersection on target node

Example:

{
    sourceIntersect: {x, y}, 
    targetIntersect: {x, y}
}
Allan Bogh
  • 605
  • 8
  • 15
  • You'd need to know where the line is (point on the line)... – Eric Aug 31 '18 at 23:52
  • https://stackoverflow.com/questions/1343346/calculate-a-vector-from-the-center-of-a-square-to-edge-based-on-radius – Maciej Kwas Sep 01 '18 at 01:19
  • Check how to calculate the minimal distance between a line and a point, there are many ways. Then since you know the arrow's start and end positions you can calculate whether (distance>tolerance or distance – macroland Sep 01 '18 at 06:04

1 Answers1

0

I found that there's a tool that can calculate the intersection of two lines. If I treated the rectangle as a set of 4 lines I can use the line-intersect npm project to get the point of intersection on one of those 4 lines. The solution was found in the SO question below.

calculating the point of intersection of two lines

This is an example of my code:

// first, get the sizes of the element.
// here we use getBoundingClientRect for an SVG
const clientRect = svgRectElement.getBoundingClientRect();

// extract the width and height
const w = clientRect.width;
const h = clientRect.height;

// trg represents the target point from the element above
// the x and y for trg relate to the center of the element
const top = trg.y - h / 2;
const bottom = trg.y + h / 2;
const left = trg.x - w / 2;
const right = trg.x + w / 2;

// a line extends from src{x,y} to trg{x,y} at the center of both rectangles

// another line extends from left to right at the top of the rectangle   
const topIntersect = lineIntersect.checkIntersection(src.x, src.y, trg.x, trg.y, left, top, right, top);

// another line extends from top to bottom at the right of the rectangle
const rightIntersect = lineIntersect.checkIntersection(src.x, src.y, trg.x, trg.y, right, top, right, bottom);

// another line extends from left to right at the bottom of the rectangle
const bottomIntersect = lineIntersect.checkIntersection(src.x, src.y, trg.x, trg.y, left, bottom, right, bottom);

// another line extends from top to bottom at the left of the rectangle
const leftIntersect = lineIntersect.checkIntersection(src.x, src.y, trg.x, trg.y, left, top, left, bottom);

// only one of the intersect variables above will have a value
if (topIntersect.type !== 'none' && topIntersect.point != null) {
  // topIntersect.point is the x,y of the line intersection with the top of the rectangle
} else if (rightIntersect.type !== 'none' && rightIntersect.point != null) {
  // rightIntersect.point is the x,y of the line intersection with the right of the rectangle
} else if (bottomIntersect.type !== 'none' && bottomIntersect.point != null) {
  // bottomIntersect.point is the x,y of the line intersection with the bottom of the rectangle
} else if (leftIntersect.type !== 'none' && leftIntersect.point != null) {
  // leftIntersect.point is the x,y of the line intersection with the left of the rectangle
}

To get the intersection of the source node I would pass that as the trg parameter to my function and the target node would represent the src parameter, essentially tricking the system into thinking the line is drawn backwards. This would provide the intersection of the source node, which is represented in the variable trg above.

Allan Bogh
  • 605
  • 8
  • 15