一维中两条线段之间最短距离的高效算法

发布于 2024-10-08 04:51:55 字数 801 浏览 5 评论 0原文

我可以找到很多公式来计算两条斜线之间的距离。我想计算一维中两条线段之间的距离。

使用一堆 IF 语句很容易做到。但我想知道它们是否是一个更有效的数学公式。

例如1:

----L1x1-------L2x1-------L1x2------L2x2----------------------------

L1=线段1,L2=线段2; ,这里的距离为 0

由于相交 2:

----L1x1-------L1x2-------L2x1------L2x2----------------------------

这里的距离是L2x1 - L1x2

编辑:

唯一的假设是线段是有序的,即x2总是> x1。

线段 1 可能位于线段 2 的左侧、右侧、等于线段 2 等。算法必须解决这个问题。

编辑2:

我必须在T-SQL (SQL Server 2008) 中实现这一点。我只需要逻辑...我可以编写 T-SQL。

编辑3:

如果一条线段是另一条线的线段,则距离为0。

----L1x1-------L2x1-------L2x2------L1x2----------------------------

线段2是线段1的线段,使得距离为0。

如果它们相交或接触,距离为 0。

I can find plenty formulas for finding the distance between two skew lines. I want to calculate the distance between two line segments in one dimension.

It's easy to do with a bunch of IF statements. But I was wondering if their is a more efficient math formula.

E.g. 1:

----L1x1-------L2x1-------L1x2------L2x2----------------------------

L1 = line segment 1, L2 = line segment 2;
the distance here is 0 because of intersection

E.g. 2:

----L1x1-------L1x2-------L2x1------L2x2----------------------------

the distance here is L2x1 - L1x2

EDIT:

The only assumption is that the line segments are ordered, i.e. x2 is always > x1.

Line segment 1 may be to the left, right, equal to etc. of line segment 2. The algorithm has to solve for this.

EDIT 2:

I have to implement this in T-SQL (SQL Server 2008). I just need the logic... I can write the T-SQL.

EDIT 3:

If a line segment is a line segment of the other line, the distance is 0.

----L1x1-------L2x1-------L2x2------L1x2----------------------------

Line segment 2 is a segment of line segment 1, making the distance 0.

If they intersect or touch, the distance is 0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

◇流星雨 2024-10-15 04:51:55

这个问题与“两个范围是否相交,如果不相交,那么它们之间的距离是多少?”的问题相同。答案稍微取决于您是否已经知道哪个范围最小,以及范围中的点是否排序正确(即,线是否具有相同的方向)。

if (a.start < b.start) {
  first = a;
  second = b;
} else {
  first = b;
  second = a;
}

然后:

distance = max(0, second.start - first.end);

根据您运行它的位置,您的编译器应该很好地优化它。无论如何,您可能应该进行分析以确保您的代码是瓶颈,然后再降低其可读性以提高理论上的性能。

This question is the same as the question "Do two ranges intersect, and if not then what is the distance between them?" The answer depends slightly on whether you already know which range is smallest already, and whether the points in the ranges are ordered correctly (that is, whether the lines have the same direction).

if (a.start < b.start) {
  first = a;
  second = b;
} else {
  first = b;
  second = a;
}

Then:

distance = max(0, second.start - first.end);

Depending on where you're running this, your compiler should optimise it nicely. In any case, you should probably profile to make sure that your code is a bottleneck before making it less readable for a theoretical performance improvement.

情释 2024-10-15 04:51:55

这适用于所有情况:

d = (s1 max s2 - e1 min e2) max 0

作为奖励,删除 max 0 意味着负结果准确指示两个段重叠的程度。

证明

请注意,该算法是对称的,因此非对称情况只需覆盖一次。所以我要断言 s2 >= s1 wlog 另请注意 e1 >= s1 和 e2 >= s2。

情况:

  • L1 结束后开始 L2(s2 >= e1):s1 max s2 = s2,e1 min e2 = e1。结果是 s2 - e1,它是非负数,显然是我们想要的值(距离)。
  • L1 内的 L2(s2 <= e1,e2 <= e1):s1 max s2 = s2,e1 min e2 = e2。 s2 - e2 为非正数,s2 <= e2,因此重叠期间结果如预期为 0。
  • L2 在 L1 内开始,但在 (s2 <= e1, e2 >= e1) 之后结束: s1 max s2 = s2, e1 min e2 = e1。由于 s2 <= e1,s2 - e1 为非正数,因此重叠期间结果如预期为 0。

This works in all cases:

d = (s1 max s2 - e1 min e2) max 0

As a bonus, removing max 0 means a negative result indicates exactly how much of the two segments overlap.

Proof

Note that the algorithm is symmetric, so asymmetric cases only need to covered once. So I'm going to assert s2 >= s1 w.l.o.g. Also note e1 >= s1 and e2 >= s2.

Cases:

  • L2 starts after L1 ends (s2 >= e1): s1 max s2 = s2, e1 min e2 = e1. Result is s2 - e1, which is non-negative and clearly the value we want (the distance).
  • L2 inside L1 (s2 <= e1, e2 <= e1): s1 max s2 = s2, e1 min e2 = e2. s2 - e2 is non-positive by s2 <= e2, so the result is 0 as expected during overlap.
  • L2 starts within L1 but ends after (s2 <= e1, e2 >= e1): s1 max s2 = s2, e1 min e2 = e1. s2 - e1 is non-positive by s2 <= e1, so the result is 0 as expected during overlap.
梦里南柯 2024-10-15 04:51:55

我认为没有办法绕过这些条件。但这很简洁:

var diff1 = L2x1 - L1x2;
var diff2 = L2x2 - L1x1;

return diff1 > 0 ? max(0, diff1) : -min(0,diff2);

假设 LNx1 LNx2。

I do not think there is a way around the conditions. But this is succinct:

var diff1 = L2x1 - L1x2;
var diff2 = L2x2 - L1x1;

return diff1 > 0 ? max(0, diff1) : -min(0,diff2);

This assumes LNx1 < LNx2.

凯凯我们等你回来 2024-10-15 04:51:55

我认为由于 1D 中的所有线段都是 (X,0) 或 (0,Y) 形式之一,

因此将所有这些 x 值存储在数组中并对数组进行排序,最小距离将是数组的第 1 个 2 元素之间的差异。

在这里,在数组中存储元素时需要小心,以免存储重复的元素

I think since all line segments in the 1D is one of form (X,0) or (0,Y)

so store all these x values in a array and sort the array and minimum distance will the differece between 1st 2 elemenst of the array.

Here you need to be careful while storing element in the array so that duplicate elemenst are not stored

秋凉 2024-10-15 04:51:55

这个公式似乎适用于所有情况,但一条线完全位于另一条线上的情况除外。

return -min(a2-b1,b2-a1)

This formula seems to work in all cases but the one where one line lies fully on the other line.

return -min(a2-b1,b2-a1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文