检测线段是否与正方形相交

发布于 2024-08-03 07:13:29 字数 48 浏览 3 评论 0原文

有人有一个简单的算法吗?不需要旋转什么的。只需查找由两点组成的线段是否与正方形相交

Anyone have a simple algorithm for this? No need for rotation or anything. Just finding if a line segment made from two points intersects a square

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

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

发布评论

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

评论(3

長街聽風 2024-08-10 07:13:29

这段代码应该可以解决问题。它检查线与边相交的位置,然后检查它是否在正方形的宽度内。返回相交数。

float CalcY(float xval, float x0, float y0, float x1, float y1)
{
    if(x1 == x0) return NaN;
    return y0 + (xval - x0)*(y1 - y0)/(x1 - x0);
}

float CalcX(float yval, float x0, float y0, float x1, float y1)
{
    if(x1 == x0) return NaN;
    return x0 + (yval - y0)*(y1 - y0)/(x1 - x0);
}

int LineIntersectsSquare(int x0, int y0, int x1, int y1, int left, int top, int right, int bottom)
{
    int intersections = 0;
    if(CalcX(bottom, x0, y0, x1, y1) < right && CalcX(bottom, x0, y0, x1, y1) > left  ) intersections++;
    if(CalcX(top   , x0, y0, x1, y1) < right && CalcX(top   , x0, y0, x1, y1) > left  ) intersections++;
    if(CalcY(left  , x0, y0, x1, y1) < top   && CalcY(left  , x0, y0, x1, y1) > bottom) intersections++;
    if(CalcY(right , x0, y0, x1, y1) < top   && CalcY(right , x0, y0, x1, y1) > bottom) intersections++;
    return intersections;
}

注意:此代码是理论上的,可能不正确,因为它尚未经过测试

This code should do the trick. It checks where the line intersects the sides, then checks if that is within the width of the square. The number of intesections is returned.

float CalcY(float xval, float x0, float y0, float x1, float y1)
{
    if(x1 == x0) return NaN;
    return y0 + (xval - x0)*(y1 - y0)/(x1 - x0);
}

float CalcX(float yval, float x0, float y0, float x1, float y1)
{
    if(x1 == x0) return NaN;
    return x0 + (yval - y0)*(y1 - y0)/(x1 - x0);
}

int LineIntersectsSquare(int x0, int y0, int x1, int y1, int left, int top, int right, int bottom)
{
    int intersections = 0;
    if(CalcX(bottom, x0, y0, x1, y1) < right && CalcX(bottom, x0, y0, x1, y1) > left  ) intersections++;
    if(CalcX(top   , x0, y0, x1, y1) < right && CalcX(top   , x0, y0, x1, y1) > left  ) intersections++;
    if(CalcY(left  , x0, y0, x1, y1) < top   && CalcY(left  , x0, y0, x1, y1) > bottom) intersections++;
    if(CalcY(right , x0, y0, x1, y1) < top   && CalcY(right , x0, y0, x1, y1) > bottom) intersections++;
    return intersections;
}

NB: this code is theoretical and may not be correct, as it has not been tested

凡间太子 2024-08-10 07:13:29

您可以通过投射向量并计算它穿过的边数来完成此操作。

如果它穿过的边是偶数,则它在物体外部,如果它穿过的边是奇数,则它在物体内部。

这适用于所有闭合多边形。

You can do this by casting a vector and counting the number of edges it crosses.

If the edges it crosses are even, it is outside the object, if the edges it crosses are odd, it is inside.

This works for all closed polygons.

傲娇萝莉攻 2024-08-10 07:13:29

方法如下:
- 按 x 坐标对正方形的顶点进行排序
- 按 x 坐标对线的端点进行排序
- 计算从线的 minX 端到中间两个(通过 x 坐标)方形顶点中的每一个的角度
- 计算线的角度
- 如果线的角度在可能的角度内,您所要做的就是检查长度,即线的 maxX 末端 >正方形的 minX 顶点

如果正方形直接面向线,这可能会中断,在这种情况下,我只需通过检查正方形的第一条边来对其进行特殊处理。

Here's a way:
- sort the vertex points of the square by x-coord
- sort the endpoint of the line by x-coord
- calculate angle from the minX end of the line to each of the middle two (by x-coord) square vertices
- calculate angle of the line
- if the line's angle is within the possible angles, all you have to do is a length check, is maxX end of the line > minX vertex of the square

This will probably break if the square is directly facing the line, in that case I'd just special-case it by checking the first edge of the square.

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