用数学方法算基元碰撞检测 (5)

 

Line Segment & Plane

Line Seg:  P = P0 + t * V         t ∈ [0, 1]

Plane  :  N • P - N • Q = 0      (N is the normal of the plane,Q is some point on plane)

 

           N • (P0 + t * V) - N • Q = 0;

           N • (P0 – Q) + t * (N • V) = 0;

           t * (N • V) = N • (Q – P0);

 

           dp = N • V;

           if ( dp == 0 )             return Line Parallel to Plane;

 

           t = N • (Q – P0) / dp;

 

           if ( t >= 0 && t <= 1 )    return Intersectant;

 

 return No Intersection;

 

Point On Plane

Point:    P

Plane:     N • P - N • Q = 0

 

 d = N • (P – Q);

           if ( d == 0 )              return On Plane;

 

           returnNot On Plane;

 

Sphere & Plane

Sphere:   | P – C0 | <= R

Plane :    N • P - N • Q = 0

 

 d = N • (C0 – Q);

           if ( d^2 <= R^2 )              return Intersectant;

 

           returnNo Intersection;

 

Dynamic Sphere & Plane

Sphere:   | P – C0 | <= R

Delta :     C = C0 + t * V            t ∈ [0, 1]

Plane :    N • P - N • Q = 0

 

            //摘自Real Time Rendering

           d0 = N • (C0 – Q);        //t = 0

 d1 = N • (C0 + V – Q);    //t = 1

 

 if ( d0 * d1 > 0 && |d0| > R && |d1| > R ) return No Intersection;

 

 return Intersectant;

 //now we can evaluate t

 //if ( d0 == d1 )  Line Parallel to Plane, thent ∈ [0, 1]

 //else t = (d0 – R) / (d0 - d1);  here t must ∈ [0, 1]

 

Ellipsoid & Plane

Ellipsoid:    (x - x0)^2 / a^2 + (y - y0)^2 / b^2 + (z - z0)^2 / c^2 <= 1       (a>0, b>0, c>0)

Plane  :     N • P - N • Q = 0

 

   Assume:    F = (x - x0)^2 / a^2 + (y - y0)^2 / b^2 + (z - z0)^2 / c^2 – 1;

 

               For a given point T on a common ellipsoid, the normal M of the tangent plane is:

               M.x = ЭF/Эx = 2 * (T.x – x0) / a^2;

               M.y = ЭF/Эy = 2 * (T.y – y0) / b^2;

               M.z = ЭF/Эz = 2 * (T.z – z0) / c^2;

 

               Here M is not normalized. Now we normalize it:

               L = sqrt(M.x^2 + M.y^2 + M.z^2);

               N.x = 2 * (T.x – x0) / a^2 / L;

               N.y = 2 * (T.y – y0) / b^2 / L;

               N.z = 2 * (T.z – z0) / c^2 / L;

 

               N.x * L * a / 2 = (T.x – x0) / a;

               N.y * L * b / 2 = (T.y – y0) / b;

               N.z * L * c / 2 = (T.z – z0) / c;

 

 (N.x * L * a)^2 / 4 + (N.y * L * b)^2 / 4 +(N.z * L * c)^2 / 4 = 1;

 L^2 * ((N.x * a)^2 + (N.y * b)^2 +(N.z * c)^2) = 4;

 L = 2 / sqrt((N.x * a)^2 + (N.y * b)^2 +(N.z * c)^2);

 

   Assume:    K = sqrt((N.x * a)^2 + (N.y * b)^2 +(N.z * c)^2);

 

 T.x = x0 + L * N.x * a^2 / 2 = x0 + N.x * a^2 / K;

 T.y = y0 + L * N.y * b^2 / 2 = y0 + N.y * b^2 / K;

 T.z = z0 + L * N.z * c^2 / 2 = z0 + N.z * c^2 / K;

 

 P0 = {x0, y0, z0};

 dp = (P0 - T) • N = -((N.x * a)^2 + (N.y * b)^2 +(N.z * c)^2) / K = -K;

 dp^2 = (-K)^2 = (N.x * a)^2 + (N.y * b)^2 +(N.z * c)^2;

 D = (P0 - Q) • N;

 

 if ( D^2 <= dp^2 ) return Intersectant;

 

 returnNo Intersection;

 

Triangle & Plane

Triangle :    P0, P1, P2

Plane  :     N • P - N • Q = 0

 

               dp0 = N • (P0 - Q);

               dp1 = N • (P1 - Q);

               dp2 = N • (P2 - Q);

 

               if ( dp0 > 0 && dp1 > 0 && dp2 > 0 )   return No Intersection;

               if ( dp0 < 0 && dp1 < 0 && dp2 < 0 )   return No Intersection;

 

               return Intersectant;

 //the intersected line of triangle & plane can be evaluated by using proportion

 //for example: P0 is at the positive side of the plane, P1 & P2 are at the negative side

 //then dp0 >= 0, dp1 <= 0, dp2 <=0

 //if (dp0 == 0 && dp1 == 0 && dp2 == 0 ), then the triangle is on the plane, the intersected part is the triangle itself

 //else if (dp1 – dp0 == 0), then P0 & P1 are both on the Plane, the intersected line is P0 – P1

 //else if (dp2 – dp0 == 0), then P0 & P2 are both on the Plane, the intersected line is P0 – P2

 //else

 //assume E is the intersected point between (P0 – P1) & plane, F is the intersected point between (P0 – P2) & plane

 //so E = P1 + dp1 / (dp1 – dp0) * (P0 – P1)

 //so F = P2 + dp2 / (dp2 – dp0) * (P0 – P2)

 //and EF is the intersected line of triangle & plane

 

 

 

AABB & Plane

AABB :A  { V3d inf, sup;}

Plane :    N • P - N • Q = 0

 

           //摘自Real Time Rendering

 

           基本思想是计算AABB的8个顶点到平面的距离,如果都在同一侧,则表示没有相交,否则就有相交

           优化的方法就是找出沿平面法线方向离平面距离最近的两个顶点,这两个顶点是AABB的对角顶点,构成AABB四条对角线中的一条

 

 //这里Vmin和Vmax是按平面的方向N来说的,两个点到平面的带符号距离较大的就是Vmax

           for each i [x, y, z]

            {

               if ( N.i >= 0 )

                {

                Vmin.i = A.inf.i;

                Vmax.i = A.sup.i;

  }

  else

 {

                Vmax.i = A.inf.i;

                Vmin.i = A.sup.i;

 }

            }

 

            if ( N • (Vmin - Q) ) > 0 )   return No Intersection;

            if ( N • (Vmax - Q) ) < 0 )   return No Intersection;

 

 return Intersectant;

 

 

OBB & Plane

OBB :     {  V3d C, U, V, W;

  V3d L; }      //C是中心点坐标,U、V、W是三个轴方向,L的三个分量是U、V、W是三个方向的半长,表示Box长宽高各一半大小

Plane:     N • P - N • Q = 0

 

           //摘自Real Time Rendering

 

           D = (C - Q) • N;

           f = L.x * |N • U| + L.y * |N • V| + L.z * |N • W|;

 

           if ( D^2 > f^2 )   return No Intersection;

 

 return Intersectant;




阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/unknowm/article/details/752102
文章标签: 游戏 碰撞检测
个人分类: 游戏开发
上一篇用数学方法算基元碰撞检测 (4)
下一篇用数学方法算基元碰撞检测 (6)
想对作者说点什么? 我来说一句

碰撞检测中的包围盒算法

2011年09月21日 230KB 下载

没有更多推荐了,返回首页

关闭
关闭