Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8360047

Allow interpolation outside of range [0,1]

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • javafx
    • None
    • behavioral
    • minimal
    • Hide
      Third-party implementations of `Interpolatable` may work incorrectly for interpolation factors outside of [0,1]. However, no valid JavaFX program can currently produce such interpolation factors in animations (as this capability is only added with this enhancement). Therefore, no existing JavaFX program will be accidentally affected by this change; only new programs that specifically decide to use cubic Beziér functions with values outside of [0,1] must ensure that all interpolators behave correctly. In practice, this shouldn't be a problem as it is very unlikely that a third-party implementation would fail by throwing an exception. A GitHub search yielded no such example.
      Show
      Third-party implementations of `Interpolatable` may work incorrectly for interpolation factors outside of [0,1]. However, no valid JavaFX program can currently produce such interpolation factors in animations (as this capability is only added with this enhancement). Therefore, no existing JavaFX program will be accidentally affected by this change; only new programs that specifically decide to use cubic Beziér functions with values outside of [0,1] must ensure that all interpolators behave correctly. In practice, this shouldn't be a problem as it is very unlikely that a third-party implementation would fail by throwing an exception. A GitHub search yielded no such example.
    • Java API
    • JDK

      Summary

      Allow interpolation outside of range [0,1], and accept cubic Bézier functions with control points outside of range [0,1] on the Y axis (output progress).

      Problem

      JavaFX unnecessarily restricts interpolation in the following ways:

      • Interpolatable implementations often clamp intermediate values to the interpolation factor range [0,1].

      • SplineInterpolator doesn't accept Y coordinates outside of [0,1] for its control points. While this was probably done so that the computed interpolation factor doesn't exceed [0,1], the restriction goes far beyond that. For example, the following function is not representable, even though its values are all within the [0,1] range: <cubic-bezier-1.png>. The following function is also not representable, but would be very useful for bouncy animations: <cubic-bezier-2.png>.

      Solution

      Fortunately, there is no technical reason why JavaFX can't support the full range of animations that can be represented with a cubic Beziér interpolation function.

      1. The specification of Interpolatable is changed to require implementations to accept interpolation factors outside of [0,1].
      2. All implementations of Interpolatable now correctly return intermediate values outside of [0,1].
      3. SplineInterpolator accepts control points with any Y coordinate (it was never specified that it should reject Y coordinates outside of [0,1]).

      Specification

      --- a/modules/javafx.graphics/src/main/java/javafx/animation/Interpolatable.java
      +++ b/modules/javafx.graphics/src/main/java/javafx/animation/Interpolatable.java
      @@ -39,10 +39,10 @@
        *                 {@link #interpolate(Object, double)} method.</td>
        *         </tr>
        *         <tr><td style="vertical-align: top"><a id="linear" style="white-space: nowrap">linear</a></td>
      - *             <td>Two components are combined by linear interpolation such that {@code t = 0} produces
      - *                 the start value, {@code t = 1} produces the end value, and {@code 0 < t < 1} produces
      - *                 {@code (1 - t) * start + t * end}. This interpolation type is usually applicable for
      - *                 numeric components.</td>
      + *             <td>Two components are combined by linear interpolation such that the intermediate value is
      + *                 produced by computing {@code (1 - t) * start + t * end}. Note that this formula produces
      + *                 values less than {@code start} for {@code t < 0} and values greater than {@code end} for
      + *                 {@code t > 1}. This interpolation type is usually applicable for numeric components.</td>
        *         </tr>
        *         <tr><td style="vertical-align: top"><a id="discrete" style="white-space: nowrap">discrete</a></td>
        *             <td>If two components cannot be meaningfully combined, the intermediate component value
      @@ -70,8 +70,8 @@
      
           /**
            * Returns an intermediate value between the value of this {@code Interpolatable} and the specified
      -     * {@code endValue} using the linear interpolation factor {@code t}, ranging from 0 (inclusive)
      -     * to 1 (inclusive).
      +     * {@code endValue} using the linear interpolation factor {@code t}. The interpolation factor can
      +     * be any finite value.
            * <p>
            * The returned value might not be a new instance; the implementation might also return one of the
            * two existing instances if the intermediate value would be equal to one of the existing values.
      @@ -78,10 +78,8 @@
            * However, this is an optimization and applications should not assume any particular identity
            * of the returned value.
            *
      -     * @implSpec An implementation is not required to reject interpolation factors less than 0 or larger
      -     *           than 1, but this specification gives no meaning to values returned outside of this range.
      -     *           For example, an implementation might clamp the interpolation factor to [0..1], or it might
      -     *           continue the linear interpolation outside of this range.
      +     * @implSpec An implementation must accept any interpolation factor, but it can return a clamped
      +     *           intermediate value that falls within its value range.
            *
            * @param endValue the target value
            * @param t the interpolation factor

            mstrauss Michael Strauß
            mstrauss Michael Strauß
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: