计算空间两个平面的交线,用的到原理是:
第一步通过两个平面法线的叉乘( cross(...) )得到交线的切向。
第二步通过平面方程:pnv.dot(pv) = pd,pv为平面上的任意一点。则pnv乘以pd,就能得到这个平面上的一点。
第三步计算出位于交线上的点,至此,就可以得到这个交线。
在运算中尽量不要产生新对象,以下方法中之所以用新对象是为了方便,如果你会用到下面的方法,请自己优化。
用到的planeAndSLIntersectionV(...),方法请见:
http://www.cnblogs.com/vilyLei/articles/2195156.html
此实现原理和语言无关,只基于几何原理
基于as3的实现代码如下:
/* *
* 符合右手定则的叉乘: dest = v1 x v2
* @param dest 叉乘的结果
* @param v1 叉乘的第一个参数
* @param v2 叉乘的第二个参数
* */
public function cross(dest:Vector3D, v1:Vector3D, v2:Vector3D): void{
dest.x=v1.y*v2.z-v1.z*v2.y;
dest.y=v1.z*v2.x-v1.x*v2.z;
dest.z=v1.x*v2.y-v1.y*v2.x;
}
/* *
* 计算3d空间两个平面相交直线,得到的直线数据为: 直线的切向ltv和直线上的一点lpv
* @param panv 空间平面a的法线的单位矢量
@param pad 空间平面a的参数距离,平面的方程为: pnv.dot( pv ) = pd
@param pbnv 空间平面b的法线的单位矢量
@param pbd 空间平面b的参数距离,平面的方程为: pnv.dot( pv ) = pd
@param ltv 两个平面交线的切向
@param lv 两个平面交线上的一点
*
* */
public function pAndPIntersectionLine(panv:Vector3D, pad:Number, pbnv:Vector3D, pbd:Number, ltv:Vector3D, lv:Vector3D): void {
// 计算出两条法线的叉积,即为交线的切向
cross(ltv, panv, pbnv);
ltv.normalize();
// 计算平面a上的一点
var pav:Vector3D = new Vector3D();
pav.x = pad * panv.x;
pav.y = pad * panv.y;
pav.z = pad * panv.z;
var tnv:Vector3D = new Vector3D();
// 计算出在平面a上的,垂直于交线ltv的直线的切向
cross(tnv, ltv, panv);
// 计算由pav和tnv决定的直线和平面b的交点,这个交点就是两个平面交线上的一点
planeAndSLIntersectionV(pbnv, pbd, tnv, pav, lv);
}
//