All Downloads are FREE. Search and download functionalities are using the official Maven repository.
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.curve.float32.BezierCubic2f.kt Maven / Gradle / Ivy
package ru.casperix.math.curve.float32
import ru.casperix.math.curve.CurveHelper
import ru.casperix.math.interpolation.float32.InterpolationFloat
import ru.casperix.math.vector.float32.Vector2f
import kotlinx.serialization.Serializable
import kotlin.math.pow
@Serializable
data class BezierCubic2f(val p0: Vector2f, val p1: Vector2f, val p2: Vector2f, val p3: Vector2f) :
ParametricCurve2f {
override fun getPosition(t: Float): Vector2f {
val s = 1f - t
val k0 = s.pow(3)
val k1 = 3 * t * s.pow(2)
val k2 = 3f * t.pow(2) * s
val k3 = t.pow(3)
return Vector2f(
p0.x * k0 + p1.x * k1 + p2.x * k2 + p3.x * k3,
p0.y * k0 + p1.y * k1 + p2.y * k2 + p3.y * k3,
)
}
override fun length(): Float {
return CurveHelper.calculateLength(this, 10)
}
fun translate(offset: Vector2f): BezierCubic2f {
return BezierCubic2f(p0 + offset, p1 + offset, p2 + offset, p3 + offset)
}
override fun divide(t: Float): Pair {
val H = InterpolationFloat.vector2(p1, p2, t)
val L0 = p0
val R3 = p3
val L1 = InterpolationFloat.vector2(p0, p1, t)
val L2 = InterpolationFloat.vector2(L1, H, t)
val R2 = InterpolationFloat.vector2(p2, p3, t)
val R1 = InterpolationFloat.vector2(H, R2, t)
val R0 = InterpolationFloat.vector2(L2, R1, t)
val L3 = R0
return Pair(BezierCubic2f(L0, L1, L2, L3), BezierCubic2f(R0, R1, R2, R3))
}
override fun getTangent(t: Float): Vector2f {
return Vector2f(
bezierTangent(t, p0.x, p1.x, p2.x, p3.x),
bezierTangent(t, p0.y, p1.y, p2.y, p3.y),
).normalize()
}
/**
* https://stackoverflow.com/questions/4089443/find-the-tangent-of-a-point-on-a-cubic-bezier-curve
*/
private fun bezierTangent(t: Float, a: Float, b: Float, c: Float, d: Float): Float {
val C1 = d - 3f * c + 3f * b - a
val C2 = 3f * c - 6f * b + 3f * a
val C3 = 3f * b - 3f * a
return 3f * C1 * t * t + 2f * C2 * t + C3
}
companion object {
fun byDirection(
start: Vector2f,
startDirection: Vector2f,
finish: Vector2f,
finishDirection: Vector2f
): BezierCubic2f {
return BezierCubic2f(start, start + startDirection, finish - finishDirection, finish)
}
}
}