使用JS计算两个矩形节点之间的直线相交偏移量
Using JS calculate the line intersection offset between two rectangular nodes
我不想问别人这样的问题,但我不是三角专家,我需要一些帮助来计算线相交的一些位置。
使用Javascript和一组具有已知宽度和高度的已知矩形节点(节点的x和y位置代表每个节点的中心),我想计算线的线偏移起点和终点,使直线仅接触节点的边缘。
[_____]---->[_____]
上面的 ascii 艺术显示了 2 个矩形节点,中间有一个箭头。箭头不与起点或终点处的节点相交。假设这条线总是水平或垂直的,这很容易计算,但是如果这条线是一个角度,那么我仍然希望这条线只接触边缘。
假设下面的 ascii 艺术有一个指向目标节点的箭头(用管道符号表示)
[_____]
\
\|
[______]
已知变量:
- 来源 (1):{x, y, w, h}
- 目标 (2):{x, y, w, h}
- 线的 Theta (Math.atan(y2-y1, x2-x1))
期望的输出:
- 源节点上的交点
- 目标节点上的交点
示例:
{
sourceIntersect: {x, y},
targetIntersect: {x, y}
}
我发现有一个工具可以计算两条线的交点。如果我将矩形视为一组 4 条线,我可以使用 line-intersect npm 项目来获取这 4 条线之一的交点。在下面的 SO 问题中找到了解决方案。
calculating the point of intersection of two lines
这是我的代码示例:
// 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
}
为了获得源节点的交集,我会将其作为 trg
参数传递给我的函数,而目标节点将代表 src
参数,本质上是欺骗系统认为这条线被向后拉。这将提供源节点的交集,在上面的变量 trg
中表示。
我不想问别人这样的问题,但我不是三角专家,我需要一些帮助来计算线相交的一些位置。
使用Javascript和一组具有已知宽度和高度的已知矩形节点(节点的x和y位置代表每个节点的中心),我想计算线的线偏移起点和终点,使直线仅接触节点的边缘。
[_____]---->[_____]
上面的 ascii 艺术显示了 2 个矩形节点,中间有一个箭头。箭头不与起点或终点处的节点相交。假设这条线总是水平或垂直的,这很容易计算,但是如果这条线是一个角度,那么我仍然希望这条线只接触边缘。
假设下面的 ascii 艺术有一个指向目标节点的箭头(用管道符号表示)
[_____]
\
\|
[______]
已知变量:
- 来源 (1):{x, y, w, h}
- 目标 (2):{x, y, w, h}
- 线的 Theta (Math.atan(y2-y1, x2-x1))
期望的输出:
- 源节点上的交点
- 目标节点上的交点
示例:
{
sourceIntersect: {x, y},
targetIntersect: {x, y}
}
我发现有一个工具可以计算两条线的交点。如果我将矩形视为一组 4 条线,我可以使用 line-intersect npm 项目来获取这 4 条线之一的交点。在下面的 SO 问题中找到了解决方案。
calculating the point of intersection of two lines
这是我的代码示例:
// 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
}
为了获得源节点的交集,我会将其作为 trg
参数传递给我的函数,而目标节点将代表 src
参数,本质上是欺骗系统认为这条线被向后拉。这将提供源节点的交集,在上面的变量 trg
中表示。