calculate_magnus_force
Compute the Magnus force vector and magnitude for a spinning ball moving through a fluid, enabling analysis of curved motion in sports or aerodynamics.
Instructions
Calculate Magnus force on a spinning ball.
The Magnus force is perpendicular to both velocity and spin axis.
Causes curve balls in sports.
Args:
velocity: Ball velocity [x, y, z] in m/s (or JSON string)
angular_velocity: Angular velocity [x, y, z] in rad/s (or JSON string)
radius: Ball radius in meters
fluid_density: Fluid density in kg/m³ (air=1.225)
Returns:
Dict containing:
- magnus_force: Magnus force vector [x, y, z] in Newtons
- magnus_force_magnitude: Force magnitude in Newtons
- spin_rate: Spin rate (angular velocity magnitude) in rad/s
Example - Soccer ball curve:
result = await calculate_magnus_force(
velocity=[20, 0, 0], # 20 m/s forward
angular_velocity=[0, 0, 50], # 50 rad/s topspin
radius=0.11, # Soccer ball
fluid_density=1.225
)Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| velocity | Yes | ||
| angular_velocity | Yes | ||
| radius | Yes | ||
| fluid_density | No |
Implementation Reference
- Core implementation of calculate_magnus_force - calculates Magnus force on a spinning ball using F ≈ (1/2) * ρ * π * r³ * (ω × v). Returns Magnus force vector, magnitude, and spin rate.
def calculate_magnus_force(request: MagnusForceRequest) -> MagnusForceResponse: """Calculate Magnus force on a spinning ball. The Magnus force is perpendicular to both the velocity and spin axis. F_magnus ∝ ω × v Simplified model: F ≈ (1/2) ρ π r³ |ω × v| Args: request: Magnus force request Returns: Magnus force vector """ rho = request.fluid_density r = request.radius v = request.velocity omega = request.angular_velocity # Magnus force is proportional to ω × v cross = _cross_product(omega, v) # Magnitude of spin spin_rate = _vector_magnitude(omega) # Simplified Magnus force coefficient # F ≈ (1/2) * ρ * π * r³ * |ω × v| coeff = 0.5 * rho * math.pi * (r**3) magnus = [coeff * c for c in cross] magnitude = _vector_magnitude(magnus) return MagnusForceResponse( magnus_force=magnus, magnus_force_magnitude=magnitude, spin_rate=spin_rate, ) - MCP tool endpoint for calculate_magnus_force - decorated with @tool, handles input parsing (lists/JSON strings), constructs MagnusForceRequest, calls the core handler from fluid_advanced, and returns serialized response.
@tool # type: ignore[arg-type] async def calculate_magnus_force( velocity: Union[list[float], str], angular_velocity: Union[list[float], str], radius: float, fluid_density: float = 1.225, ) -> dict: """Calculate Magnus force on a spinning ball. The Magnus force is perpendicular to both velocity and spin axis. Causes curve balls in sports. Args: velocity: Ball velocity [x, y, z] in m/s (or JSON string) angular_velocity: Angular velocity [x, y, z] in rad/s (or JSON string) radius: Ball radius in meters fluid_density: Fluid density in kg/m³ (air=1.225) Returns: Dict containing: - magnus_force: Magnus force vector [x, y, z] in Newtons - magnus_force_magnitude: Force magnitude in Newtons - spin_rate: Spin rate (angular velocity magnitude) in rad/s Example - Soccer ball curve: result = await calculate_magnus_force( velocity=[20, 0, 0], # 20 m/s forward angular_velocity=[0, 0, 50], # 50 rad/s topspin radius=0.11, # Soccer ball fluid_density=1.225 ) """ from ..fluid_advanced import MagnusForceRequest, calculate_magnus_force as calc_magnus parsed_velocity = json.loads(velocity) if isinstance(velocity, str) else velocity parsed_angular_velocity = ( json.loads(angular_velocity) if isinstance(angular_velocity, str) else angular_velocity ) request = MagnusForceRequest( velocity=parsed_velocity, angular_velocity=parsed_angular_velocity, radius=radius, fluid_density=fluid_density, ) response = calc_magnus(request) return response.model_dump() - MagnusForceRequest Pydantic model - input schema with velocity, angular_velocity, radius, and fluid_density fields.
class MagnusForceRequest(BaseModel): """Request for Magnus force calculation (spinning ball in fluid).""" velocity: list[float] = Field(..., description="Ball velocity [x, y, z] in m/s") angular_velocity: list[float] = Field( ..., description="Angular velocity [x, y, z] in rad/s (spin)" ) radius: float = Field(..., description="Ball radius in meters", gt=0.0) fluid_density: float = Field( default=1.225, description="Fluid density in kg/m³ (air=1.225)", gt=0.0 ) - MagnusForceResponse Pydantic model - output schema with magnus_force vector, magnus_force_magnitude, and spin_rate fields.
class MagnusForceResponse(BaseModel): """Response for Magnus force calculation.""" magnus_force: list[float] = Field(..., description="Magnus force vector [x, y, z] in Newtons") magnus_force_magnitude: float = Field(..., description="Magnus force magnitude in Newtons") spin_rate: float = Field(..., description="Spin rate (angular velocity magnitude) in rad/s") - Helper functions used by calculate_magnus_force: _vector_magnitude and _cross_product.
def _vector_magnitude(v: list[float]) -> float: """Calculate magnitude of a vector.""" return math.sqrt(sum(x * x for x in v)) def _cross_product(a: list[float], b: list[float]) -> list[float]: """Calculate cross product a × b.""" return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], ]