class Physics { static checkCircleCollision(pos1, radius1, pos2, radius2) { const distance = pos1.distance(pos2); return distance < (radius1 + radius2); } static resolveCircleCollision(obj1, obj2) { const distance = obj1.position.distance(obj2.position); const minDistance = obj1.radius + obj2.radius; if (distance < minDistance) { const overlap = minDistance - distance; const direction = obj2.position.subtract(obj1.position).normalize(); const separation = direction.multiply(overlap * 0.5); obj1.position = obj1.position.subtract(separation); obj2.position = obj2.position.add(separation); const relativeVelocity = obj2.velocity.subtract(obj1.velocity); const speed = relativeVelocity.dot(direction); if (speed > 0) return; const restitution = Math.min(obj1.restitution || 0.8, obj2.restitution || 0.8); const impulse = 2 * speed / (obj1.mass + obj2.mass); obj1.velocity = obj1.velocity.add(direction.multiply(impulse * obj2.mass * restitution)); obj2.velocity = obj2.velocity.subtract(direction.multiply(impulse * obj1.mass * restitution)); } } static checkPointInRectangle(point, rect) { return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height; } static checkCircleRectangleCollision(circle, rect) { const closestX = Math.max(rect.x, Math.min(circle.x, rect.x + rect.width)); const closestY = Math.max(rect.y, Math.min(circle.y, rect.y + rect.height)); const distance = new Vector2(circle.x - closestX, circle.y - closestY).magnitude(); return distance < circle.radius; } static applyFriction(velocity, friction, deltaTime) { const speed = velocity.magnitude(); if (speed > 0) { const frictionForce = speed * friction * deltaTime; if (frictionForce >= speed) { return new Vector2(0, 0); } else { return velocity.subtract(velocity.normalize().multiply(frictionForce)); } } return velocity; } static wrapAngle(angle) { while (angle > Math.PI) angle -= 2 * Math.PI; while (angle < -Math.PI) angle += 2 * Math.PI; return angle; } static lerp(start, end, t) { return start + (end - start) * t; } }