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.float64.BezierCubic2d.kt Maven / Gradle / Ivy
package ru.casperix.math.curve.float64
import ru.casperix.math.curve.CurveHelper
import ru.casperix.math.interpolation.float64.InterpolationDouble
import ru.casperix.math.vector.float64.Vector2d
import kotlinx.serialization.Serializable
import kotlin.math.pow
@Serializable
data class BezierCubic2d(val p0: Vector2d, val p1: Vector2d, val p2: Vector2d, val p3: Vector2d) :
LazyCurve2d() {
override fun getPosition(t: Double): Vector2d {
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 Vector2d(
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(): Double {
return CurveHelper.calculateLength(this, 10)
}
fun translate(offset: Vector2d): BezierCubic2d {
return BezierCubic2d(p0 + offset, p1 + offset, p2 + offset, p3 + offset)
}
override fun divide(t: Double): Pair {
val H = InterpolationDouble.vector2(p1, p2, t)
val L0 = p0
val R3 = p3
val L1 = InterpolationDouble.vector2(p0, p1, t)
val L2 = InterpolationDouble.vector2(L1, H, t)
val R2 = InterpolationDouble.vector2(p2, p3, t)
val R1 = InterpolationDouble.vector2(H, R2, t)
val R0 = InterpolationDouble.vector2(L2, R1, t)
val L3 = R0
return Pair(BezierCubic2d(L0, L1, L2, L3), BezierCubic2d(R0, R1, R2, R3))
}
override fun getTangent(t: Double): Vector2d {
return Vector2d(
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: Double, a: Double, b: Double, c: Double, d: Double): Double {
val C1 = d - 3.0 * c + 3.0 * b - a
val C2 = 3.0 * c - 6.0 * b + 3.0 * a
val C3 = 3.0 * b - 3.0 * a
return 3.0 * C1 * t * t + 2.0 * C2 * t + C3
}
companion object {
fun byDirection(
start: Vector2d,
startDirection: Vector2d,
finish: Vector2d,
finishDirection: Vector2d
): BezierCubic2d {
return BezierCubic2d(start, start + startDirection, finish - finishDirection, finish)
}
}
}