Add orx-easing

This commit is contained in:
Edwin Jakobs
2019-04-11 16:14:28 +02:00
parent a88c53abea
commit ee9deb29c4
5 changed files with 360 additions and 9 deletions

View File

@@ -6,7 +6,9 @@ A growing library of assorted data structures, algorithms and utilities.
- [`orx-camera`](orx-camera/README.md), 3d camera and controls - [`orx-camera`](orx-camera/README.md), 3d camera and controls
- [`orx-compositor`](orx-compositor/README.md), a simple toolkit to make composite (layered) images - [`orx-compositor`](orx-compositor/README.md), a simple toolkit to make composite (layered) images
- [`orx-filter-extension`](orx-filter-extension/README.md), Program extension method that provides Filter based `extend()` - [`orx-easing`](orx-easing/README.md), a collection of easing functions.
- [`orx-file-watcher`](orx-file-watcher/README.md), `Program` extension method that allows monitoring and hot loading from files.
- [`orx-filter-extension`](orx-filter-extension/README.md), `Program` extension method that provides Filter based `extend()`
- [`orx-integral-image`](orx-integral-image/README.md), CPU-based and GPU-based implementation for integral images (summed area tables) - [`orx-integral-image`](orx-integral-image/README.md), CPU-based and GPU-based implementation for integral images (summed area tables)
- `orx-jumpflood`, a filter/shader based implementation of the jump flood algorithm for finding fast approximate (directional) distance fields - `orx-jumpflood`, a filter/shader based implementation of the jump flood algorithm for finding fast approximate (directional) distance fields
- `orx-kdtree`, a kd-tree implementation for fast nearest point searches - `orx-kdtree`, a kd-tree implementation for fast nearest point searches
@@ -16,7 +18,7 @@ A growing library of assorted data structures, algorithms and utilities.
- [`orx-obj-loader`](orx-obj-loader/README.md), simple Wavefront .obj mesh loader - [`orx-obj-loader`](orx-obj-loader/README.md), simple Wavefront .obj mesh loader
## Usage ## Usage
ORX 0.0.20 is built against OPENRNDR 0.3.32, make sure you use this version in your project. Because OPENRNDR's API is pre 1.0 it tends to change from time to time. ORX 0.0.23 is built against OPENRNDR 0.3.33-rc1, make sure you use this version in your project. Because OPENRNDR's API is pre 1.0 it tends to change from time to time.
The easiest way to add ORX to your project is through the use of Jitpack. [Jitpack](http://jitpack.io) is a service that pulls Gradle based libraries from Github, builds them and serves the jar files. The easiest way to add ORX to your project is through the use of Jitpack. [Jitpack](http://jitpack.io) is a service that pulls Gradle based libraries from Github, builds them and serves the jar files.
@@ -30,13 +32,13 @@ repositories {
You can then add any of the ORX artifacts to your `dependencies {}`: You can then add any of the ORX artifacts to your `dependencies {}`:
``` ```
dependencies { dependencies {
compile 'com.github.openrndr.orx:<orx-artifact>:v0.0.20' compile 'com.github.openrndr.orx:<orx-artifact>:v0.0.23'
} }
``` ```
For example if you want to use the `orx-no-clear` artifact one would use: For example if you want to use the `orx-no-clear` artifact one would use:
``` ```
dependencies { dependencies {
compile 'com.github.openrndr.orx:orx-no-clear:v0.0.20' compile 'com.github.openrndr.orx:orx-no-clear:v0.0.23'
} }
``` ```

View File

@@ -4,7 +4,7 @@ plugins {
allprojects { allprojects {
group 'org.openrndr.extra' group 'org.openrndr.extra'
version '0.0.22' version '0.0.23'
} }
repositories { repositories {
@@ -40,7 +40,6 @@ subprojects {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
from components.java from components.java
artifact sourceJar artifact sourceJar
} }
} }
@@ -50,9 +49,6 @@ subprojects {
classifier = 'sources' classifier = 'sources'
from sourceSets.main.kotlin from sourceSets.main.kotlin
} }
} }
dependencies { dependencies {

31
orx-easing/README.md Normal file
View File

@@ -0,0 +1,31 @@
# orx-easing
A collection of easing functions similar to those on https://easings.net
- `easeLinear`
- `easeBackIn`, `easeBackInOut`, `easeBackOut`
- `easeBounceIn`, `easeBounceInOut`, `easeBounceOut`
- `easeCircIn`, `easeCircInOut`, `easeCircOut`
- `easeCubicIn`, `easeCubicInOut` `easeCubicOut`
- `easeElasticIn`, `easeElasticInOut`, `easeElasticOut`
- `easeExpoIn`, `easeExpoInOut`, `easeExpoOut`
- `easeQuadIn`, `easeQuadInOut`, `easeQuadOut`
- `easeQuartIn`, `easeQuartInOut`, `easeQuartOut`
- `easeQuintIn`, `easeQuintInOut`, `easeQuintOut`
- `easeSineIn`, `easeSineInOut`, `easeSineOut`
## usage
`fun easeX(time: Double, bias: Double = 0.0, scale: Double = 1.0, duration : Double = 1.0)`
```kotlin
// -- when t is in [0, 1]
val et = easeQuadIn(t)
val et = easeQuadIn(t, 0.0, 1.0, 10.0)
```
Using the `Easing` enumeration
```kotlin
val et = Easing.QuadIn.function(t, 0.0, 1.0, 1.0)
```

View File

@@ -0,0 +1,321 @@
package org.openrndr.extras.easing
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
// -- 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
// -- back
fun easeBackIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val s = 1.70158
val td = t / d
return c * (td) * td * ((s + 1) * td - s) + b
}
fun easeBackInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val s = 1.70158 * 1.525
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
}
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
}
// -- bounce
fun easeBounceIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
var t1 = d - t
val result: Double
t1 /= d
if (t1 < 1 / 2.75) {
result = c * (7.5625 * t1 * t1) + 0.toDouble()
} else if (t1 < 2 / 2.75f) {
t1 -= (1.5 / 2.75)
result = c * (7.5625 * (t1 * t1 + .75f))
} else if (t1 < 2.5 / 2.75) {
t1 -= 2.25 / 2.75
result = c * (7.5625 * (t1 * t1 + .9375f))
} else {
t1 -= (2.625 / 2.75)
result = c * (7.5625 * (t1) * t1 + .984375f)
}
return c - result + b
}
fun easeBounceInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
var t1 = d - t * 2
val result: Double
t1 /= d
if (t1 < 1 / 2.75f) {
result = c * (7.5625 * t1 * t1) + 0.toDouble()
} else if (t1 < 2 / 2.75f) {
t1 -= 1.5 / 2.75
result = c * (7.5625 * (t1) * t1 + .75f) + 0.toDouble()
} else if (t1 < 2.5 / 2.75) {
t1 -= 2.25 / 2.75
result = c * (7.5625 * (t1) * t1 + .9375f) + 0.toDouble()
} else {
t1 -= 2.625 / 2.75
result = c * (7.5625 * (t1) * t1 + .984375f) + 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) {
t2 -= 1.5 / 2.75
result1 = c * (7.5625 * t2 * t2 + .75f)
} else if (t2 < 2.5 / 2.75) {
t2 -= 2.25 / 2.75
result1 = c * (7.5625 * t2 * t2 + .9375f)
} else {
t2 -= 2.626 / 2.75
result1 = c * (7.5625 * t2 * t2 + .984375f)
}
return if (t < d / 2)
(c - result) * .5 + b
else
result1 * .5 + c * .5 + b
}
fun easeBounceOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
var td = t / d
return if (td < (1 / 2.75f)) {
c * (7.5625f * td * td) + b
} else if (t < (2 / 2.75f)) {
td -= 1.5 / 2.75
c * (7.5625f * td * td + .75f) + b
} else if (t < (2.5 / 2.75)) {
td -= 2.25 / 2.75
c * (7.5625f * td * td + .9375f) + b
} else {
td -= 2.625 / 2.75
c * (7.5625f * td * td + .984375f) + b
}
}
// -- circ
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
}
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
td2 -= 2
return c / 2 * (Math.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
}
// -- cubic
fun easeCubicIn(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td = t / d
return c * td * td * td + b
}
fun easeCubicOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td = t / d - 1.0
return c * (td * td * td + 1) + b
}
fun easeCubicInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td = t / (d / 2)
val td2 = td - 2.0
return if (td < 1) c / 2 * td * td * td + b else c / 2 * (td2 * td2 * td2 + 2) + b
}
// -- elastic
fun easeElasticIn(t: Double, b: Double, c: Double, d: Double): Double {
if (t == 0.0) {
return b
} else if (t / d == 1.0) {
return b + c
} else {
var td = t / d
val p = d * .3f
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
}
}
fun easeElasticInOut(t: Double, b: Double, c: Double, d: Double): Double {
var td2 = t / (d / 2)
if (t == 0.0)
return b
if (td2 == 2.0)
return b + c
val p = d * (.3f * 1.5f)
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
}
fun easeElasticOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d
if (t == 0.0)
return b
if (td == 1.0)
return b + c
val p = d * .3f
val s = p / 4
return c * Math.pow(2.0, -10 * td) * Math.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
fun easeExpoInOut(t: Double, b: Double = 0.0, c: Double = 1.0, d: Double = 1.0): Double {
val td2 = t / (d / 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 {
c / 2 * (-Math.pow(2.0, -10 * (t - 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
// -- quad
fun easeQuadIn(t: Double, b: Double, c: Double, d: Double): Double = c * (t / d) * (t / d) + b
fun easeQuadInOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / (d / 2)
return if (td < 1) {
c / 2 * td * td + b
} else {
-c / 2 * ((td - 1) * (td - 3) - 1) + b
}
}
fun easeQuadOut(t: Double, b: Double, c: Double, d: Double): Double = -c * (t / d) * (t / d - 2) + b
// -- quart
fun easeQuartIn(t: Double, b: Double, c: Double, d: Double): Double {
val n = t / d
return c * n * n * n * n + b
}
fun easeQuartInOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / (d / 2)
val td2 = td - 2.0
return if (td < 1) c / 2 * td * td * td * td + b else -c / 2 * (td2 * td2 * td2 * td2 - 2) + b
}
fun easeQuartOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d - 1
return -c * (td * td * td * td - 1) + b
}
// -- quint
fun easeQuintIn(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d
return c * td * td * td * td * td + b
}
fun easeQuintInOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d
return c * td * td * td * td * td + b
}
fun easeQuintOut(t: Double, b: Double, c: Double, d: Double): Double {
val td = t / d - 1
return c * ((td) * td * td * td * td + 1) + b
}
// -- 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
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
fun easeSineInOut(t: Double, b: Double, c: Double, d: Double): Double =
-c / 2 * (Math.cos(Math.PI * t / d) - 1) + b
enum class Easing(val function: EasingFunction) {
Linear(::easeLinear),
Zero(::easeZero),
One(::easeOne),
BackIn(::easeBackIn),
BackInOut(::easeBackInOut),
BackOut(::easeBackOut),
BounceIn(::easeBounceIn),
BounceInOut(::easeBounceInOut),
BounceOut(::easeBounceOut),
CircIn(::easeCircIn),
CircInOut(::easeCircInOut),
CircOut(::easeCircOut),
CubicIn(::easeCubicIn),
CubicInOut(::easeCubicInOut),
CubicOut(::easeCubicOut),
ElasticIn(::easeElasticIn),
ElasticInOut(::easeElasticInOut),
ElasticOut(::easeElasticOut),
ExpoIn(::easeExpoIn),
ExpoInOut(::easeExpoInOut),
ExpoOut(::easeExpoOut),
QuadIn(::easeQuadIn),
QuadInOut(::easeQuadInOut),
QuadOut(::easeQuadOut),
QuartIn(::easeQuartIn),
QuartInOut(::easeQuartInOut),
QuartOut(::easeQuartOut),
QuintIn(::easeQuintIn),
QuintInOut(::easeQuintInOut),
QuintOut(::easeQuintOut),
SineIn(::easeSineIn),
SineInOut(::easeSineInOut),
SineOut(::easeSineOut),
}

View File

@@ -2,6 +2,7 @@ rootProject.name = 'orx'
include 'orx-camera', include 'orx-camera',
'orx-compositor', 'orx-compositor',
'orx-easing',
'orx-file-watcher', 'orx-file-watcher',
'orx-filter-extension', 'orx-filter-extension',
'orx-integral-image', 'orx-integral-image',