原文地址:https://blog.csdn.net/q493201681/article/details/80541754
这个是面试官经常考的一个问题,我们先把它变成一个数学问题。
已知一个平面上的一点P0和法向量n,一条直线上的点L0和方向L,求该直线与该平面的交点P
如下图
首先我们分析一下我们知道平面和直线的法向量,知道平面和直线上的一点,求直线与平面上的交点p。
这里我们就要引入点积的概念。点积的几何意义(百度百科直接粘的)
设二维空间内有两个向量
和
,它们的夹角为
,则内积定义为以下实数: [2]
该定义只对二维和三维空间有效。
这个运算可以简单地理解为:在点积运算中,第一个向量投影到第二个向量上(这里,向量的顺序是不重要的,点积运算是可交换的),然后通过除以它们的标量长度来“标准化”。这样,这个分数一定是小于等于1的,可以简单地转化成一个角度值。
简单点来说当我们使用Vector3.Dot来处理两个标准化的向量的时候会得到两个向量角度的COS值。
也就是说如果两个向量垂直的话,cos值为0,也就是说两个向量垂直的话点积为0.
而p和po组成的直线肯定与平面法向量n垂直。
这里我们就能推倒出已知的公式1:(p-p0)*n=0
而由于交点p是属于直线上的一点,所以我们能推倒出公式2:P=L0+dL;
然后我们把公式2导入到公式1得到:
(L0+dL-P0)*n=0
(L0-P0)*n+dL*n=0(点乘满足分配率)
(p0-L0)*n=dL*n
d=(p0-L0)*n/L*n(点乘满足结合律)
只要我们求出d的值带入公式2就能求出交点P.
/// <summary>
/// 计算直线与平面的交点
/// </summary>
/// <param name="point">直线上某一点</param>
/// <param name="direct">直线的方向</param>
/// <param name="planeNormal">垂直于平面的的向量</param>
/// <param name="planePoint">平面上的任意一点</param>
/// <returns></returns>
private Vector3 GetIntersectWithLineAndPlane(Vector3 point, Vector3 direct, Vector3 planeNormal, Vector3 planePoint)
{
float d = Vector3.Dot(planePoint - point, planeNormal) / Vector3.Dot(direct.normalized, planeNormal);
return d * direct.normalized + point;
}