射线和圆的相交

射线和圆相交有两个办法

  1. 解联立方程式
  2. 通过点到直线距离计算

解联立方程式

射线方程,点向式,参数方程应该是从屏幕坐标算出来的方向向量直接构成的。
计算过程参考之前写的博文,http://blog.csdn.net/goteet/article/details/8259030。
摄像机位置为Po, 选取点可以得到射线方向Dir。这里简述一下。

简述picking

Po为摄像机位置的原点 vec3 Origin(0, 0, 0), 
鼠标选取点反投影到齐次控件,根据投影矩阵算出视矩阵坐标:

View.z = Zn;  
View.x = Proj.x * Zn / xScale = Zn * Proj.x / matrixProj._m11;  
View.y = Proj.y * Zn / yScale = Zn * Proj.y / matrixProj._m22;
//一般设Zn = 1.0,则
view = vec3(Proj.x / matProj._11, Proj.y / matProj._22, 1.0);

则,射线 DirView = view - origin = view;
通过  matrixView 的逆矩阵,把Origin和Dir变换回世界空间坐标,有:
 Po = vec4(Origin, 1.0f) * matrix_view_inverse;
 Dir = vec4(DirView, 0.0f) * matrx_view_inverse;

Po.x = 0 + 0 + 0 + matViewInv._41;
Po.y = 0 + 0 + 0 + matViewInv._42;
Po.z = 0 + 0 + 0 + matViewInv._43;

Dir.x = DirView.x * matViewInv._11 + DirView.y * matViewInv._21 + DirView.z * matViewInv._31;
Dir.y = DirView.x * matViewInv._12 + DirView.y * matViewInv._22 + DirView.z * matViewInv._33;
Dir.z = DirView.x * matViewInv._13 + DirView.y * matViewInv._23 + DirView.z * matViewInv._33;
// row * col

解方程式

最后射线方程得到:Ray = Po + t x Dir;
圆的方程自己写啦,比如:  Sphere=P^2 = R^2 或者  (P - Po)^2 = R^2;
联立两个方程,我按照圆点在中心的方程联立的,就有:(表示点P即在Ray上,又在Sphere上)
Ray^2 = R^2 =>   (Po + t x Dir)^2 = R^2。求t,按照 t 来张开
得到一元二次方程,dot(Dir, Dir) x t^2 + 2xdot(Dir, Po) x t +  dot(Po,Po) = R^2,
a = dot(Dir, Dir)
b = 2dot(Dir, Po);
c = dot(Po,Po);
则,百度了一下,判别式 discriminant = b^2 - 4ac >= 0 有解。解为( -b ± discriminant ) / 2a
判断 b  > 0 则近点选取为   (dis -b) / 2a, done.

代码可以看叶蔚大大的链接,不过好像azure.com.cn关了,去opengpu搜一下  azure  射线 球

点到直线距离计算

数学基础

这个办法是从 3D.Math.Primer.for.graphics.and.game.development 上看来的,图什么的也都在上面。给个链接先:
http://www.verycd.gdajie.com/topics/2867783/  G大姐,你懂的。

然后给个直线数学基础的链接。
http://kcpt.niit.edu.cn:8080/skills/portal/displayItem/502663/%E7%AC%AC5%E7%AB%A0%E7%A9%BA%E9%97%B4%E8%A7%A3%E6%9E%90%E5%87%A0%E4%BD%95%E4%B8%8E%E5%A4%8D%E6%95%B0.htm(http://kcpt.niit.edu.cn:8080/skills/portal/displayItem/502663/第5章空间解析几何与复数.htm)

算法

那本书里的算法,你看看这个就好啦:http://blog.csdn.net/rabbit729/article/details/4285119

说说2d到3d的拓展

上面的算法是2d的,主要问题就是怎么通过参数方程把点法式做出来,不然算点到直线距离比较麻烦。这里给个思路:
首先是三维中,一个向量的法向量有很多的,这些法向量分布在一个平面上(平面的法向量与此向量平行)。
所以说先要确定是法向量所在的平面,注意上图中点到射线的距离,他们都在同一个平面上,因此,做点P到射线的投影Q
PQ所组成的向量就是这条射线的法向量之一,也正好能够算出点到直线距离,如何找到这条法向量?
设射线一点O,不与P重合,有OP, OQ。 v= cross(OP, OQ)得到垂直于OP,OQ的向量v,v为射线的法向量之一!然后
n = cross(v, OP),得打  OPQ平面上的法向量n, 则,得到直线点法式   (P - Po)n = 0;
pn - dot(Po,n) = 0

或者:做P在射线上的投影,得到t的值。  因为Q =  Po + t * Dir;  所以t = PoQ.length;
PoQ正好是PoP的投影,内积 t =  dot(PoP, Dir);
n =  PoP -  PoQ = PoP - Po - dot(PoP, Dir) x Dir;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值