import React from 'react'; import { differentialState } from '../../../animations/mechanics'; import type { MachineAnimationModule } from '../../../animations/types'; import { MachinePart, Shaft, ToothedGear, } from './primitives'; import { EngineeringBaseplate, PartLabels, getPartVisualProps, } from './proceduralSceneHelpers'; import type { ProceduralMachineDefinition, ProceduralMachineModule, ProceduralMachineSceneProps, } from './types'; const definition: ProceduralMachineDefinition = { id: 'differential-gear', slug: 'differential-gear', title: 'Differential Gear', subtitle: 'Torque split with speed difference during cornering', category: 'Gearboxes & Drives', difficulty: 'Intermediate', summary: 'A bevel-gear differential showing ring input, rotating carrier, spider gears, and unequal axle speeds.', description: 'The differential lets drive wheels rotate at different speeds while still transmitting torque. During straight-line travel both side gears rotate together; during a turn spider gears rotate on their pin and allow one axle to overrun the other.', keywords: ['differential', 'bevel gear', 'axle', 'cornering', 'torque split'], complexity: 7, dateAdded: '2025-02-04', typicalRpm: 'Wheel speed 0–1,500 RPM', facts: [ { label: 'Purpose', value: 'Equal torque, variable speed', detail: 'An open differential sends equal torque to both axles while allowing different angular speeds.', }, { label: 'Key event', value: 'Spider gears spin only with speed difference', detail: 'When both wheels rotate equally the spider gears orbit without spinning on their own axes.', }, { label: 'Common location', value: 'Drive axle final drive', detail: 'Used in rear axles, front transaxles, and transfer cases.', }, { label: 'Limitation', value: 'Low-traction wheel limits torque', detail: 'Limited-slip or locking differentials address this open-differential drawback.', }, ], parts: [ { id: 'ring-gear', name: 'Crown ring gear', description: 'Large bevel/crown gear driven by the pinion, rotating the differential carrier.', labelPosition: [0.1, 1.25, 0.9], material: 'Case-hardened steel', }, { id: 'pinion-gear', name: 'Drive pinion', description: 'Small input gear from the prop shaft that drives the ring gear.', labelPosition: [-1.55, -0.72, 0.75], }, { id: 'carrier', name: 'Differential carrier', description: 'Rotating cage that holds the spider pin and carries the ring gear.', labelPosition: [0, -1.28, 0.85], }, { id: 'left-side-gear', name: 'Left side gear', description: 'Bevel gear splined to the left axle shaft.', labelPosition: [-1.32, 0.45, 0.75], }, { id: 'right-side-gear', name: 'Right side gear', description: 'Bevel gear splined to the right axle shaft.', labelPosition: [1.32, 0.45, 0.75], }, { id: 'spider-gears', name: 'Spider gears', description: 'Small bevel gears carried by the rotating cage that mediate axle speed difference.', labelPosition: [0.15, 0.72, 0.95], }, { id: 'left-axle', name: 'Left axle', description: 'Output shaft to the left wheel.', labelPosition: [-2.2, -0.35, 0.62], }, { id: 'right-axle', name: 'Right axle', description: 'Output shaft to the right wheel.', labelPosition: [2.2, -0.35, 0.62], }, { id: 'housing', name: 'Axle housing', description: 'Stationary casing and bearings supporting the final drive.', labelPosition: [0, -1.7, 0.5], defaultOpacity: 0.34, }, ], cameraPresets: [ { id: 'iso', label: 'Isometric', position: [4.4, 2.5, 4.1], target: [0, 0, 0], fov: 42 }, { id: 'front', label: 'Axle split', position: [0, 0.8, 5.4], target: [0, 0, 0], fov: 38 }, { id: 'pinion', label: 'Pinion mesh', position: [-4.4, 1.2, 2.6], target: [-0.2, 0, 0], fov: 42 }, ], tour: { id: 'tour-differential-gear', machineId: 'differential-gear', title: 'Why wheels need a differential', description: 'Observe the carrier, side gears, and spider gears during straight-line and cornering states.', steps: [ { id: 'final-drive', title: 'Pinion drives the ring', body: 'Input torque arrives through the pinion and turns the ring gear bolted to the carrier.', durationSeconds: 4, partIds: ['pinion-gear', 'ring-gear', 'carrier'], camera: { position: [-3.8, 1.5, 3.2], target: [0, 0, 0], duration: 1.1 }, rpm: 180, }, { id: 'straight', title: 'Straight-line travel', body: 'Both side gears rotate together, so the spider gears mainly orbit with the carrier.', durationSeconds: 4.5, partIds: ['left-side-gear', 'right-side-gear', 'spider-gears'], phaseRange: [0.02, 0.24], camera: { position: [0, 1.4, 5.1], target: [0, 0, 0], duration: 1.1 }, }, { id: 'cornering', title: 'Cornering speed difference', body: 'The spider gears spin on their own axes, allowing the outside axle to rotate faster.', durationSeconds: 5, partIds: ['spider-gears', 'left-axle', 'right-axle'], phaseRange: [0.34, 0.72], camera: { position: [3.6, 2.0, 3.3], target: [0, 0, 0], duration: 1.1 }, }, ], }, relatedMachineIds: ['planetary-gearbox', 'ball-bearing', 'disc-brake-caliper'], }; function partProps( partId: string, props: ProceduralMachineSceneProps, explodeDirection: [number, number, number] = [0, 0, 0], ) { return { partId, registerPart: props.registerPart, explodeDirection, explodedDistance: props.explodedDistance ?? 0, onSelectPart: props.onSelectPart, onHoverPart: props.onHoverPart, ...getPartVisualProps(partId, props), }; } export const differentialGearAnimation: MachineAnimationModule = { id: 'differential-cornering-cycle', machineId: 'differential-gear', label: 'Open differential cornering animation', version: '1.0.0', defaultRpm: 180, minRpm: 15, maxRpm: 1200, cycleRevolutions: 1, cycleSteps: 20, loop: true, supportsReverse: true, reducedMotionStrategy: 'slow', update(context) { const state = differentialState(context.shaftAngle, context.cycleProgress); const ring = context.getPart('ring-gear'); if (ring) ring.rotation.z = -state.ringAngle; const carrier = context.getPart('carrier'); if (carrier) carrier.rotation.z = -state.carrierAngle; const pinion = context.getPart('pinion-gear'); if (pinion) pinion.rotation.x = state.ringAngle * 3.2; const leftGear = context.getPart('left-side-gear'); if (leftGear) leftGear.rotation.x = -state.leftAxleAngle; const rightGear = context.getPart('right-side-gear'); if (rightGear) rightGear.rotation.x = state.rightAxleAngle; const leftAxle = context.getPart('left-axle'); if (leftAxle) leftAxle.rotation.x = -state.leftAxleAngle; const rightAxle = context.getPart('right-axle'); if (rightAxle) rightAxle.rotation.x = state.rightAxleAngle; const spiders = context.getPart('spider-gears'); if (spiders) { spiders.rotation.z = -state.carrierAngle; spiders.rotation.x = state.spiderAngle; } const biasPercent = Math.round(Math.abs(state.corneringBias) * 100); context.setPhaseLabel( biasPercent < 4 ? 'Straight-line travel — axles rotate together' : `Cornering — outside axle running about ${biasPercent}% faster`, ); context.clearHighlights(); if (biasPercent < 4) context.highlightParts(['carrier', 'left-side-gear', 'right-side-gear'], 0.7); else context.highlightParts(['spider-gears', 'left-axle', 'right-axle'], 0.85); }, }; export function DifferentialGearScene(props: ProceduralMachineSceneProps): JSX.Element { return ( ); } export const differentialGear: ProceduralMachineModule = { definition, animationModule: differentialGearAnimation, Scene: DifferentialGearScene, };