89 lines
2.7 KiB
Kotlin
89 lines
2.7 KiB
Kotlin
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)
|
||
}
|
||
}
|