| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | import DeveloperError from "./DeveloperError.js";import CesiumMath from "./Math.js";/** * Defines functions for 2nd order polynomial functions of one variable with only real coefficients. * * @namespace QuadraticRealPolynomial */const QuadraticRealPolynomial = {};/** * Provides the discriminant of the quadratic equation from the supplied coefficients. * * @param {Number} a The coefficient of the 2nd order monomial. * @param {Number} b The coefficient of the 1st order monomial. * @param {Number} c The coefficient of the 0th order monomial. * @returns {Number} The value of the discriminant. */QuadraticRealPolynomial.computeDiscriminant = function (a, b, c) {  //>>includeStart('debug', pragmas.debug);  if (typeof a !== "number") {    throw new DeveloperError("a is a required number.");  }  if (typeof b !== "number") {    throw new DeveloperError("b is a required number.");  }  if (typeof c !== "number") {    throw new DeveloperError("c is a required number.");  }  //>>includeEnd('debug');  const discriminant = b * b - 4.0 * a * c;  return discriminant;};function addWithCancellationCheck(left, right, tolerance) {  const difference = left + right;  if (    CesiumMath.sign(left) !== CesiumMath.sign(right) &&    Math.abs(difference / Math.max(Math.abs(left), Math.abs(right))) < tolerance  ) {    return 0.0;  }  return difference;}/** * Provides the real valued roots of the quadratic polynomial with the provided coefficients. * * @param {Number} a The coefficient of the 2nd order monomial. * @param {Number} b The coefficient of the 1st order monomial. * @param {Number} c The coefficient of the 0th order monomial. * @returns {Number[]} The real valued roots. */QuadraticRealPolynomial.computeRealRoots = function (a, b, c) {  //>>includeStart('debug', pragmas.debug);  if (typeof a !== "number") {    throw new DeveloperError("a is a required number.");  }  if (typeof b !== "number") {    throw new DeveloperError("b is a required number.");  }  if (typeof c !== "number") {    throw new DeveloperError("c is a required number.");  }  //>>includeEnd('debug');  let ratio;  if (a === 0.0) {    if (b === 0.0) {      // Constant function: c = 0.      return [];    }    // Linear function: b * x + c = 0.    return [-c / b];  } else if (b === 0.0) {    if (c === 0.0) {      // 2nd order monomial: a * x^2 = 0.      return [0.0, 0.0];    }    const cMagnitude = Math.abs(c);    const aMagnitude = Math.abs(a);    if (      cMagnitude < aMagnitude &&      cMagnitude / aMagnitude < CesiumMath.EPSILON14    ) {      // c ~= 0.0.      // 2nd order monomial: a * x^2 = 0.      return [0.0, 0.0];    } else if (      cMagnitude > aMagnitude &&      aMagnitude / cMagnitude < CesiumMath.EPSILON14    ) {      // a ~= 0.0.      // Constant function: c = 0.      return [];    }    // a * x^2 + c = 0    ratio = -c / a;    if (ratio < 0.0) {      // Both roots are complex.      return [];    }    // Both roots are real.    const root = Math.sqrt(ratio);    return [-root, root];  } else if (c === 0.0) {    // a * x^2 + b * x = 0    ratio = -b / a;    if (ratio < 0.0) {      return [ratio, 0.0];    }    return [0.0, ratio];  }  // a * x^2 + b * x + c = 0  const b2 = b * b;  const four_ac = 4.0 * a * c;  const radicand = addWithCancellationCheck(b2, -four_ac, CesiumMath.EPSILON14);  if (radicand < 0.0) {    // Both roots are complex.    return [];  }  const q =    -0.5 *    addWithCancellationCheck(      b,      CesiumMath.sign(b) * Math.sqrt(radicand),      CesiumMath.EPSILON14    );  if (b > 0.0) {    return [q / a, c / q];  }  return [c / q, q / a];};export default QuadraticRealPolynomial;
 |