3DGIS(3D GIS)

研究OpenGL,DirectX 3D,GPU和GIS

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
 

继续上一节的内容,本节主要讲解三维空间中射线、线段与平面及三维物体的交点及距离的计算,它们在碰撞检测和可见性剔除等应用中是必不可少的。首先给出3D空间下点乘和叉乘的定义与定理的推导,再谈如何应用到程序编码的工作中。

设三维空间中任意两矢量V(v1v2v3)W(w1w2w3)

                                                                                                                                    
               由三角形的余弦公式:

                                      cosα = (a2 + b2 – c2)2ab

               则两矢量夹角α的余弦 cosα = {(v1*v1 + v2*v2 + v3*v3) + (w1*w1+w2*w2+w3*w3) [ (w1 v1)2+( w2 v2)2+( w3 v3)2] } / 2 |V| |W| = (v1w1+ v2w2 + v3w3)/ |V| |W|

               由于将矢量的点乘定义为 V·W = v1w1+ v2w2 + v3w3

               所以 |V| |W| cosα = V·W

               由上面的结论引申,可知道如果两矢量的点乘为0,则说明夹角α的余弦为0,即矢量的夹角是90度,互相垂直。

               再来看两矢量的叉乘,与点乘的计算结果定义为一数值不同,叉乘的结果定义为另外一个矢量 U (u1u2u3) ,其中:

                                             u1 = v2w3 v3w2

                                             u2 = v3w1 v1w3

                                             u3 = v1w2 v2w1

               由这个定义我们来推导:

               V·U = v1(v2w3 v3w2) + v2(v3w1 v1w3) + v3(v1w2 v2w1) = v1v2w3 v1 v3w2 + v2v3w1v2 v1w3 + v3v1w2v3 v2w1 = 0;两矢量的点乘为0,说明它们互相垂直。

               W·U = w1(v2w3 v3w2) + w2(v3w1 v1w3) + w3(v1w2 v2w1) = 0,说明它们也是互相垂直的。

               在三维空间中,UVW都垂直,说明U是垂直与VW构成的平面,也就是这个平面的法向量。

               U虽然是矢量,但其模|U|依旧是一个数值,表明其长度。

               |U|2 = u1*u1 + u2*u2 + u3*u3 = (v2w3 v3w2)2+( v3w1 v1w3)2+( v1w2 v2w1)2

               同时考虑,在αVW两矢量的夹角条件下,(|V| |W|sinα)2= |V|2|W|21cos2α= |V|2|W|2 |V|2|W|2cos2α = |V|2|W|2 - (V·W)2= (v1*v1 + v2*v2 + v3*v3)( w1*w1+w2*w2+w3*w3) (v1w1+ v2w2 + v3w3)2

               通过化解,可以得到一个数学等式,即:

               bzcy2+(cx-az)2+(ay-bx)2=a2+b2+c2)(x2+y2+z2-(ax+by+cz)2

               所以 (v2w3 v3w2)2+( v3w1 v1w3)2+( v1w2 v2w1)2  = (v1*v1 + v2*v2 + v3*v3)( w1*w1+w2*w2+w3*w3) (v1w1+ v2w2 + v3w3)2

                                         |U|2 = (|V| |W|sinα)2

                                    |U| = |V| |W|sinα

            在完成三维空间的点乘和叉乘定义与公式推导后,可以直接运用结论到程序的编写中,这些结论包括利用点乘来求得夹角的余弦,利用点乘为0来求得垂直于某向量的另一向量,利用两向量的叉乘来求得平面的法向量,利用叉乘的模来求得三角形的面积等。

            三维空间中点到直线、射线和线段的距离。即从点P作垂直于线段(P0,P1)的垂线,求得垂心T后,计算两点之间的距离。

                                                   

          设置T点为参数表达方式: T = P0 + t(P1 –P0);将T点看作是从P0开始往P1移动的动态点,则矢量PT为PP0与P0T两个矢量之和,当PT垂直于P0P1时,利用两个矢量的点乘为0列等式,求得参数t的数值。

                       (PP0 + P0T) ·P1P0 = 0;

                              P-P0·(P1 –P0) + t(P1 –P0) ·(P1 –P0) = 0;

                       t = - P-P0·(P1 –P0) / (P1 –P0) ·(P1 –P0)

        可以看出分子是需要计算两个矢量的点乘,而分母是矢量P0P1点乘自身,即为模的平方。

double CDEMAlgorithm::dist_Point_to_Line( Point P, Line L)

{

    Vector v = L.P1 - L.P0;                                     //顶点相减得到矢量

    Vector w = P - L.P0;                                    //顶点相减得到矢量

    double c1 = Dot(w,v);                                   //两矢量的点乘

    double c2 = Dot(v,v);                                   //两矢量的点乘

    double b = c1 / c2;                                     //求得参数

    Point Pb = L.P0 + b * v;                                //解得参数后,得到垂心位置

    return d(P, Pb);                                        //返回两点之间的距离

}

posted on 2008-03-08 10:39  武汉侯涛  阅读(1707)  评论(1编辑  收藏  举报