摘自[3D数学基础: 图形与游戏开发]

考虑在3D中两条以参数形式定义的射线:

\(\vec{r_1}(t_1)=\vec{p_1}+t_1\vec{d_1}\)
\(\vec{r_2}(t_2)=\vec{p_2}+t_2\vec{d_2}\)

我们能够解得它们的交点。暂时先不考虑\(t_1,t_2\)的取值范围。因此,我们考虑的是无限长的射线;同样,向量\(\vec{d_1},\vec{d_2}\)也不必是单位向量。如果这两条射线在一个平面中,那么和前一节的情况一样,也存在有一种可能性:

  • 两条射线交于一点;
  • 两条射线平行,没有交点;
  • 两条射线重合,有无限多交点。

在3D中,还有第四种可能性:两条射线不在一个平面中。

下面演示如何解得交点处的\(t_1,t_2\):

\(\vec{r_1}(t_1)=\vec{r_2}(t_2)\)
\(\Rightarrow \vec{p_1}+t_1\vec{d_1}=\vec{p_2}+t_2\vec{d_2}\)
\(\Rightarrow t_1\vec{d_1}=\vec{p_2}+t_2\vec{d_2}-\vec{p_1}\)
\(\Rightarrow (t_1\vec{d_1})\times\vec{d_2} =(\vec{p_2}+t_2\vec{d_2}-\vec{p_1})\times\vec{d_2}\)
\(\Rightarrow t_1(\vec{d_1}\times\vec{d_2}) =t_2(\vec{d_2}\times\vec{d_2})+(\vec{p_2}-\vec{p_1})\times\vec{d_2}\)
\(\Rightarrow t_1(\vec{d_1}\times\vec{d_2}) =t_2\vec{0}+(\vec{p_2}-\vec{p_1})\times\vec{d_2}\)
\(\Rightarrow t_1(\vec{d_1}\times\vec{d_2})\cdot(\vec{d_1}\times\vec{d_2}) =(\vec{p_2}-\vec{p_1})\times\vec{d_2}\cdot(\vec{d_1}\times\vec{d_2})\)
\(\Rightarrow t_1 =\cfrac{(\vec{p_2}-\vec{p_1})\times\vec{d_2}\cdot(\vec{d_1}\times\vec{d_2})}{(\vec{d_1}\times\vec{d_2})\cdot(\vec{d_1}\times\vec{d_2})}\)
\(\Rightarrow t_1 =\cfrac{(\vec{p_2}-\vec{p_1})\times\vec{d_2}\cdot(\vec{d_1}\times\vec{d_2})}{\Vert\vec{d_1}\times\vec{d_2}\Vert^2}\)

也可以用类似的方法求出\(t_2\):

\(t_2 =\cfrac{(\vec{p_1}-\vec{p_2})\times\vec{d_1}\cdot(\vec{d_2}\times\vec{d_1})}{\Vert\vec{d_2}\times\vec{d_1}\Vert^2}\)

\(\Rightarrow t_2 =\cfrac{(\vec{p_2}-\vec{p_1})\times\vec{d_1}\cdot(\vec{d_1}\times\vec{d_2})}{\Vert\vec{d_1}\times\vec{d_2}\Vert^2}\)

如果两条射线平行或重合,\(\vec{d_1},\vec{d_2}\)的叉乘为零,所以上面两个等式的分母都为零。如果两条射线不在一个平面内,那么\(\vec{r_1}(t_1),\vec{r_2}(t_2)\)是相距最近的点。通过检查\(\vec{r_1}(t_1),\vec{r_2}(t_2)\)间的距离即可确定两条射线相交的情况。当然,在实践中,因为浮点数的精度问题,精确的相交很少出现,这时就需要用到一个偏差值。

上面的讨论假设没有限定\(t_1,t_2\)的取值范围,如果射线的长度有限(或只沿一个方向沿伸),在计算出\(t_1,t_2\)后,还应作适当的边界检测。

在3D中两条射线的相交性检测的更多相关文章

  1. AABB和平面的相交性检测

    [AABB和平面的相交性检测]

  2. SqlServer表中两条全然同样的记录,怎样删除当中1条

    描写叙述:表无主键ID,误插入两遍数据,怎样删除内容同样的记录,而仅仅留下1条. SELECT DISTINCT * INTO #temp FROM grade; DROP TABLE grade; ...

  3. C# 判断两条直线是否相交

    直接上代码,过程不复杂 /// <summary> /// 判断两条线是否相交 /// </summary> /// <param name="a"& ...

  4. cocos2d-x 判断两条直线是否相交

    bool GraphicsUtil::linesCross(b2Vec2 v0, b2Vec2 v1, b2Vec2 t0, b2Vec2 t1, b2Vec2 &intersectionPo ...

  5. 【sql】mysql数据库做两条数据替换的操作,不使用第三方变量

    需求: 1.将数据库中两条数据中的唯一约束列  做值的替换 原始思想: 将两条数据查出来,在程序中设置第三方变量,进行两条数据的替换,然后将原始两条数据删除,将新的两条替换后的数据插入. 新思想: 1 ...

  6. [SQL]开启事物,当两条插入语句有出现错误的时候,没有错误的就插入到表中,错误的语句不影响到正确的插入语句

    begin transaction mustt insert into student values(,'kkk','j大洒扫','j','djhdjh') insert into student v ...

  7. 关于Unity中NGUI的3D角色血条的实现

    首先要到Unity的Assets Store里面去下载一个扩展的Package叫NGUI HUD Text v1.13(81),注意如果没有安装NGUI就必须先安装NGUI插件,否则会用不了,因为HU ...

  8. c编程:求出4&#215;4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和。

    //求出4×4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和 #include <stdio.h> int main() { int sum=0; int max, ...

  9. 一条SQL语句查询两表中两个字段

    首先描述问题,student表中有字段startID,endID.garde表中的ID需要对应student表中的startID或者student表中的endID才能查出grade表中的name字段, ...

随机推荐

  1. ubuntu14.04 fcitx安装

    先卸载ibus sudo apt-get remove ibus (也可尝试不卸载ibus,直接安装fcitx) 添加源 sudo add-apt-repository ppa:fcitx-team/ ...

  2. JavaSE 学习笔记之网络编程(二十三)

    端口: 物理端口: 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. java 中ip对象:InetAddress. import ja ...

  3. 九度oj 题目1050:完数

    题目1050:完数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:8778 解决:3612 题目描述: 求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子 ...

  4. POJ2774:Long Long Message

    问两个串的最长公共子串,n<=100000. SAM可以直接搞当然SA哈希都可以..类似于KMP的做法,如果沿parent边走要顺势修改匹配位置. #include<stdio.h> ...

  5. P1516 青蛙的约会 洛谷

    https://www.luogu.org/problem/show?pid=1516 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上, ...

  6. 洛谷——P2910 [USACO08OPEN]寻宝之路Clear And Present Danger

    P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 题目描述 Farmer John is on a boat seeking fabled treasur ...

  7. Nginx 源码

    http://blog.sina.com.cn/s/articlelist_1834459124_1_1.html http://tengine.taobao.org/book/ https://gi ...

  8. org.apache.shiro.web.servlet.ShiroHttpServletRequest cannot be cast to org.springframwork.web.mult..

    在用dwz框架+spring MVC时上传文件报的错 详细错误例如以下: 事实上就是一个类型转换错误,但却研究了好长时间,怎么都不知道哪里错了.由于前面卸过一个文件上传的和这个差点儿相同,那个就没有问 ...

  9. AOP设计场景

    AOP就是切面编程的一个思想,当然完毕一项编码任务,发现有些东西是反复工作,这时就能够考虑使用AOP编程.把一些共性的东西交给它来完毕,我们仅仅关心业务逻辑的东西,最精彩用的场景有两种: 一,控制数据 ...

  10. 第K顺序统计量的求解

    一个n个元素组成的集合中,第K个顺序统计量(Order Statistic)指的是该集合中第K小的元素,我们要讨论的是如何在线性时间(linear time)里找出一个数组的第K个顺序统计量. 一.问 ...