Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
commonMain.ru.casperix.math.interpolation.float32.InterpolationFloat.kt Maven / Gradle / Ivy
package ru.casperix.math.interpolation.float32
import ru.casperix.math.angle.float32.DegreeFloat
import ru.casperix.math.angle.float32.RadianFloat
import ru.casperix.math.color.Color
import ru.casperix.math.color.toColor4f
import ru.casperix.math.geometry.fPI
import ru.casperix.math.geometry.fPI2
import ru.casperix.math.quaternion.float32.QuaternionFloat
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.float32.Vector3f
import ru.casperix.math.vector.float32.Vector4f
import kotlin.math.acos
import kotlin.math.sin
object InterpolationFloat {
fun color(
a: Color,
b: Color,
t: Float,
interpolateFloatFunction: InterpolateFloatFunction = linearInterpolatef
): Color {
return vector4(a.toColor4f().toVector4f(), b.toColor4f().toVector4f(), t, interpolateFloatFunction).toColor4f()
}
fun angle(
startAngle: ru.casperix.math.angle.float32.DegreeFloat,
finishAngle: ru.casperix.math.angle.float32.DegreeFloat,
position: Float,
interpolator: InterpolateFloatFunction = linearInterpolatef
): ru.casperix.math.angle.float32.DegreeFloat {
return angle(startAngle.toRadian(), finishAngle.toRadian(), position, interpolator).toDegree()
}
fun angle(
startAngle: RadianFloat,
finishAngle: RadianFloat,
position: Float,
interpolator: InterpolateFloatFunction = linearInterpolatef
): RadianFloat {
val start = startAngle.value
val finish = finishAngle.value
return RadianFloat(
if (finish - start <= fPI) {
interpolator(start, finish, position)
} else if (finish > start) {
interpolator(start, finish - fPI2, position)
} else {
interpolator(start - fPI2, finish, position)
}
)
}
fun single(first: Float, second: Float, t: Float, interpolator: InterpolateFloatFunction = linearInterpolatef): Float {
return interpolator(first, second, t)
}
fun vector2(first: Vector2f, second: Vector2f, t: Float, interpolator: InterpolateFloatFunction = linearInterpolatef): Vector2f {
return Vector2f(interpolator(first.x, second.x, t), interpolator(first.y, second.y, t))
}
fun vector3(first: Vector3f, second: Vector3f, t: Float, interpolator: InterpolateFloatFunction = linearInterpolatef): Vector3f {
return Vector3f(
interpolator(first.x, second.x, t),
interpolator(first.y, second.y, t),
interpolator(first.z, second.z, t)
)
}
fun vector4(first: Vector4f, second: Vector4f, t: Float, interpolator: InterpolateFloatFunction = linearInterpolatef): Vector4f {
return Vector4f(
interpolator(first.x, second.x, t),
interpolator(first.y, second.y, t),
interpolator(first.z, second.z, t),
interpolator(first.w, second.w, t),
)
}
fun quaternion(q1: QuaternionFloat, q2: QuaternionFloat, factor: Float): QuaternionFloat {
// todo: non-linearinterpolation
val info = setupQF(q1, q2)
return info.source * sin((1f - factor) * info.omega) + info.target * sin(factor * info.omega)
}
internal class SlerpF(val source: QuaternionFloat, val target: QuaternionFloat, val omega: Float)
internal fun setupQF(originalA: QuaternionFloat, originalB: QuaternionFloat): SlerpF {
val MAX = .999999f
var source = originalA.normalize()
var target = originalB.normalize()
var cosOmega = source.dot(target)
if (cosOmega < 0.0) {
cosOmega = -cosOmega
target = -target
}
if (cosOmega > MAX) cosOmega = MAX
val omega = acos(cosOmega)
val sinOmegaInv = 1f / sin(omega)
source *= sinOmegaInv
target *= sinOmegaInv
return SlerpF(source, target, omega)
}
}