diff --git a/orx-fcurve/README.md b/orx-fcurve/README.md index f3c3c026..2bdbda71 100644 --- a/orx-fcurve/README.md +++ b/orx-fcurve/README.md @@ -6,15 +6,16 @@ They are often used to control a property over time. The language to express FCurves is similar to SVG's path language. -| Relative command | Absolute command | Description | -|---------------------|-----------------------|-------------------------------------------------------------| -| `m y` | `M y` | move the pen only in the y-direction | -| `h x` | `H x` | hold a value to draw a horizontal line | -| `l x,y` | `L x,y` | line to (x, y) | -| `q x0,y0,x,y` | `Q x0,y0,x,y` | quadratic bezier to (x,y) and control-point (x0, y0) | -| `c x0,y0,x1,y1,x,y` | `C x0,y0,x1,y1,x,y` | cubic bezier to (x,y) and control-points (x0, y0), (x1, y1) | -| `t x,y` | `T x,y` | quadratic smooth to (x, y) | -| `s x1,y1,x,y` | `S x1,y1,x,y` | cubic smooth to (x,y) and control point (x1, y1) | +| Relative command | Absolute command | Description | +|---------------------|---------------------|--------------------------------------------------------------| +| `m y` | `M y` | move the pen only in the y-direction | +| `h x` | | hold a value to draw a horizontal line | +| | `H x` | shift curve in time by x. Can only be used as first command. | +| `l x,y` | `L x,y` | line to (x, y) | +| `q x0,y0,x,y` | `Q x0,y0,x,y` | quadratic bezier to (x,y) and control-point (x0, y0) | +| `c x0,y0,x1,y1,x,y` | `C x0,y0,x1,y1,x,y` | cubic bezier to (x,y) and control-points (x0, y0), (x1, y1) | +| `t x,y` | `T x,y` | quadratic smooth to (x, y) | +| `s x1,y1,x,y` | `S x1,y1,x,y` | cubic smooth to (x,y) and control point (x1, y1) | ## Examples diff --git a/orx-fcurve/src/commonMain/kotlin/FCurve.kt b/orx-fcurve/src/commonMain/kotlin/FCurve.kt index c67d9801..dd7eaef0 100644 --- a/orx-fcurve/src/commonMain/kotlin/FCurve.kt +++ b/orx-fcurve/src/commonMain/kotlin/FCurve.kt @@ -308,11 +308,8 @@ class FCurveBuilder { if (relative) { lineTo(x, cursor.y) } else { - val d = x - cursor.x - require(d >= 0.0) { - "requested to hold until $x, but cursor is already at ${cursor.x}" - } - lineTo(d, cursor.y) + require(segments.isEmpty()) { "absolute hold (H $x) is only allowed when used as first command"} + cursor = cursor.copy(x = x) } path += "h$x" } diff --git a/orx-fcurve/src/commonTest/kotlin/TestFCurve.kt b/orx-fcurve/src/commonTest/kotlin/TestFCurve.kt index 291e24fe..c62d1b6b 100644 --- a/orx-fcurve/src/commonTest/kotlin/TestFCurve.kt +++ b/orx-fcurve/src/commonTest/kotlin/TestFCurve.kt @@ -16,4 +16,20 @@ class TestFCurve { assertEquals(10.5, normalizedSampler(1.0)) assertEquals(10.5, normalizedSampler(-1.0)) } + + @Test + fun testAbsoluteHold() { + run { + val text = "H-1 L 5 5" + val fc = fcurve(text) + assertEquals(0.0, fc.value(-1.0)) + assertEquals(5.0, fc.value(4.0)) + } + run { + val text = "H1 L 5 5" + val fc = fcurve(text) + assertEquals(0.0, fc.value(1.0)) + assertEquals(5.0, fc.value(6.0)) + } + } } \ No newline at end of file