文章目录

  • 1. 原理推导
    • 1.1. 直线公式
    • 1.2. 求交
  • 2. 具体实现
  • 3. 参考

1. 原理推导

1.1. 直线公式

在严格的数学定义中,直线是无线延长,没有端点的线;射线是一端有端点,另外一段没有端点无线延长的线。但在具体的计算机几何实现中,不可能去找到这种无线延长,没有端点的线,所以这里直线的定义更加近于线段,如果线段选的够长,那么这个线段就可以认为是直线或者射线。

空间直线的数学定义是,已知直线L上一点M0(x0,y0,c0)M_0(x_0,y_0,c_0)M0​(x0​,y0​,c0​),以及直线L的方向向量s(m,n,p)s(m,n,p)s(m,n,p),那么空间直线L的方程为:
x−x0m=y−y0n=z−z0p\frac{x-x_0}{m} = \frac{y-y_0}{n} = \frac{z-z_0}{p}mx−x0​​=ny−y0​​=pz−z0​​

以上是空间直线的标准式方程(点向式方程)。令上面式子的比值为ttt,那么直线的参数式方程为:
{x=x0+m∗ty=y0+n∗tz=z0+p∗t\begin{cases} x = x_0 + m * t\\ y = y_0 + n * t\\ z = z_0 + p * t\\ \end{cases} ⎩⎪⎨⎪⎧​x=x0​+m∗ty=y0​+n∗tz=z0​+p∗t​

这两个方程是无法直接在实际情况中使用的,毕竟很多时候都是直接给出经过直线的两个点。我在《已知线段上某点与起点的距离,求该点的坐标》这篇博文中论述过:

对于知道线段的起点OOO和终点EEE,显然方向向量为D=E−OD=E−OD=E−O。这时,根据射线的向量方程,线段上某一点P为
P=O+tDP=O+tDP=O+tD

很明显,直线的参数式方程与上篇博文中描述的其实是一个意思,起点OOO就是M0(x0,y0,c0)M_0(x_0,y_0,c_0)M0​(x0​,y0​,c0​),方向向量DDD就是s(m,n,p)s(m,n,p)s(m,n,p):
{x=Ox+Dx∗ty=Oy+Dy∗tz=Oz+Dz∗t(1)\begin{cases} x = O_x + D_x * t\\ y = O_y + D_y * t\\ z = O_z + D_z * t\\ \end{cases} \tag {1} ⎩⎪⎨⎪⎧​x=Ox​+Dx​∗ty=Oy​+Dy​∗tz=Oz​+Dz​∗t​(1)

并且,采取这种公式描述还有个好处,局势t的取值范围为0到1,否则就在直线的两个端点之外,也就很有可能不是你需要的点。

1.2. 求交

根据数学定义,已知球心坐标C(Cx,Cy,Cz)C(C_x, C_y, C_z)C(Cx​,Cy​,Cz​)与球的半径R,球面的公式为:
(X−Cx)2+(Y−Cy)2+(Z−Cz)2=R2(2)(X-C_x)^2 + (Y-C_y)^2 + (Z-C_z)^2 = R^2 \tag{2} (X−Cx​)2+(Y−Cy​)2+(Z−Cz​)2=R2(2)

联立(1)(2)两式,最终会得到一个关于t的一元二次方程:
(Ox+Dx∗t−Cx)2+(Oy+Dy∗t−Cy)2+(Oz+Dz∗t−Cz)2=R2(O_x + D_x * t-C_x)^2 + ( O_y + D_y * t-C_y)^2 + (O_z + D_z * t-C_z)^2 = R^2 (Ox​+Dx​∗t−Cx​)2+(Oy​+Dy​∗t−Cy​)2+(Oz​+Dz​∗t−Cz​)2=R2

一元二次方程组的有无解,单个解,以及双解三种可能,这也符合空间直线与球面相交的直观认识,要么相切有一个交点,要么相交有两个交点,否则的话可能没有交点。

得到ttt后,将其带入到(1)式中,就得到想要的交点。不过注意t的范围一般是0到1,这是与直线给的起点位置与终点位置有关的。

推到这里就会发现原来全部都是高中数学知识,应该还做过题目来着。

2. 具体实现

具体的C++实现如下:

#include <iostream>
#include <string>
#include <vector>using namespace std;const double EPSILON = 0.0000000001;// 3D vector
struct Vector3d
{public:Vector3d(){}~Vector3d(){}Vector3d(double dx, double dy, double dz){x = dx;y = dy;z = dz;}// 矢量赋值void set(double dx, double dy, double dz){x = dx;y = dy;z = dz;}// 矢量相加Vector3d operator + (const Vector3d& v) const{return Vector3d(x + v.x, y + v.y, z + v.z);}// 矢量相减Vector3d operator - (const Vector3d& v) const{return Vector3d(x - v.x, y - v.y, z - v.z);}//矢量数乘Vector3d Scalar(double c) const{return Vector3d(c*x, c*y, c*z);}// 矢量点积double Dot(const Vector3d& v) const{return x * v.x + y * v.y + z * v.z;}// 矢量叉积Vector3d Cross(const Vector3d& v) const{return Vector3d(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);}bool operator == (const Vector3d& v) const{if (abs(x - v.x) < EPSILON && abs(y - v.y) < EPSILON && abs(z - v.z) < EPSILON){return true;}return false;}double x, y, z;
};//求解一元二次方程组ax*x + b*x + c = 0
void SolvingQuadratics(double a, double b, double c, vector<double>& t)
{double delta = b * b - 4 * a * c;if (delta < 0){return;}if (abs(delta) < EPSILON){t.push_back(-b / (2 * a));}else{t.push_back((-b + sqrt(delta)) / (2 * a));t.push_back((-b - sqrt(delta)) / (2 * a));}
}void LineIntersectSphere(Vector3d& O, Vector3d& E, Vector3d& Center, double R, vector<Vector3d>& points)
{Vector3d D = E - O;           //线段方向向量double a = (D.x * D.x) + (D.y * D.y) + (D.z * D.z);double b = (2 * D.x * (O.x - Center.x) + 2 * D.y * (O.y - Center.y) + 2 * D.z* (O.z - Center.z));double c = ((O.x - Center.x)*(O.x - Center.x) + (O.y - Center.y) * (O.y - Center.y) + (O.z - Center.z) * (O.z - Center.z)) - R * R;vector<double> t;SolvingQuadratics(a, b, c, t);for (auto it : t){ if (it >= 0 && it <= 1){points.push_back(O + D.Scalar(it));}       }
}int main()
{Vector3d O(20, 30, 40);Vector3d E(20, 20, 20); Vector3d Center(20, 20, 20);double R = 15;vector<Vector3d> points;LineIntersectSphere(O, E, Center, R, points);cout<<"该直线(线段)与球面有"<< points.size() <<"个交点"<<endl;for (auto it : points){printf("%lf\t%lf\t%lf\n", it.x, it.y, it.z);}
}

最终运行的结果:

再次注意,我这里是把线段当成直线判断的,如果希望判断整个直线与球面的交点,应该略去最后的关于ttt是否在0到1之间的判断,此时应该会有两个交点。

3. 参考

  1. 空间直线同球体交点求解

空间直线与球面相交算法相关推荐

  1. 空间射线与三角形相交算法的两种实现

    文章目录 1. 概述 2. 常规算法 2.1. 理论推导 2.2. 具体实现 3. 优化算法 3.1. 理论推导 3.2. 具体实现 4. 参考 1. 概述 任何复杂的三维模型都可以视作空间三角面片的 ...

  2. 基于带约束S型加减速曲线的空间直线插补与空间圆弧插补算法(Matlab)

    写在前面 学习代码都记录在个人github上,欢迎关注~ Matlab机器人工具箱版本9.10 在前面的博文中: 基于抛物线过渡(梯形加减速)的空间直线插补算法与空间圆弧插补算法(Matlab) 基于 ...

  3. 图形学 射线相交算法_计算机图形学中的阴极射线管(CRT)

    图形学 射线相交算法 什么是阴极射线管(CRT)? (What is Cathode Ray Tube (CRT)?) CRT stands for "Cathode Ray Tube&qu ...

  4. 【unity shader】unity游戏特效-仿《幽灵特警》生命扫描仪索敌效果(运用深度、相交算法、CommandBuffer)

    街机游戏<幽灵特警>第一关有个这样的效果: 嗯,透视挂hhhh,关键很炫. 来做个吧. 第一步,做"墙" 仔细观察GIF可见,这个效果像是一堵向前跑的墙,撞到无生命物体 ...

  5. Möller-Trumbore算法-射线三角形相交算法

    Möller-Trumbore算法 一.概述 二.准备知识 三.Möller-Trumbore 算法推导 推导过程 四.代码实现 一.概述 Möller-Trumbore 射线三角相交算法是一种快速计 ...

  6. 图形学 射线相交算法_计算机图形学中的彩色阴极射线管

    图形学 射线相交算法 彩色阴极射线管 (Color Cathode Ray Tube) CRT i.e. Cathode Ray Tubes are used to produce Color dis ...

  7. 【转载】空间直线同任意形状椭球交点

    空间直线同空间中三维椭球相交,其交点即为空间直线方程同椭球方程的解,对于空间直线方程,只要知道两点空间坐标即可,而欧拉角不为零的三维椭球方程则较难描述,但可以考虑对椭球进行变换,使其欧拉角为零,进而转 ...

  8. 图形学 射线相交算法_计算机图形学中的阴极射线管

    图形学 射线相交算法 阴极射线管 (Cathode Ray Tube) Ferdinand Barun of Strasbourg developed the cathode ray tube in ...

  9. 空间直线和三维物体之间的交线相关问题

    1.如何求空间直线在某一平面上的投影直线方程 https://zhidao.baidu.com/question/631349383625570644.html 2. 知道平面一点和平面法向量如何求平 ...

  10. 8.4 向量应用(二)——空间直线

    本篇内容接上篇,还是关于向量应用的内容.没有废话,直接来. 空间直线方程 (一)点向式方程(对称式方程) 从名字上看,点向式两个关键,一个是点,一个是向,点是直线上一点,向是直线的方向,或者是和直线方 ...

最新文章

  1. java中获取时间的方式,持续更新
  2. 百度地图 开发 乡镇级区域显示_Tableau导入乡镇级地图进行数据展示
  3. 【Java】不正当使用break语句的危害
  4. AbstractQueuedSynchronizer浅析——同步
  5. Windows Phone标准中文字体
  6. nodejs实战案例(Express框架+mongoDB)——(15)——爬虫功能
  7. 怎么样快速修改HOSTS文件?让火绒等小工具来帮忙
  8. html5手机详情页,H5网页打开app内部详情页
  9. 前方高能!Netflix推出《怪奇物语》VR体验
  10. 带您认识弱电工程中常见光纤接头,再也不用傻傻分不清楚
  11. Java中带有T Z格式(UTC是世界标准时间)的时间转换为date,string,long类型
  12. 华为p10 android保活,华为P10这八大细节,请看完之后决定要不要买!
  13. 【BZOJ】4292: [PA2015]Równanie
  14. ata职业技能评价证书考出来有啥用?
  15. cad拉伸怎么用_【cad比例缩放教程】cad缩放怎么用?
  16. 基于阿里云的超级性能测试 亿级企业压力测试神器JMeter4.X实战 抗压神器JMeter课程
  17. Latex排版 Chapter2格式调整(长度单位、字体、段落、页面、目录)
  18. serverAdd.sin_addr.s_addr
  19. 浙江省c语言二级的笔试真题及答案,浙江省高等学校C语言二级----笔试部分真题2007-2010年.doc...
  20. 计算机应用于软件等待预审,1系统架构-计算机应用与软件.doc

热门文章

  1. windows日志总结
  2. u检验中的查u界值表_u检验、t检验、F检验、X2检验
  3. 四招搞定托业(TOEIC)英语阅读
  4. php程序 导出表格文件后缀,PHPExcel生成Excel文件---提示导出文件或者文件扩展名不一致,或导出的文件或文件扩展名无效...
  5. java 全量_七、通过java代码实现增量、全量索引
  6. 下一跳配置的原则--ensp
  7. php 打水印,PHP 给图片制作水印的方法
  8. axio深入实例以及配置
  9. CUDA矩阵转置(共享内存 tile)
  10. 组建服务计算机我的电脑有个下三角,excel小三角怎么弄出来