延伸线段以适合边界框
我有一个由两个 pointF 定义的线段,以及一个 2D 边界矩形。我想在两个方向上尽可能地延伸线段,以便该线段与边界框的壁齐平。以下是我想做的一些示例:
有人对如何做有任何建议吗这?
I have a line segment defined by two pointF
s, along with a 2D bounding rectangle. I want to extend the line segment as much as possible in both directions so that the segment is flush with the walls of the bounding box. Here are some examples of what I'm trying to do:
Does anyone have any suggestions on how to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
下面是 python 中的代码示例:
它不会检查线段是否包含在矩形中,并且如果线段位于矩形外部,则也应该起作用(如果没有实际的线段交集,则返回 None -隐式)。
它基于矩形具有与轴平行的线段的假设。
Here is an code example in python:
It doesn't check that the segment is contained in the rectangle and should work also if it is exterior to it (returns None -implicit- if there is no actual segment intersection).
It is based on the assumption that the rectangle has the segments parallel with the axes.
将矩形定义为四条线。
找到您的线与四条线中每条线之间的交点。 (你的高中几何学怎么样?)
在这四个交点中,确定哪些点在矩形的边界内。 (找到 x 和 y 值都在矩形范围内的交点)。
您的算法还必须考虑到以下边缘情况:
Define the rectangle as four lines.
Find the intersection between your line and each of the four lines. (How's your highschool geometry?)
Of these four intersection points, determine which points are within the bounds of the rectangle. (find the intersection points where both the x and y values are within the rectangles range).
Your algorithm must also allow for the following edge cases:
一种选择是定义范围在某个变量 t 上的线段的参数表示,然后定义四个线性方程来定义盒子侧面的线(在所有方向上无限延伸)。这个想法是,当您检查段命中的位置时这些线,对于您可以延伸线段的每个方向,您将获得两个交点 - 一个用于水平交点,一个用于垂直交点。无论盒子里有哪一个,都将是您想要选择的。
为此,请计算通过在击中四个边界线之一的每个方向上延伸线段而形成的线的参数 t 值。我假设线段被参数化,使得 t ∈ [0, 1]。然后,您将获得(最多)四个与线与边界框相交处的参数相对应的 t 值 - 两个值 ≥ 1 表示线在一个方向上的延伸,两个值 ≤ 0 表示线在另一方向上的延伸。在这四个值中,您要选择 t ≥ 1 的值最小,t ≥ 0 的值最大(这些代表在撞墙之前在每个方向上延伸出最短距离的线的参数) 。获得这两个参数后,将 t 的值插回到原始参数化中,以生成所需的与墙壁的两个交点,然后将新线段定义为从第一个线段跨越到第二个线段。
请注意,该算法更一般地可用于延伸线段以填充任何凸多边形的边界,包括未轴对齐的矩形。您实际上不需要测试您找到的任何点是否包含在边界框中;您只需查看参数 t 的值即可了解哪些交点更接近线段的端点。
希望这有帮助!
One option would be to define a parametric representation of the line segment ranging over some variable t, then to define four linear equations defining the lines on the side of the box (extended infinitely in all directions). The idea is that when you check where the segment hits these lines, for each direction you could extend the segment, you'll get two intersection points - one for the horizontal intersection and one for the vertical intersection. Whichever of these lies inside the box will be the one that you want to pick.
To do this, compute values of the parameter t of the line formed by extending the segment in each direction where you hit one of the four bounding lines. I assume that the line segment is parameterized such that t ∈ [0, 1]. You will then get (up to) four values of t corresponding to parameters where the line intersects the bounding box - two values ≥ 1 representing extensions of the line in one direction and two values ≤ 0 representing extensions of the line in the other direction. Of these four values, you want to choose the value of t ≥ 1 that's the smallest and the value of t ≥ 0 that's the greatest (these represent the parameters of the line that extend out the shortest distance in each direction before hitting the wall). Once you have these two parameters, plug the values of t back into the original parameterization to yield the two intersection points you want with the walls, then define the new line segment to be one that spans from the first of these to the second.
Note that this algorithm more generally can be used to extend the line segment to fill the bounds of any convex polygon, including rectangles that aren't axis-aligned. You never actually need to test whether any of the points you find are contained in the bounding box; you just look at the value of the parameter t to see which of the intersection points are closer to the endpoints of your segment.
Hope this helps!
我通过@tsveti_iko修改了代码,因为当 y_for_xmin 为“无穷大”时(如果 x2 - x1 为 0),int 转换无法正常工作,我遇到了一些问题
I modified the code by @tsveti_iko as I had some issues with int conversions not working when y_for_xmin was 'infinity' (if x2 - x1 is 0)
@andredor 算法的扩展版本,涵盖所有情况(也包括当线段不平行于轴时 - 例如当线段是对角线时)。详细解释该方法作为文档。
An extended version of the @andredor algorithm to cover all cases (also when the segments are not parallel to the axes - e.g. when the segments are diagonal). With elaborate explanation of the method as documentation.
改进了 andredor 的代码 - 添加了线与顶部和底部或左侧和右侧边缘相交时的边缘情况。提供的代码用于处理测试算法。第一个点通过单击鼠标设置,第二个点随着当前鼠标指针位置不断更新。
Improved andredor's code - Added edge cases for when line intersects top and bottom or left and right edges. The provided code is for Processing to test the algorithm. The first point is set by clicking the mouse and the second point continuously updates with the current mouse pointer position.
该脚本将适用于任何给定的线,无论它是如何绘制的
This script will work with any given line no matter how it is drawn