我试图计算两个段的交点。每个段都是垂直或水平(0°,90°,180°,270°)。如果两个段都是垂直或水平的,我还需要计算交点。
function intersection(line1, line2) {
var origin1x = Math.min(line1.getStartPosition().x, line1.getEndPosition().x);
var origin1y = Math.min(line1.getStartPosition().y, line1.getEndPosition().y);
var origin2x = Math.min(line2.getStartPosition().x, line2.getEndPosition().x);
var origin2y = Math.min(line2.getStartPosition().y, line2.getEndPosition().y);
var dx = origin2x - origin1x;
var dy = origin2y - origin1y;
if((line1.isHorizontal() && (dx < 0 || dx > line2.getLength())) || (!line1.isHorizontal() && (dy < 0 || dy > line1.getLength()))) {
return null;
}
return {
x: line1.isHorizontal() ? origin1x + dx : origin1x,
y: !line2.isHorizontal() ? origin2y - dy : origin2y
}
}
代码在某些情况下运行良好,但有时会失败。
例如:
line1 = ((0, 50), (0, 30)) // ((startX, startY), (endX, endY))
line2 = ((0, 0), (0, 30))
shouldBe = (0, 30)
谢谢。
答案 0 :(得分:2)
以下是解决此问题的一种方法:
使用y = m1x + c1
和y = m2x + c2
编写两行的等式。请注意特殊情况:如果一条线是水平的,那么它具有等式y = c
,如果是垂直的则它具有等式x = c
(在最后一种情况下c
实际上是截止点x
轴,但代数仍能很好地运作。)
使用第一行提供的顶点求解系数m1
和c1
,使用第二行的顶点对m2
和c2
进行求解。
一旦得到这些方程,交点就是两个联立方程的解,它将根据计算出的系数给出x
和y
的值。
请注意,这适用于线的任何非平行排列。 (对于并行情况,联立方程将是彼此的线性倍数,因此不会产生解决方案。)
一些代数,但你应该能够突然想到它。
答案 1 :(得分:1)
由于线条总是水平或垂直,因此它们与轴对齐的边界框完全相同。因此,我们可以简单地使用边界框交叉算法,而不是使用线交叉算法,就像这个伪代码一样:
# get the minimum and maximum x and y coordinates of each region
# (this part can be skipped if you know the coordinates are sorted already)
(xmin1, xmax1) = sort(region1.start.x, region1.end.x)
(ymin1, ymax1) = sort(region1.start.y, region1.end.y)
(xmin2, xmax2) = sort(region2.start.x, region2.end.x)
(ymin2, ymax2) = sort(region2.start.y, region2.end.y)
# get the maximum of the minimums and the minimum of the maximums
xmin = max(xmin1, xmin2), xmax = min(xmax1, xmax2)
ymin = max(ymin1, ymin2), ymax = min(ymax1, ymax2)
# check if there is any overlap
if xmin > xmax or ymin > ymax:
raise error("the regions do not intersect")
else:
return new region( start=(xmin, ymin), end=(xmax, ymax) )
请注意,此代码返回一个新的边界框,覆盖两个区域重叠的整个区域。即使对于水平/垂直线的区域,如果两条线具有相同的方向并且在一系列点上重叠,则该区域可能包含多个点。如果您只需要一个点,您可以随时选择重叠区域的中点。