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

本文详细介绍了不同几何体(包括线段、点、球体、动态球体、椭球体、三角形、AABB、OBB等)与平面之间的碰撞检测算法。通过数学公式推导,清晰地展示了如何判断这些几何体是否与平面相交。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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;




<think>我们被要求解释一个数学表达式,该表达式来自Pollard-Rho法中用于离散对数的部分。表达式如下: \[ x_{i+1} = \begin{cases} g \cdot x_i & \text{if } x_i \in S_0 \\ x_i^2 & \text{if } x_i \in S_1 \\ h \cdot x_i & \text{if } x_i \in S_2 \end{cases} \] 这是一个分段函数,用于定义序列中下一个元素的值,取决于当前元素属于哪个子集。 ### 详细解释 1. **上下文**:在Pollard-Rho法中,这个函数用于生成一个伪随机序列,目的是在循环群中寻找离散对数的解。群被划分为三个互不相交的子集 \( S_0, S_1, S_2 \),且它们的并集是整个群。 2. **变量含义**: - \( g \):群的生成元(或基元)。 - \( h \):群中的另一个元素,即我们需要求解离散对数的元素(例如 \( h = g^a \) 中的 \( h \))。 - \( x_i \):序列中第 \( i \) 个元素,它是群中的一个元素。 - \( S_0, S_1, S_2 \):将群分为三个大小相近的子集(通常随机划分或按某种规则划分)。 3. **函数行为**: - 如果当前元素 \( x_i \) 属于子集 \( S_0 \),则下一个元素 \( x_{i+1} \) 被设置为 \( g \cdot x_i \)(即用生成元 \( g \) 乘以当前元素)。 - 如果 \( x_i \) 属于子集 \( S_1 \),则下一个元素是当前元素的平方 \( x_i^2 \)。 - 如果 \( x_i \) 属于子集 \( S_2 \),则下一个元素是 \( h \cdot x_i \)(即用元素 \( h \) 乘以当前元素)。 4. **目的**:通过这种迭代,序列会进入一个循环(rho形的序列),然后通过碰撞检测(如Floyd环检测法)来找到两个不同的索引 \( i \) 和 \( j \) 使得 \( x_i = x_j \)。利用这个碰撞,我们可以建立一个关于离散对数的方程,从而求解。 5. **数学基础**:每个元素 \( x_i \) 都可以表示为 \( g^{a_i} h^{b_i} \) 的形式,其中 \( a_i \) 和 \( b_i \) 是整数。迭代规则会相应地更新这些指数: - 若 \( x_i \in S_0 \),则 \( x_{i+1} = g \cdot x_i = g^{a_i+1} h^{b_i} \)。 - 若 \( x_i \in S_1 \),则 \( x_{i+1} = x_i^2 = g^{2a_i} h^{2b_i} \)。 - 若 \( x_i \in S_2 \),则 \( x_{i+1} = h \cdot x_i = g^{a_i} h^{b_i+1} \)。 当发生碰撞 \( x_i = x_j \) 时,我们有 \( g^{a_i} h^{b_i} = g^{a_j} h^{b_j} \),即 \( g^{a_i - a_j} = h^{b_j - b_i} \)。由于 \( h = g^k \)(k为离散对数),所以 \( a_i - a_j \equiv k (b_j - b_i) \pmod{\text{群的阶}} \)。如果 \( b_j - b_i \) 与群的阶互质,则可以解出 \( k \)。 ### 注意事项 - 该法是概率性的,可能需要多次尝试。 - 子集的划分应尽可能均匀,以保证序列的随机性。 - 在实现中,我们同时追踪指数(即 \( a_i, b_i \))的更新,以便在碰撞时建立方程。 ### 示例 假设在模 \( p \) 的乘法群中,\( g \) 是生成元,\( h = g^k \mod p \)。我们随机划分群元素为三个子集。从一个随机点 \( x_0 = g^{a_0} h^{b_0} \) 开始,然后按照上述规则迭代,直到找到碰撞。 --- §§相关问题§§ 1. 在离散对数的Pollard-Rho法中,如何选择子集 \( S_0, S_1, S_2 \) 的划分方式? 2. 为什么在发生碰撞 \( x_i = x_j \) 时,我们能够建立关于离散对数的方程? 3. 如何通过追踪指数 \( (a_i, b_i) \) 来避免在每次迭代时重新计整个序列的指数? 4. Pollard-Rho法求解离散对数时,如何处理当 \( b_j - b_i \) 与群的阶不互质的情况? 5. 与传统的Baby-Step Giant-Step法相比,Pollard-Rho法在空间复杂度上有何优势?</think>### 数学表达式解析:Pollard-Rho法的离散对数迭代函数 给定表达式为离散对数求解中的核心迭代函数: \[ x_{i+1} = \begin{cases} g \cdot x_i & \text{if } x_i \in S_0 \\ x_i^2 & \text{if } x_i \in S_1 \\ h \cdot x_i & \text{if } x_i \in S_2 \end{cases} \] #### 数学含义详解 1. **变量定义**: - \(x_i\):第 \(i\) 步的当前状态(群元素) - \(g\):循环群的生成元(固定元素) - \(h\):目标元素(需解 \(g^k = h\) 中的 \(h\)) - \(S_0, S_1, S_2\):群的三等分互斥子集(满足 \(S_0 \cup S_1 \cup S_2 = G\)) 2. **操作逻辑**: - **乘法分支**(\(g \cdot x_i\)):当 \(x_i \in S_0\) 时,用生成元 \(g\) 更新状态 - **平方分支**(\(x_i^2\)):当 \(x_i \in S_1\) 时,对当前元素做平方运 - **目标分支**(\(h \cdot x_i\)):当 \(x_i \in S_2\) 时,用目标元素 \(h\) 更新状态 3. **指数追踪原理**: 每个 \(x_i\) 可表示为 \(x_i = g^{a_i} h^{b_i}\),迭代过程同步更新指数: - 若选 \(g \cdot x_i\):则 \(a_{i+1} = a_i + 1,\ b_{i+1} = b_i\) - 若选 \(x_i^2\):则 \(a_{i+1} = 2a_i,\ b_{i+1} = 2b_i\) - 若选 \(h \cdot x_i\):则 \(a_{i+1} = a_i,\ b_{i+1} = b_i + 1\) #### 法工作流程 ```python def pollard_rho_dlog(g, h, p, group_order): # 初始化随机起点和指数 x0 = pow(g, random_int(), p) # x0 = g^a0 a0, b0 = random_int(), 0 x = x0; a = a0; b = b0 # 定义子集划分函数(示例:按元素值模3划分) def get_subset(x): if x % 3 == 0: return 0 elif x % 3 == 1: return 1 else: return 2 # 迭代直到碰撞 for i in range(group_order): subset = get_subset(x) if subset == 0: x = (g * x) % p # x_{i+1} = g·x_i a = (a + 1) % group_order elif subset == 1: x = (x * x) % p # x_{i+1} = x_i^2 a = (2 * a) % group_order b = (2 * b) % group_order else: x = (h * x) % p # x_{i+1} = h·x_i b = (b + 1) % group_order # 碰撞检测(略) ``` #### 数学特性分析 | 操作类型 | 代数结构变化 | 群作用效果 | |----------------|--------------------|--------------------| | \(g \cdot x_i\) | 线性增长(+1) | 沿群生成方向移动 | | \(x_i^2\) | 指数增长(×2) | 加速遍历群元素 | | \(h \cdot x_i\) | 引入目标关联 | 绑定目标元素关系 | **碰撞方程**:当检测到 \(x_i = x_j\) 时,由 \(g^{a_i}h^{b_i} \equiv g^{a_j}h^{b_j}\) 导出: \[ k \equiv \frac{a_i - a_j}{b_j - b_i} \pmod{\text{群阶}} \] (需 \(b_j \neq b_i \pmod{\text{群阶}}\)) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值