Graphics 如何确定两个矩形是否重叠(成角度)

Graphics 如何确定两个矩形是否重叠(成角度),graphics,shapes,overlap,angle,clip,Graphics,Shapes,Overlap,Angle,Clip,我想确定两个矩形是否重叠(不相交)。我知道如何对轴对齐的矩形执行此操作,但在本例中,我有一个矩形并不总是轴对齐(即在其中心旋转)。显示了如何计算两个相交的矩形,但它不会将一个矩形划分为另一个矩形,如中所示,因为它们是重叠的,而不是相交的 在我的例子中,一个矩形是轴对齐的(黑框),另一个旋转(红框),这样可能会更容易 我想我需要多个案例来确定它们是否重叠。第一种简单的情况是检查是否有任何红色顶点在黑框内。然后我可以检查红/黑边是否相交。我不确定如何才能涵盖上述案例,以及是否有更简单的方法来实现这一

我想确定两个矩形是否重叠(不相交)。我知道如何对轴对齐的矩形执行此操作,但在本例中,我有一个矩形并不总是轴对齐(即在其中心旋转)。显示了如何计算两个相交的矩形,但它不会将一个矩形划分为另一个矩形,如中所示,因为它们是重叠的,而不是相交的

在我的例子中,一个矩形是轴对齐的(黑框),另一个旋转(红框),这样可能会更容易

我想我需要多个案例来确定它们是否重叠。第一种简单的情况是检查是否有任何红色顶点在黑框内。然后我可以检查红/黑边是否相交。我不确定如何才能涵盖上述案例,以及是否有更简单的方法来实现这一点

额外细节:这是为我的图形软件clipper(在这种情况下不能使用硬件剪裁)设计的,其中黑框是我的窗口/视口,红框是“精灵”,黑框之外的任何内容都被剪裁/未渲染。我使用的是正交/二维投影。最后我将有两个函数,一个用于检测精灵是否在窗口/视口之外(我在这个问题中要问的),然后我将使用Sutherland–Hodgman算法生成一个函数,将精灵裁剪到窗口/视口之内

编辑:


is post确实概括地描述了如何进行SAT,但没有详细说明。如何生成法线?“角”是屏幕坐标还是与形状中心的距离?我试着根据自己的目的修改他们的代码,但我不知道如何使用每个形状/矩形的顶点列表(屏幕x和y)执行SAT测试这通常被称为AABB-OBB交叉测试。(轴对齐边界框和定向边界框)。如果一个边界框完全位于另一个边界框内,则仍将其视为“交点”

要解决这个问题,请使用分离轴定理。如果AABB和OBB不重叠,则它们必须至少有一个平行于其一侧的分离轴

对于OBB-OBB相交测试,将两个形状投影到8条不同的线上(每个矩形的每条边一条),并对每个投影执行简单的1D重叠测试

对于AABB-OBB,这基本相同,但减少为4个投影,因为四对边始终平行

请看以下有关OBB-OBB的说明:


首先,我要感谢用户“prideout”为我指明了正确的方向。他的笔记,特别是只需要4个法线,帮助我优化了代码。奇怪的是,中的代码似乎工作不正常(检测形状的“压碎”顶点是否重叠)。我发现这为我指明了正确的方向,现在我的代码工作得很好

这是我的AABB-OBB重叠检测器函数+SAT函数(使用的语言是基于Java的“处理”)

//如果重叠则为True,如果不重叠则为False
布尔分离轴定理(float[]x1,float[]y1,float[]x2,float[]y2,float[]normal){
float[]范围=新浮点[4];//minAlong1、maxAlong1、minAlong2、maxAlong2
范围[0]=Float.MAX_值;
范围[1]=-Float.MAX_值;
范围[2]=Float.MAX_值;
范围[3]=-Float.MAX_值;
//Dot将点投影到分离轴上,然后我们得到最大值和最小值
浮点数;
对于(int i=0;i<4;i++){
dotVal=dot(x1[i],y1[i],法线[0],法线[1]);
如果(dotValrange[1]){range[1]=dotVal;}
dotVal=dot(x2[i],y2[i],正常[0],正常[1]);
如果(dotValrange[3]){range[3]=dotVal;}
}
如果(范围[1]<范围[2]| |范围[0]>范围[3]){
返回false;
}
返回true;
}
//如果两个形状重叠,则为True,否则为False
布尔AABB_OBB_重叠(float[]OBB_X,float[]OBB_Y,float[]AABB_X,float[]AABB_Y){
//检查相机的法线,因为我们知道它的轴对齐,所以不需要进行单位矢量计算,所以简化了检查
float[]range=get_range(OBB_X);//返回数组的最小值和最大值
如果(范围[1]AABB_X[1]){
返回false;
}
范围=获取范围(OBB_Y);
如果(范围[1]AABB_Y[2]){
返回false;
}
//检查精灵的法线
float[]normal1=单位向量(OBB_X[1]-OBB_X[0],OBB_Y[1]-OBB_Y[0]);//顶部
float[]normal2=单位向量(OBB_X[2]-OBB_X[0],OBB_Y[2]-OBB_Y[0]);//左侧
if(!分离轴定理(OBB_X,OBB_Y,AABB_X,AABB_Y,normal1)){
返回false;
}
if(!分离轴定理(OBB_X,OBB_Y,AABB_X,AABB_Y,normal2)){
返回false;
}
//它们重叠
返回true;
}

我已经阅读了推荐答案。我模模糊糊地明白发生了什么,但还不足以正确地理解它。代码中有几个洞,没有什么解释(什么是
大的
?Max int还是什么?)。我会看一下SAT的其他解释,但谢谢你给我指出了正确的答案:)我已经让它大部分工作正常了,但我不能按照他们的逻辑“将两个形状投影到线条上”。我知道这条线是正常的,但是他们如何将顶点投射到这条线上毫无意义。他们对每个顶点做一个点积,然后把它排序成一个列表?我在谷歌上搜索了很多这部分,我能找到的唯一其他答案要复杂得多。你知道那里发生了什么事吗?