程序实现射线与平面相交计算时差值向量取反才生效的原因咨询
射线与平面相交代码符号错误原因说明
核心问题是你代码中射线参数方程的写法和参考推导的约定不一致,二者符号冲突导致结果异常。
基础约定说明
- 平面通用方程:对于平面上任意一点
P,满足(P - plane_point) · plane_normal = 0,其中plane_point是平面上的已知点,plane_normal是平面法向量。 - 射线参数方程存在两种常见的合法写法:
- 多数技术资料使用的写法:
P(t) = ray_origin + t * ray_direction,其中t≥0对应射线正向传播的路径 - 你代码中实际使用的写法:
intersection = ray_origin - ray_direction * distance_from_origin_to_plane,对应参数方程为P(t) = ray_origin - t * ray_direction,t≥0为射线正向
- 多数技术资料使用的写法:
推导验证
将你代码中的射线参数方程代入平面方程:
(P(t) - plane_point) · plane_normal = 0
替换P(t)为你的表达式:
(ray_origin - t * ray_direction - plane_point) · plane_normal = 0
展开点积拆分计算项:
( (ray_origin - plane_point) · plane_normal ) - t * ( ray_direction · plane_normal ) = 0
移项求解参数t(即你代码中的distance_from_origin_to_plane):
t = [ (ray_origin - plane_point) · plane_normal ] / ( ray_direction · plane_normal )
可以看到式子的分子正好是你修改后的ray_origin - plane_point。
你最开始参考的推导使用的是P(t) = ray_origin + t * ray_direction的参数约定,推导出来的分子是plane_point - ray_origin。你直接复用了适配加号参数方程的分子计算,但自己写交点的时候用了减号的参数方程,两个符号冲突,自然无法得到正确结果。修改分子后符号抵消,逻辑完全匹配,因此运行正常。
可选修正方案
除了你已经采用的修改分子的方案,也可以修改交点计算逻辑适配参考推导的约定,两种方案效果一致:
// 分子保持和参考推导一致 Vector3 difference = plane_point - ray_origin; double product_1 = difference.dot(plane_normal); double product_2 = ray_direction.dot(plane_normal); // 注意判断product_2绝对值过小的情况,避免除零错误 double distance_from_origin_to_plane = product_1 / product_2; // 交点计算改为加号,匹配参考的参数方程约定 Vector3 intersection = ray_origin + ray_direction * distance_from_origin_to_plane;
额外提示:实际工程中需要先判断
product_2的绝对值是否接近0,此时射线与平面平行,没有交点或完全共面,需要单独处理避免除零异常。
内容的提问来源于stack exchange,提问作者Richard Garfield
相关产品推荐
相关产品推荐

