复盘刚做的一个三维操作APP
致敬偶像
功能点挺多的,做了一个月没完没了,也没啥意义哈
其中一个环节是做贴纸的点触碰撞
很简单的,没有转换矩阵,没有公式推导
如图白色框(小的)是点击,绿色框是目标位置x4
明显的一开始用了白色框的左下角做判断(点是否在正方形内),所以没办法正确判断白绿2个方形是否相交
if (d.XMin <= rect.XMin && rect.XMin <= d.XMax)
{
if (d.YMin <= rect.YMin && rect.YMin <= d.YMax)
{
正确的AABB包含写法是?
在网上随便百度一下。。。。。。。。。
所以,在程序中做二维游戏的AABB碰撞检测时,只需验证物体A与物体B是否满足如下条件:
(1)物体A的Y轴方向最小值大于物体B的Y轴方向最大值;
(2)物体A的X轴方向最小值大于物体B的X轴方向最大值;
(3)物体B的Y轴方向最小值大于物体A的Y轴方向最大值;
(4)物体B的X轴方向最小值大于物体A的X轴方向最大值;
若满足上述条件,则证明物体A与物体B并未发生重合,反之,则证明物体A与物体B重合。
说程序员的话,就是:
if (rect.YMin > d.YMax && rect.XMin > d.XMax && rect.YMax < d.YMin && rect.XMax < d.XMin)
{
//未重合
}
else
{
//AABB包围
}
(上面的逻辑条件,和代码,都是大错特错的,结果就是多个rect击中,代码崩的一塌糊涂)
根本和AABB包围盒无关
上面都是错的
上面都是错的
上面都是错的
其实只要计算2个矩形是否相交
这个才是非常正确的逻辑
bool is_rect_intersect(P3D_Rect rectA,P3D_Rect rectB)
{
int x01 = rectA.XMin;
int x02 = rectA.XMax;
int y01 = rectA.YMin;
int y02 = rectA.YMax;
int x11 = rectB.XMin;
int x12 = rectB.XMax;
int y11 = rectB.YMin;
int y12 = rectB.YMax;
int zx = Mathf.Abs(x01 + x02 - x11 - x12);
int x = Mathf.Abs(x01 - x02) + Mathf.Abs(x11 - x12);
int zy = Mathf.Abs(y01 + y02 - y11 - y12);
int y = Mathf.Abs(y01 - y02) + Mathf.Abs(y11 - y12);
if (zx <= x && zy <= y)
return true;
else
return false;
}
其实很多时候,实际工作中,我们只要照抄一下同事的方法即可,也不需要怎么理解
即便不理解
但真的要知道,上面“某大神”又图,又说明,又分析,说了一堆AABB,结果是不能用的伪逻辑
所以,这个网络时代,大家看看就好了,不要往心里去
具体的推导,大家可能直接从代码里反推比较好,参考:
===========================================================
难道我们要每个case都要判断一边,然后决定是否相交?
其实是有通用方法的。
如果两个矩形相交,那么矩形A B的中心点和矩形的边长是有一定关系的。
Case 2345中,两个中心点间的距离肯定小于AB边长和的一半。
Case 1中就像等了。
设A[x01,y01,x02,y02] B[x11,y11,x12,y12].
矩形A和矩形B物理中心点X方向的距离为Lx:abs( (x01+x02)/2 – (x11+x12) /2)
矩形A和矩形B物理中心点Y方向的距离为Ly:abs( (y01+y02)/2 – (y11+y12) /2)
矩形A和矩形B X方向的边长为 Sax:abs(x01-x02) Sbx: abs(x11-x12)
矩形A和矩形B Y方向的边长为 Say:abs(y01-y02) Sby: abs(y11-y12)
如果AB相交,则满足下列关系:
Lx <= (Sax + Sbx)/2 && Ly <=(Say+ Sby)/2
==============================================================
之后可能会分享下真正的光线包围盒吧,作为杠精的我,还是先摆网上的错误论调,再分享实践过,测试通过的代码
分享一下Gizmos的写法
大的白色框是UV框