package core import model.PhysicsState /** * 物理引擎 - 模拟真实的运动物理过程 * * 职责:根据时间计算运动状态(距离、速度、加速度) * * 数据流: * 时间 t * ↓ * [PhysicsEngine.calculate(t)] * ↓ * PhysicsState(distance, velocity, acceleration) * * 预留扩展: * - 支持不同的运动模式(跑步/散步) * - 支持加速度衰减曲线 * - 支持不同的速度曲线 */ class RunnerPhysics( private val totalDistance: Double = 0.0, // 总路线距离(米) private val duration: Double = 1000.0, // 总运动时间(秒) private val maxVelocity: Double = 4.0 // 最大速度(m/s) ) { private val derivativeStepSeconds = 1.0 // 接入人类风格距离引擎(仅用于 time -> distance) private val distanceEngine: HumanLikeDistanceEngine? = if (totalDistance > 0.0 && duration > 0.0 && maxVelocity > 0.0) { HumanLikeDistanceEngine( HumanLikeDistanceConfig( totalDistanceMeters = totalDistance, totalDurationSeconds = duration, minSpeedMps = (maxVelocity * 0.45).coerceAtLeast(0.5), maxSpeedMps = maxVelocity ) ) } else { null } /** * 计算指定时间的物理状态 * * @param time 当前时间(秒) * @return 包含距离、速度、加速度的物理状态 */ fun calculate(time: Double): PhysicsState { // 1) 距离:由 distanceEngine 生成 // 2) 速度:对距离做一阶差分 // 3) 加速度:对速度做二阶差分 val t = time.coerceAtLeast(0.0) val dt = derivativeStepSeconds val distance = getDistance(t) val t1 = (t - dt).coerceAtLeast(0.0) val t2 = (t - 2 * dt).coerceAtLeast(0.0) val d1 = getDistance(t1) val d2 = getDistance(t2) val vNow = if (t > t1) (distance - d1) / (t - t1) else 0.0 val vPrev = if (t1 > t2) (d1 - d2) / (t1 - t2) else vNow val velocity = vNow.coerceAtLeast(0.0) val acceleration = if (t > t1) ((vNow - vPrev) / (t - t1)) else 0.0 return PhysicsState( time = t, distance = distance, velocity = velocity, acceleration = acceleration ) } /** * 获取指定时间的行进距离 * * @param time 时间(秒) * @return 行进距离(米) */ fun getDistance(time: Double): Double { // 优先使用新引擎;参数无效时回退为简单线性进度 return distanceEngine?.getDistance(time) ?: time.coerceAtLeast(0.0) } }