src/curve.js
/**
   * Computes the position t of a point on the curve given its x coordinate.
   * That is, for an input xVal, finds t s.t. getPointX(t) = xVal.
   * As such, the following should always be true up to some small epsilon:
   * t ~ solvePositionFromXValue(getPointX(t)) for t in [0, 1].
   * @param {number} xVal The x coordinate of the point to find on the curve.
   * @return {number} The position t.
   */
Computes the position t of a point on the curve given its x coordinate.
That is, for an input xVal, finds t s.t.
Computes the position t of a point on the curve given its x coordinate . That is for an input xVal finds t s . t .
solvePositionFromXValue(xVal) {
    const epsilon = 1e-6;
    let t = (xVal - this.x0) / (this.x3 - this.x0);
    if (t <= 0) {
      return 0;
    } else if (t >= 1) {
      return 1;
    }
    let tMin = 0;
    let tMax = 1;
    let value = 0;
    for (let i = 0; i < 8; i++) {
      value = this.getPointX(t);
      const derivative = (this.getPointX(t + epsilon) - value) / epsilon;
      if (Math.abs(value - xVal) < epsilon) {
        return t;
      } else if (Math.abs(derivative) < epsilon) {
        break;
      } else {
        if (value < xVal) {
          tMin = t;
        } else {
          tMax = t;
        }
        t -= (value - xVal) / derivative;
      }
    }
    for (let i = 0; Math.abs(value - xVal) > epsilon && i < 8; i++) {
      if (value < xVal) {
        tMin = t;
        t = (t + tMax) / 2;
      } else {
        tMax = t;
        t = (t + tMin) / 2;
      }
      value = this.getPointX(t);
    }
    return t;
  }
solvePositionFromXValue ( xVal ) { const epsilon = 1e-6 ; let t = ( xVal - this . x0 ) / ( this . x3 - this . x0 ) ; if ( t <= 0 ) { return 0 ; } else if ( t >= 1 ) { return 1 ; } let tMin = 0 ; let tMax = 1 ; let value = 0 ; for ( let i = 0 ; i < 8 ; i ++ ) { value = this . getPointX ( t ) ; const derivative = ( this . getPointX ( t + epsilon ) - value ) / epsilon ; if ( Math . abs ( value - xVal ) < epsilon ) { return t ; } else if ( Math . abs ( derivative ) < epsilon ) { break ; } else { if ( value < xVal ) { tMin = t ; } else { tMax = t ; } t -= ( value - xVal ) / derivative ; } } for ( let i = 0 ; Math . abs ( value - xVal ) > epsilon && i < 8 ; i ++ ) { if ( value < xVal ) { tMin = t ; t = ( t + tMax ) / 2 ; } else { tMax = t ; t = ( t + tMin ) / 2 ; } value = this . getPointX ( t ) ; } return t ; }
Computes the position t of a point on the curve given its x coordinate.
Computes the position t of a point on the curve given its x coordinate .
// Desired precision on the computation. // Initial estimate of t using linear interpolation. // Try gradient descent to solve for t. If it works, it is very fast. // If the gradient descent got stuck in a local minimum, e.g. because // the derivative was close to 0, use a Dichotomy refinement instead. // We limit the number of iterations to 8.