射线和立方体相交的判断方法_射线线段直线的相同点和不同点[通俗易懂]

射线和立方体相交的判断方法_射线线段直线的相同点和不同点[通俗易懂]如何判断射线和立方体相交_java求空间中一条射线是否穿过立方体

本文主要介绍如何判定一条线和一个立方体相交
1、Slabs的使用(2D的介绍)
2、将Slabs推广到3D
其中只介绍数学相关,代码实现可自行实现
检测物体碰撞的时候,我们通常在物体表面添加包围盒,其中常用的包围盒有如下三种,其中Slabs主要适用于AABB包围盒
OBB比包围球和AABB更加逼近物体,能显著减少包围体的个数。因此,人们通常进行两个回合的碰撞/相交检测,用包围球做第一回合的快速测试,用OBB进行第二回合的测试。第一回合的测试可以剔除大多数不可见或不必裁剪的物体,这样不必进行第二回合测试的几率就会大得多。

在这里插入图片描述

1、Slabs的使用(2D的介绍)

如果一条射线与有长方形构成的AABB区域相交,则该射线在x-slab和y-slab之间的线段有相交,如下图所示:
在这里插入图片描述
定义四个点,分别叫做 xnear,xfar,ynear,yfar,分别对应射线与长方形两条横线的两个交点,射线与长方形两条竖线的两个交点,如图所示

我们假设射线为 L ( t ) = t d ⃗ + P L(t) =t\vec{d}+P L(t)=td
+
P
,其中P为射线起点, d ⃗ \vec{d} d
为射线的方向,那么此时,上述四个点可以表示为

t x n e a r d ⃗ + P , t x f a r d ⃗ + P , t y n e a r d ⃗ + P , t y f a r d ⃗ + P t_{xnear}\vec{d}+P,t_{xfar}\vec{d}+P,t_{ynear}\vec{d}+P,t_{yfar}\vec{d}+P txneard
+
Ptxfard
+
Ptyneard
+
Ptyfard
+
P

如果 m a x ( t x n e a r , t y n e a r ) ≤ m i n ( t x f a r , t y f a r ) max(t_{xnear},t_{ynear})≤min(t_{xfar},t_{yfar}) max(txnear,tynear)min(txfar,tyfar),则射线与长方形相交

2、将Slabs推广到3D

3D的Slabs同2D,3D空间中判断射线是否与长方体构成的AABB包围盒相交的方法是,判断该射线在

x-slab,y-slab,z-slab之间的部分是否有公共区域。

我们假设射线为 L ( t ) = t D ⃗ + P L(t) =t\vec{D}+P L(t)=tD
+
P
,其中P为射线起点, d ⃗ \vec{d} d
为射线的方向,我们假设平面方程为

X n ⃗ = d X\vec{n}=d Xn
=
d
,这是点法式,X为平面上的点, n ⃗ \vec{n} n
为平面法向量,d为原点到平面的有向距离。

我们将射线带入平面可得到

( t D ⃗ + P ) n ⃗ = d , 即 t = d − P n ⃗ n ⃗ D ⃗ (t\vec{D}+P)\vec{n}=d,即 t=\frac{d-P\vec{n}}{\vec{n}\vec{D}} (tD
+
P)n
=
dt=n
D
dPn
,设P(px,py,pz),

D(Dx,Dy,Dz),在使用slabs的时候有两个分量为0,因此我们可以求得如下几个t值

x-slab: t x = ( d − p x ) / D x t_x=(d-p_x)/D_x tx=(dpx)/Dx

y-slab: t y = ( d − p y ) / D y t_y=(d-p_y)/D_y ty=(dpy)/Dy

z-slab: t z = ( d − p z ) / D z t_z=(d-p_z)/D_z tz=(dpz)/Dz

接下去我们同样求解出 xnear,xfar,ynear,yfar,znear,zfar

此时,如果 m a x ( t x n e a r , t y n e a r , t z n e a r ) ≤ m i n ( t x f a r , t y f a r , t z f a r ) max(t_{xnear},t_{ynear},t_{znear})≤min(t_{xfar},t_{yfar},t_{zfar}) max(txnear,tynear,tznear)min(txfar,tyfar,tzfar),则射线与长方体相交

vec2 intersectBox(const Ray& ray, const Box& cube)
{ 
   
 vec3 inv_dir = 1.0f / ray.direction;
 vec3 tMin = (cube.min - ray.origin) * inv_dir;
 vec3 tMax = (cube.max - ray.origin) * inv_dir;
 vec3 t1 = min(tMin, tMax);
 vec3 t2 = max(tMin, tMax);
 float tNear = max(max(t1.x, t1.y), t1.z);
 float tFar = min(min(t2.x, t2.y), t2.z);

 return vec2(tNear, tFar);
}

如果返回值tNear > tFar则不相交,否则射线与AABB包围盒相交。

参考文章

今天的文章射线和立方体相交的判断方法_射线线段直线的相同点和不同点[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86715.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注