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

commonMain.ru.casperix.math.BezierCalculation.kt Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
package ru.casperix.math

import ru.casperix.math.curve.float32.BezierCubic2f
import ru.casperix.math.vector.float32.Vector2f
import kotlin.math.absoluteValue
import kotlin.math.sqrt

object BezierCalculation {
    fun getDirectHeight(curve: BezierCubic2f, x: Float, steps: Int): Float {
        val nearPos = (0 until steps).map {
            val t = it / steps.toFloat()
            curve.getPosition(t)
        }.minBy { (it.x - x).absoluteValue }
        return nearPos.y
    }

    fun getApproximateIterationHeight(curve: BezierCubic2f, x: Float, steps: Int): Float {
        var tPos = 0.50f
        var tStep = 0.25f
        var remains = steps
        while (true) {
            val pos = curve.getPosition(tPos)
            if (x == pos.x) {
                return pos.y
            } else if (x < pos.x) {
                tPos -= tStep
            } else {
                tPos += tStep
            }
            tStep /= 2f


            if (remains-- == 0) {
                return pos.y
            }
        }
    }

    fun getApproximateErrorHeightPrecision(curve: BezierCubic2f, x: Float, error: Float): Float {
        var tPos = 0.50f
        var tStep = 0.25f
        var lastPos = Vector2f.NaN
        while (true) {
            val pos = curve.getPosition(tPos)
            if (pos.distTo(lastPos) < error) {
                return pos.y
            } else if (x < pos.x) {
                tPos -= tStep
            } else {
                tPos += tStep
            }
            lastPos = pos
            tStep /= 2f
        }
    }

    fun getApproximateErrorHeightAdaptive(curve: BezierCubic2f, x: Float): Float {
        val error = 0.001f * curve.run {
            p0.distTo(p1) + p1.distTo(p2) + p2.distTo(p3)
        }
        return getApproximateErrorHeightPrecision(curve, x, error)
    }


    fun getApproximateErrorHeight(curve: BezierCubic2f, x: Float, error: Float): Float {
        var tPos = 0.50f
        var tStep = 0.25f
//        var steps = 0
        while (true) {
//            steps++
            val pos = curve.getPosition(tPos)
            if ((pos.x - x).absoluteValue < error) {
                return pos.y
//                return Pair(steps, pos.y)
            } else if (x < pos.x) {
                tPos -= tStep
            } else {
                tPos += tStep
            }
            tStep /= 2f
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy