Fix easing functions in orx-easing, add demo

This commit is contained in:
Edwin Jakobs
2020-04-07 23:52:28 +02:00
parent b3fd0a0068
commit 32d0b98338
3 changed files with 163 additions and 44 deletions

20
orx-easing/build.gradle Normal file
View File

@@ -0,0 +1,20 @@
sourceSets {
demo {
java {
srcDirs = ["src/demo/kotlin"]
compileClasspath += main.getCompileClasspath()
runtimeClasspath += main.getRuntimeClasspath()
}
}
}
dependencies {
implementation project(":orx-shader-phrases")
implementation project(":orx-parameters")
demoImplementation(project(":orx-camera"))
demoImplementation("org.openrndr:openrndr-core:$openrndrVersion")
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
demoImplementation(sourceSets.getByName("main").output)
}

View File

@@ -0,0 +1,82 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extras.easing.*
import org.openrndr.math.Vector2
fun main() {
application {
configure {
width = 1280
height = 1080
}
program {
fun drawEasing(f: EasingFunction) {
drawer.stroke = ColorRGBa.PINK
val points = mutableListOf<Vector2>()
for (i in 0 .. 40) {
val y = 40.0 - f(i / 40.0, 0.0, 1.0, 1.0) * 40.0
points.add(Vector2(i*10.0, y))
}
drawer.lineStrip(points)
drawer.stroke = ColorRGBa.GRAY
drawer.lineSegment(0.0, 40.0, 400.0, 40.0)
drawer.lineSegment(0.0, 20.0, 400.0, 20.0)
}
extend {
drawer.stroke = ColorRGBa.WHITE
val functions = listOf(
::easeLinear,
::easeQuadIn,
::easeQuadOut,
::easeQuadInOut,
::easeCubicIn,
::easeCubicOut,
::easeCubicInOut,
::easeCircIn,
::easeCircOut,
::easeCircInOut,
::easeQuartIn,
::easeQuartOut,
::easeQuartInOut,
::easeExpoIn,
::easeExpoOut,
::easeExpoInOut,
::easeQuintIn,
::easeQuintOut,
::easeQuintInOut,
::easeSineIn,
::easeSineOut,
::easeSineInOut,
::easeBackIn,
::easeBackOut,
::easeBackInOut,
::easeElasticIn,
::easeElasticOut,
::easeElasticInOut,
::easeBounceIn,
::easeBounceOut,
::easeBounceInOut
)
var i = 0
for (f in functions) {
drawEasing(f)
drawer.translate(0.0, 50.0)
i ++
if (i > 19) {
drawer.translate(450.0, -20 * 50.0)
i = 0
}
}
}
}
}
}

View File

@@ -1,5 +1,10 @@
package org.openrndr.extras.easing
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
import kotlin.math.sqrt
typealias EasingFunction = (Double, Double, Double, Double) -> Double
fun easeLinear(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0) = c * (t / d) + b
@@ -7,7 +12,7 @@ fun easeLinear(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0) = c
// -- constant
fun easeZero(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0) = b
fun easeOne(t: Double, b: Double = 0.0, c: Double = 1.0, d : Double = 1.0) = b + c
fun easeOne(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0) = b + c
// -- back
@@ -22,13 +27,17 @@ fun easeBackInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0):
val s2 = s * 1.525
val td2 = t / (d / 2)
val td22 = td2 - 2
return if (td2 < 1) c / 2 * (t * t * ((s + 1) * t - s)) + b else c / 2 * ((td22) * td22 * (((s2) + 1) * t + s2) + 2) + b
return if (td2 < 1) {
c / 2 * (td2 * td2 * ((s + 1) * td2 - s)) + b
} else {
c / 2 * ((td22) * td22 * (((s2) + 1) * td22 + s2) + 2) + b
}
}
fun easeBackOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val s = 1.70158
val td1 = t / d - 1
return c * (td1 * td1 * ((s + 1) * t + s) + 1) + b
return c * (td1 * td1 * ((s + 1) * td1 + s) + 1) + b
}
// -- bounce
@@ -39,15 +48,15 @@ fun easeBounceIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0):
t1 /= d
if (t1 < 1 / 2.75) {
result = c * (7.5625 * t1 * t1) + 0.toDouble()
} else if (t1 < 2 / 2.75f) {
} else if (t1 < 2 / 2.75) {
t1 -= (1.5 / 2.75)
result = c * (7.5625 * (t1 * t1 + .75f))
result = c * (7.5625 * (t1) * t1 + .75)
} else if (t1 < 2.5 / 2.75) {
t1 -= 2.25 / 2.75
result = c * (7.5625 * (t1 * t1 + .9375f))
result = c * (7.5625 * (t1) * t1 + .9375)
} else {
t1 -= (2.625 / 2.75)
result = c * (7.5625 * (t1) * t1 + .984375f)
result = c * (7.5625 * (t1) * t1 + .984375)
}
return c - result + b
}
@@ -56,32 +65,32 @@ fun easeBounceInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0
var t1 = d - t * 2
val result: Double
t1 /= d
if (t1 < 1 / 2.75f) {
if (t1 < 1 / 2.75) {
result = c * (7.5625 * t1 * t1) + 0.toDouble()
} else if (t1 < 2 / 2.75f) {
} else if (t1 < 2 / 2.75) {
t1 -= 1.5 / 2.75
result = c * (7.5625 * (t1) * t1 + .75f) + 0.toDouble()
result = c * (7.5625 * (t1) * t1 + .75) + 0.toDouble()
} else if (t1 < 2.5 / 2.75) {
t1 -= 2.25 / 2.75
result = c * (7.5625 * (t1) * t1 + .9375f) + 0.toDouble()
result = c * (7.5625 * (t1) * t1 + .9375) + 0.toDouble()
} else {
t1 -= 2.625 / 2.75
result = c * (7.5625 * (t1) * t1 + .984375f) + 0.toDouble()
result = c * (7.5625 * (t1) * t1 + .984375) + 0.toDouble()
//return c * (7.5625 * pow((t/d) -(2.625 / 2.75),2) + .984375) + b;
}
var t2 = t * 2 - d
val result1: Double
t2 /= d
if (t2 < 1 / 2.75f) result1 = c * (7.5625 * t2 * t2) + 0.toDouble() else if (t2 < 2 / 2.75f) {
if (t2 < 1 / 2.75) result1 = c * (7.5625 * t2 * t2) + 0.toDouble() else if (t2 < 2 / 2.75) {
t2 -= 1.5 / 2.75
result1 = c * (7.5625 * t2 * t2 + .75f)
result1 = c * (7.5625 * t2 * t2 + .75)
} else if (t2 < 2.5 / 2.75) {
t2 -= 2.25 / 2.75
result1 = c * (7.5625 * t2 * t2 + .9375f)
result1 = c * (7.5625 * t2 * t2 + .9375)
} else {
t2 -= 2.626 / 2.75
result1 = c * (7.5625 * t2 * t2 + .984375f)
result1 = c * (7.5625 * t2 * t2 + .984375)
}
return if (t < d / 2)
(c - result) * .5 + b
@@ -94,17 +103,17 @@ fun easeBounceOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0):
var td = t / d
return if (td < (1 / 2.75f)) {
c * (7.5625f * td * td) + b
} else if (t < (2 / 2.75f)) {
return if (td < (1 / 2.75)) {
c * (7.5625 * td * td) + b
} else if (t < (2 / 2.75)) {
td -= 1.5 / 2.75
c * (7.5625f * td * td + .75f) + b
c * (7.5625 * td * td + .75) + b
} else if (t < (2.5 / 2.75)) {
td -= 2.25 / 2.75
c * (7.5625f * td * td + .9375f) + b
c * (7.5625 * td * td + .9375) + b
} else {
td -= 2.625 / 2.75
c * (7.5625f * td * td + .984375f) + b
c * (7.5625 * td * td + .984375) + b
}
}
@@ -112,20 +121,20 @@ fun easeBounceOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0):
fun easeCircIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td = t / d
return -c * (Math.sqrt(1 - td * td) - 1) + b
return -c * (sqrt(1 - td * td) - 1) + b
}
fun easeCircInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
var td2 = t / (d / 2.0)
if (td2 < 1)
return -c / 2 * (Math.sqrt(1 - td2 * td2) - 1) + b
return -c / 2 * (sqrt(1 - td2 * td2) - 1) + b
td2 -= 2
return c / 2 * (Math.sqrt(1 - td2 * td2) + 1) + b
return c / 2 * (sqrt(1 - td2 * td2) + 1) + b
}
fun easeCircOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d - 1
return c * Math.sqrt(1 - td * td) + b
return c * sqrt(1 - td * td) + b
}
// -- cubic
@@ -155,25 +164,28 @@ fun easeElasticIn(t: Double, b: Double, c: Double, d: Double): Double {
return b + c
} else {
var td = t / d
val p = d * .3f
val p = d * .3
val s = p / 4
td -= 1.0
return -(c * Math.pow(2.0, 10 * (td)) * Math.sin((td * d - s) * (2 * Math.PI) / p)) + b
return -(c * 2.0.pow(10 * (td)) * sin((td * d - s) * (2 * Math.PI) / p)) + b
}
}
fun easeElasticInOut(t: Double, b: Double, c: Double, d: Double): Double {
var td2 = t / (d / 2)
val td2 = t / (d / 2)
if (t == 0.0)
return b
if (td2 == 2.0)
return b + c
val p = d * (.3f * 1.5f)
val p = d * (.3 * 1.5)
val s = p / 4
td2 -= 1.0
val td3 = td2 - 1.0
return if (t < 1) -.5f * (c * Math.pow(2.0, 10 * (td2)) * Math.sin((td2 * d - s) * (2 * Math.PI) / p)) + b else c * Math.pow(2.0, -10 * (td3) * Math.sin(td3 * d - s) * (2 * Math.PI) / p) * .5f + c + b
return if (td2 < 1) {
-.5 * (c * 2.0.pow(10 * (td3)) * sin((td3 - s) * (2 * Math.PI) / p)) + b
} else {
c * 2.0.pow(-10 * (td3) * sin(td3 - s) * (2 * Math.PI) / p) * .5 + c + b
}
}
@@ -183,31 +195,33 @@ fun easeElasticOut(t: Double, b: Double, c: Double, d: Double): Double {
return b
if (td == 1.0)
return b + c
val p = d * .3f
val p = d * .3
val s = p / 4
return c * Math.pow(2.0, -10 * td) * Math.sin((td * d - s) * (2 * Math.PI) / p) + c + b
return c * 2.0.pow(-10 * td) * sin((td * d - s) * (2 * Math.PI) / p) + c + b
}
// -- expo
fun easeExpoIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double =
if (t == 0.0) b else c * Math.pow(2.0, 10 * (t / d - 1)) + b
if (t == 0.0) b else c * 2.0.pow(10 * (t / d - 1)) + b
fun easeExpoInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td2 = t / (d / 2)
val t2 = t * 2
return if (t == 0.0) {
b
} else if (t == d) {
b + c
} else if (td2 < 1) {
c / 2 * Math.pow(2.0, 10 * (t - 1)) + b
} else if (t < d / 2) {
(c / 2) * 2.0.pow(10 * (t2 - 1)) + b
} else {
c / 2 * (-Math.pow(2.0, -10 * (t - 1.0)) + 2) + b
(c / 2) * (-(2.0.pow(-10 * (t2 - 1.0))) + 2) + b
}
}
fun easeExpoOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double =
if (t == d) b + c else c * (-Math.pow(2.0, -10 * t / d) + 1) + b
if (t == d) b + c else c * (-(2.0.pow(-10 * t / d)) + 1) + b
// -- quad
@@ -250,8 +264,11 @@ fun easeQuintIn(t: Double, b: Double, c: Double, d: Double): Double {
}
fun easeQuintInOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d
return c * td * td * td * td * td + b
val t2 = t * 2.0
val t22 = t2 - 2.0
return if (t < 0.5) 0.5 * t2 * t2 * t2 * t2 * t2 else {
0.5 * (t22 * t22 * t22 * t22 * t22 + 2.0)
}
}
fun easeQuintOut(t: Double, b: Double, c: Double, d: Double): Double {
@@ -262,13 +279,13 @@ fun easeQuintOut(t: Double, b: Double, c: Double, d: Double): Double {
// -- sine
fun easeSineIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double =
-c * Math.cos(t / d * (Math.PI / 2)) + c + b
-c * cos(t / d * (Math.PI / 2)) + c + b
fun easeSineOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double =
c * Math.sin(t / d * (Math.PI / 2)) + b
c * sin(t / d * (Math.PI / 2)) + b
fun easeSineInOut(t: Double, b: Double, c: Double, d: Double): Double =
-c / 2 * (Math.cos(Math.PI * t / d) - 1) + b
-c / 2 * (cos(Math.PI * t / d) - 1) + b
enum class Easing(val function: EasingFunction) {