Animation Principles
Easing functions specify the rate of change of a parameter over time. Linear interpolation (LERP) moves at a constant speed, whereas quadratic and cubic curves add natural acceleration and deceleration.
Interpolation Functions:
1def lerp(a, b, t):2 return a + t * (b - a)34def ease_in_quad(t):5 return t * t67def ease_out_quad(t):8 return t * (2 - t)910def ease_in_out_cubic(t):11 if t < 0.5:12 return 4 * t * t * t13 else:14 return 1 - ((-2 * t + 2) ** 3) / 2
Skeletal rigging links a continuous geometric mesh (the skin) to a hierarchical structure of joints (the skeleton). Linear Blend Skinning (LBS) deforms vertices by blending transformation matrices from multiple bones using vertex weights.
Skinning Controls:
1def linear_blend_skinning(v, bones, weights):2 # LBS formula: v_prime = sum( w_i * M_i * v_local )3 prime = Vector3(0, 0, 0)4 for i, bone in enumerate(bones):5 weight = weights[v.id][i]6 if weight > 0:7 # Transform vertex by bone's current matrix8 local_pos = bone.bind_pose_inverse * v.position9 world_pos = bone.current_transform * local_pos10 prime += weight * world_pos11 return prime
In 3D animation, objects transition between discrete coordinates called keyframes. While translations are interpolated linearly, interpolating rotations using Euler angles causes distortion and Gimbal Lock. Spherical Linear Interpolation (SLERP) on Quaternions resolves this by finding the shortest arc path.
Euler vs SLERP:
1def slerp(q0, q1, t):2 # Spherical Linear Interpolation between two quaternions3 cos_theta = q0.w * q1.w + q0.x * q1.x + q0.y * q1.y + q0.z * q1.z45 # If dot product is negative, reverse one quaternion to take shortest path6 if cos_theta < 0.0:7 q1 = -q18 cos_theta = -cos_theta910 if cos_theta > 0.9995:11 # Linear approximation for close rotations12 return normalize((1 - t) * q0 + t * q1)1314 theta = acos(cos_theta)15 sin_theta = sin(theta)16 w0 = sin((1 - t) * theta) / sin_theta17 w1 = sin(t * theta) / sin_theta18 return w0 * q0 + w1 * q1