KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/util/PeriodicFunction.kt

55 lines
1.5 KiB
Kotlin

package ru.dbotthepony.kstarbound.util
import ru.dbotthepony.kommons.math.linearInterpolation
import ru.dbotthepony.kstarbound.math.Interpolator
import java.util.random.RandomGenerator
data class PeriodicFunction(
val period: Double = 1.0,
val min: Double = 0.0,
val max: Double = 1.0,
val periodVariance: Double = 0.0,
val magnitudeVariance: Double = 0.0
) {
private var timer = 0.0
private var timerMax = 1.0
private var base = 0.0
private var target = 0.0
private var isDescending = false
private val halfPeriod = period * 0.5
private val halfVariance = periodVariance * 0.5
fun update(delta: Double, random: RandomGenerator) {
timer -= delta
// original code here explicitly ignore deltas bigger than max period time
// we, however, do not, if period time is big enough
while (timer <= 0.0) {
base = target
target = (if (isDescending) min else max) + if (magnitudeVariance == 0.0) 0.0 else random.nextDouble(-magnitudeVariance, magnitudeVariance)
isDescending = !isDescending
timerMax = (halfPeriod + if (halfVariance == 0.0) 0.0 else random.nextDouble(-halfVariance, halfVariance)).coerceAtLeast(0.01)
timer += timerMax
if (timerMax <= 0.05 && timer <= 0.0) {
timer = 0.0
break
}
}
}
fun value(interpolator: Interpolator): Double {
return interpolator.interpolate(1.0 - timer / timerMax, base, target)
}
fun value(): Double {
return value(::linearInterpolation)
}
fun sinValue(): Double {
return value(Interpolator.Sin)
}
}