刚体与墙面碰撞后线速度及角速度的求解方法问询
Hey there! I totally get how frustrating it is to piece together rigid body collision physics from scattered book chapters—let’s break this down step by step, no external libraries required. First, let’s fill in the missing parameters we need for a practical, solvable model (these are standard for basic rigid body simulations):
m: Rigid body mass (applies to both sphere and square)I: Moment of inertia (sphere:(2/5)mr²; square rotating about its center:(1/6)mr²)e: Coefficient of restitution (0 = perfectly inelastic collision, 1 = perfectly elastic; pick a value between 0-1 for realism)μ: Coefficient of friction (0 = no friction, >0 = sliding friction; controls how much rotation is induced by collision)- We’ll assume the wall is fixed, massless, and rigid (it won’t move or deform during collision)
1. Sphere-Wall Collision
First, calculate the wall’s unit normal vector n (points outward from the wall, toward the sphere):
// 2D calculation example const tangent = { x: W2.x - W1.x, y: W2.y - W1.y }; // Get perpendicular vector (clockwise; flip signs for counterclockwise if needed) const normal = { x: -tangent.y, y: tangent.x }; // Normalize to unit vector const mag = Math.sqrt(normal.x**2 + normal.y**2); const n = { x: normal.x/mag, y: normal.y/mag };
Break the sphere’s initial velocity V1 into normal (perpendicular to wall) and tangent (parallel to wall) components:
- Normal speed:
Vn = V1.x * n.x + V1.y * n.y(dot product) - Tangent velocity vector:
Vt = { x: V1.x - Vn*n.x, y: V1.y - Vn*n.y }
No Friction (μ=0)
- Normal velocity reverses and scales by restitution:
Vn2 = -e * Vn - Tangent velocity stays unchanged (no force to slow it down)
- Final linear velocity:
V2 = { x: Vn2*n.x + Vt.x, y: Vn2*n.y + Vt.y } - Angular velocity: No torque means no change →
R2 = R1
With Friction (μ>0)
Friction adds a tangential impulse that changes both linear and angular velocity:
- Calculate normal impulse (changes normal momentum):
Jn = m * (1 + e) * Math.abs(Vn) - Tangential impulse magnitude:
Jt = μ * Jn(direction opposes tangent velocity) - Update tangent velocity:
const tMag = Math.sqrt(Vt.x**2 + Vt.y**2); const t = { x: Vt.x/tMag, y: Vt.y/tMag }; // Unit tangent vector const deltaVt = { x: -Jt/m * t.x, y: -Jt/m * t.y }; const Vt2 = { x: Vt.x + deltaVt.x, y: Vt.y + deltaVt.y }; - Update angular velocity (friction creates torque around the sphere’s center):
Torqueτ = r * Jt(r is sphere radius), so angular change:deltaR = (r * Jt) / I
Final angular velocity:R2 = R1 + deltaR(direction depends on tangent velocity; adjust sign if needed) - Final linear velocity:
V2 = { x: -e*Vn*n.x + Vt2.x, y: -e*Vn*n.y + Vt2.y }
2. Square (Rigid Body)-Wall Collision
This is trickier because the collision point isn’t aligned with the square’s center, so even without friction, the collision will induce rotation.
First, calculate the wall’s unit normal n (same as sphere step). Then get the vector from the square’s center X2 to the collision point C:r_vec = { x: C.x - X2.x, y: C.y - X2.y }
Calculate the collision point’s initial velocity (combines linear and rotational motion):
// Rotational velocity at collision point: R1 × r_vec (2D equivalent) const rotVel = { x: -R1 * r_vec.y, y: R1 * r_vec.x }; const Vc1 = { x: V1.x + rotVel.x, y: V1.y + rotVel.y };
Break Vc1 into normal and tangent components:
- Normal speed:
Vcn1 = Vc1.x * n.x + Vc1.y * n.y - Tangent velocity vector:
Vct1 = { x: Vc1.x - Vcn1*n.x, y: Vc1.y - Vcn1*n.y }
No Friction (μ=0)
We need to solve for the normal impulse Jn that satisfies both momentum/angle momentum conservation and restitution:
- Derive
Jnusing the restitution rule (Vcn2 = -e * Vcn1, whereVcn2is post-collision normal speed atC):
The termJn = -Vcn1 * (1 + e) / (1/m + (r_vec.x*n.y - r_vec.y*n.x)**2 / I)(r_vec.x*n.y - r_vec.y*n.x)is the 2D cross product ofr_vecandn(measures the torque arm length). - Update linear velocity:
V2 = { x: V1.x + (Jn/m)*n.x, y: V1.y + (Jn/m)*n.y } - Update angular velocity:
const cross = r_vec.xn.y - r_vec.yn.x;R2 = R1 + (Jn * cross) / I
With Friction (μ>0)
Add a tangential impulse Jt (magnitude μ*Math.abs(Jn), direction opposite to Vct1):
- Calculate unit tangent vector
t(same as sphere step):const tMag = Math.sqrt(Vct1.x**2 + Vct1.y**2); const t = { x: Vct1.x/tMag, y: Vct1.y/tMag }; - Tangential impulse vector:
Jt_vec = { x: -μ*Math.abs(Jn)*t.x, y: -μ*Math.abs(Jn)*t.y } - Update linear velocity:
V2 = { x: V1.x + (Jn/m)*n.x + Jt_vec.x/m, y: V1.y + (Jn/m)*n.y + Jt_vec.y/m } - Update angular velocity (torque from tangential impulse):
const crossT = r_vec.xJt_vec.y - r_vec.yJt_vec.x;R2 = R1 + crossT / I
Quick Note on Your Book Reference
I’ve worked through Physics for JavaScript Games, Animation, and Simulations too—you’re right, the rigid body collision content is spread out across chapters on momentum, angular momentum, and collision detection. The formulas above tie directly to the book’s explanations of impulse-momentum theorem and angular momentum conservation; if you flip back to those sections, you’ll see how the pieces connect.
内容的提问来源于stack exchange,提问作者Lu4

