All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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)
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy