检查矩形的任何角是否在另一个矩形内
Checking if any of corners of a rectangle is inside other rectangle
我有一道数学题。
当一个矩形(或其中一个)都没有角度并且完全适合网格时,我检查一个矩形是否在另一个矩形的边界内没有问题。但是一旦我改变它们的角度,这一切走下坡路。
这就是我的意思 - 右边的效果完美,但左边的效果不佳:
您可以旋转两个矩形,使其中一个与网格对齐。首先,计算两个矩形的 degree of rotation:
angle = arc tan(ength of long side / length of short side)
arc tan(11 / 7)
= 57.5 degrees
现在你知道绿色三角形从它的长边平行于x轴逆时针旋转57.5度。因此,您可以将两个矩形顺时针旋转 57.5 度以获得您可以处理的配置。请参阅 here 了解如何执行此操作。
我建议只使用 Tim 的答案,而不是对轮换那么挑剔。但是如果你真的太强迫症了,你可以试试下面的vector-based方法。
由于矩形的边是垂直的,您可以将它们用作(正交)坐标系。
新坐标轴:
变换坐标:
支票:
可以在不使用旋转(这意味着调用三角函数)或归一化向量(这需要 sqrt)的情况下做到这一点。
假设您的矩形由点 a、b、c、d 按顺时针顺序定义。如果一个点位于每个向量 ab、bc、cd 和 da 的右侧,则该点位于矩形内。
您可以通过向量 ap 与垂直于 ab 的向量的点积来测试点 p 与向量 ab 的关系,只需交换 x 和 y 并翻转其中一个符号即可得到。点积的符号告诉你你在矢量的哪一边。
如果符号均为正则点在矩形内。您不需要归一化,因为您只是检查符号,而不是幅度。
float pointToVector(Vec2 p, Vec2 a, Vec2 b)
{
Vec2 n = new Vec2(b.y - a.y, a.x - b.x); // no need to normalize
return n.dot(p - a);
}
bool pointInRect(Vec2 p, Vec2 a, Vec2 b, Vec2 c, Vec2 d)
{
return (pointToVector(p, a, b) > 0) && // can short-circuit
(pointToVector(p, b, c) > 0) &&
(pointToVector(p, c, d) > 0) &&
(pointToVector(p, d, a) > 0));
}
请注意,这实际上是一个任意点在 4 边凸多边形中的测试。您可以利用 ab 和 cd 以及 bc 和 da 平行这一事实来针对矩形优化它,这样您就可以重用垂直向量,但反转检查符号。但是,这会使代码稍微复杂一些。此外,上面假设一个坐标系随着 y 的增加而上升。如果不是,则将比较更改为 < 或按逆时针顺序定义矩形。
P=aA+bB
求解 a
和 b
。 P 在矩形内,如果 a < 1 && b < 1
我有一道数学题。
当一个矩形(或其中一个)都没有角度并且完全适合网格时,我检查一个矩形是否在另一个矩形的边界内没有问题。但是一旦我改变它们的角度,这一切走下坡路。
这就是我的意思 - 右边的效果完美,但左边的效果不佳:
您可以旋转两个矩形,使其中一个与网格对齐。首先,计算两个矩形的 degree of rotation:
angle = arc tan(ength of long side / length of short side)
arc tan(11 / 7)
= 57.5 degrees
现在你知道绿色三角形从它的长边平行于x轴逆时针旋转57.5度。因此,您可以将两个矩形顺时针旋转 57.5 度以获得您可以处理的配置。请参阅 here 了解如何执行此操作。
我建议只使用 Tim 的答案,而不是对轮换那么挑剔。但是如果你真的太强迫症了,你可以试试下面的vector-based方法。
由于矩形的边是垂直的,您可以将它们用作(正交)坐标系。
新坐标轴:
变换坐标:
支票:
可以在不使用旋转(这意味着调用三角函数)或归一化向量(这需要 sqrt)的情况下做到这一点。
假设您的矩形由点 a、b、c、d 按顺时针顺序定义。如果一个点位于每个向量 ab、bc、cd 和 da 的右侧,则该点位于矩形内。
您可以通过向量 ap 与垂直于 ab 的向量的点积来测试点 p 与向量 ab 的关系,只需交换 x 和 y 并翻转其中一个符号即可得到。点积的符号告诉你你在矢量的哪一边。
如果符号均为正则点在矩形内。您不需要归一化,因为您只是检查符号,而不是幅度。
float pointToVector(Vec2 p, Vec2 a, Vec2 b)
{
Vec2 n = new Vec2(b.y - a.y, a.x - b.x); // no need to normalize
return n.dot(p - a);
}
bool pointInRect(Vec2 p, Vec2 a, Vec2 b, Vec2 c, Vec2 d)
{
return (pointToVector(p, a, b) > 0) && // can short-circuit
(pointToVector(p, b, c) > 0) &&
(pointToVector(p, c, d) > 0) &&
(pointToVector(p, d, a) > 0));
}
请注意,这实际上是一个任意点在 4 边凸多边形中的测试。您可以利用 ab 和 cd 以及 bc 和 da 平行这一事实来针对矩形优化它,这样您就可以重用垂直向量,但反转检查符号。但是,这会使代码稍微复杂一些。此外,上面假设一个坐标系随着 y 的增加而上升。如果不是,则将比较更改为 < 或按逆时针顺序定义矩形。
P=aA+bB
求解 a
和 b
。 P 在矩形内,如果 a < 1 && b < 1