import { AngleSweep } from "../geometry3d/AngleSweep";
import { GrowableFloat64Array, OptionalGrowableFloat64Array } from "../geometry3d/GrowableFloat64Array";
import { LongitudeLatitudeNumber } from "../geometry3d/LongitudeLatitudeAltitude";
import { Point2d } from "../geometry3d/Point2dVector2d";
import { Point3d, Vector3d, XYZ } from "../geometry3d/Point3dVector3d";
import { Range1d, Range3d } from "../geometry3d/Range";
import { Ray3d } from "../geometry3d/Ray3d";
import { XAndY } from "../geometry3d/XYZProps";
/**
 * degree 2 (quadratic) polynomial in for y = c0 + c1*x + c2*x^2
 * @internal
 */
export declare class Degree2PowerPolynomial {
    /** The three coefficients for the quadratic */
    coffs: number[];
    constructor(c0?: number, c1?: number, c2?: number);
    /**
     * * Return 2 duplicate roots in double root case.
     * * The solutions are always in algebraic order.
     * @returns 0, 1, or 2 solutions of the usual quadratic (a*x*x + b * x + c = 0)
     */
    static solveQuadratic(a: number, b: number, c: number): number[] | undefined;
    /** Add `a` to the constant term. */
    addConstant(a: number): void;
    /** Add  `s * (a + b*x)^2` to the quadratic coefficients */
    addSquaredLinearTerm(a: number, b: number, s?: number): void;
    /** Return the real roots of this polynomial */
    realRoots(): number[] | undefined;
    /** Evaluate the quadratic at x. */
    evaluate(x: number): number;
    /**
     * Evaluate the bezier function at a parameter value.  (i.e. sum the basis functions times coefficients)
     * @param u parameter for evaluation
     */
    evaluateDerivative(x: number): number;
    /** Factor the polynomial in to the form `y0 + c * (x-x0)^2)`, i.e. complete the square. */
    tryGetVertexFactorization(): {
        x0: number;
        y0: number;
        c: number;
    } | undefined;
    /** Construct a quadratic from input form `c2 * (x-root0) * (x-root1)` */
    static fromRootsAndC2(root0: number, root1: number, c2?: number): Degree2PowerPolynomial;
}
/**
 * degree 3 (cubic) polynomial in for y = c0 + c1*x + c2*x^2 + c3*x^3
 * @internal
 */
export declare class Degree3PowerPolynomial {
    /** polynomial coefficients, index corresponds to power */
    coffs: number[];
    constructor(c0?: number, c1?: number, c2?: number, c3?: number);
    /** Add `a` to the constant term. */
    addConstant(a: number): void;
    /** Add `s * (a + b*x)^2` to the cubic */
    addSquaredLinearTerm(a: number, b: number, s?: number): void;
    /**
     * Evaluate the polynomial at x
     * @param u parameter for evaluation
     */
    evaluate(x: number): number;
    /**
     * Evaluate the polynomial derivative
     * @param u parameter for evaluation
     */
    evaluateDerivative(x: number): number;
    /** Construct a cubic from the form `c3 * (x-root0) * (x - root1) * (x- root2)` */
    static fromRootsAndC3(root0: number, root1: number, root2: number, c3?: number): Degree3PowerPolynomial;
}
/**
 * degree 4 (quartic) polynomial in for y = c0 + c1*x + c2*x^2 + c4*x^4
 * @internal
 */
export declare class Degree4PowerPolynomial {
    /** polynomial coefficients, index corresponds to power */
    coffs: number[];
    constructor(c0?: number, c1?: number, c2?: number, c3?: number, c4?: number);
    /** Add `a` to the constant term. */
    addConstant(a: number): void;
    /**
     * Evaluate the polynomial
     * @param x x coordinate for evaluation
     */
    evaluate(x: number): number;
    /**
     * Evaluate the derivative
     * @param x x coordinate for evaluation
     */
    evaluateDerivative(x: number): number;
    /** Construct a quartic from the form `c3 * (x-root0) * (x - root1) * (x- root2) * (x-root3)` */
    static fromRootsAndC4(root0: number, root1: number, root2: number, root3: number, c4?: number): Degree4PowerPolynomial;
}
/**
 * polynomial services for an implicit torus with
 * * z axis is "through the donut hole"
 * * `majorRadius` is the radius of the circle "around the z axis"
 * * `minorRadius` is the radius of circles around the major circle
 * * for simple xyz the implicit form is
 *   * `(x^2+y^2+z^2+(R^2-r^2))^2 = 4 R^2(x^2+y^2)`
 * * In weighted form
 *   * `(x^2+y^2+z^2+(R^2-r^2)w^2)^2 = 4 R^2 w^2 (x^2+y^2)`
 * @internal
 */
export declare class TorusImplicit {
    /** major (xy plane) radius */
    majorRadius: number;
    /** hoop (perpendicular to major circle) radius */
    minorRadius: number;
    constructor(majorRadius: number, minorRadius: number);
    /** Return sum of (absolute) major and minor radii, which is (half) the box size in x and y directions */
    boxSize(): number;
    /** Return scale factor appropriate to control the magnitude of the implicit function. */
    implicitFunctionScale(): number;
    /**
     * At space point (x,y,z) evaluate the implicit form of the torus (See `ImplicitTorus`)
     */
    evaluateImplicitFunctionXYZ(x: number, y: number, z: number): number;
    /** Evaluate the implicit function at a point. */
    evaluateImplicitFunctionPoint(xyz: Point3d): number;
    /** Evaluate the implicit function at homogeneous coordinates */
    evaluateImplicitFunctionXYZW(x: number, y: number, z: number, w: number): number;
    /** Evaluate the surface point at angles (in radians) on the major and minor circles. */
    evaluateThetaPhi(thetaRadians: number, phiRadians: number): Point3d;
    /** Evaluate partial derivatives at angles (int radians) on major and minor circles. */
    evaluateDerivativesThetaPhi(thetaRadians: number, phiRadians: number, dxdTheta: Vector3d, dxdPhi: Vector3d): void;
    /** Evaluate space point at major and minor angles (in radians) and distance from major hoop. */
    evaluateThetaPhiDistance(thetaRadians: number, phiRadians: number, distance: number): Point3d;
    /** Given an xyz coordinate in the local system of the toroid, compute the torus parametrization
     * * theta = angular coordinate in xy plane
     * * phi = angular coordinate in minor circle.
     * * distance = distance from major circle
     * * rho = distance from origin to xy part of the input.
     * @param xyz space point in local coordinates.
     * @return object with properties theta, phi, distance, rho
     */
    xyzToThetaPhiDistance(xyz: Point3d): {
        theta: number;
        phi: number;
        distance: number;
        rho: number;
        safePhi: boolean;
    };
}
/**
 * evaluation methods for an implicit sphere
 * * xyz function `x*x + y*y + z*z - r*r = 0`.
 * * xyzw function `x*x + y*y + z*z - r*r*w*w = 0`.
 * @internal
 */
export declare class SphereImplicit {
    /** Radius of sphere. */
    radius: number;
    constructor(r: number);
    /** Evaluate the implicit function at coordinates x,y,z */
    evaluateImplicitFunction(x: number, y: number, z: number): number;
    /** Evaluate the implicit function at homogeneous coordinates x,y,z,w */
    evaluateImplicitFunctionXYZW(wx: number, wy: number, wz: number, w: number): number;
    /** Given an xyz coordinate in the local system of the toroid, compute the sphere parametrization
     * * theta = angular coordinate in xy plane
     * * phi = rotation from xy plane towards z axis.
     * @param xyz space point in local coordinates.
     * @return object with properties thetaRadians, phi, r
     */
    xyzToThetaPhiR(xyz: Point3d): {
        thetaRadians: number;
        phiRadians: number;
        r: number;
        valid: boolean;
    };
    /** Return the range of a uv-aligned patch of the sphere. */
    static patchRangeStartEndRadians(center: Point3d, radius: number, theta0Radians: number, theta1Radians: number, phi0Radians: number, phi1Radians: number, result?: Range3d): Range3d;
    /** Compute intersections with a ray.
     * * Return the number of intersections
     * * Fill any combinations of arrays of
     *    * rayFractions = fractions along the ray
     *    * xyz = xyz intersection coordinates points in space
     *    * thetaPhiRadians = sphere longitude and latitude in radians.
     * * For each optional array, caller must of course initialize an array (usually empty)
     */
    static intersectSphereRay(center: Point3d, radius: number, ray: Ray3d, rayFractions: number[] | undefined, xyz: Point3d[] | undefined, thetaPhiRadians: LongitudeLatitudeNumber[] | undefined): number;
    /** Compute the point on a sphere at angular coordinates.
     * @param thetaRadians latitude angle
     * @param phiRadians longitude angle
     */
    evaluateThetaPhi(thetaRadians: number, phiRadians: number, result?: Point3d): Point3d;
    /**
     * * convert radians to xyz on unit sphere
     * * Note that there is no radius used -- implicitly radius is 1
     * * Evaluation is always to a preallocated xyz.
     */
    static radiansToUnitSphereXYZ(thetaRadians: number, phiRadians: number, xyz: XYZ): void;
    /** Compute the derivatives with respect to spherical angles.
     * @param thetaRadians latitude angle
     * @param phiRadians longitude angle
     */
    evaluateDerivativesThetaPhi(thetaRadians: number, phiRadians: number, dxdTheta: Vector3d, dxdPhi: Vector3d): void;
}
/** AnalyticRoots has static methods for solving quadratic, cubic, and quartic equations.
 * @internal
 *
 */
export declare class AnalyticRoots {
    private static readonly _EQN_EPS;
    private static readonly _safeDivideFactor;
    /** Absolute zero test with a tolerance that has worked well for the analytic root use case . . . */
    private static isZero;
    /** Without actually doing a division, test if (x/y) is small.
     * @param x numerator
     * @param y denominator
     * @param absTol absolute tolerance
     * @param relTol relative tolerance
     */
    private static isSmallRatio;
    /** Return the (real, signed) principal cube root of x */
    static cbrt(x: number): number;
    /**
     * Try to divide `numerator/denominator` and place the result (or defaultValue) in `values[offset]`
     * @param values array of values.  `values[offset]` will be replaced.
     * @param numerator numerator for division.
     * @param denominator denominator for division.
     * @param defaultValue value to save if denominator is too small to divide.
     * @param offset index of value to replace.
     */
    private static safeDivide;
    private static checkRootProximity;
    private static newtonMethodAdjustment;
    private static improveRoots;
    /**
     * Append (if defined) value to results.
     * @param value optional value to append
     * @param results growing array
     */
    private static appendSolution;
    /**
     * Append 2 solutions -- note that both are required args, no option of omitting as in single solution case
     * @param value1
     * @param value2
     * @param results
     */
    private static append2Solutions;
    /**
     * If `co/c1` is a safe division, append it to the values array.
     * @param c0 numerator
     * @param c1 denominator
     * @param values array to expand
     */
    static appendLinearRoot(c0: number, c1: number, values: GrowableFloat64Array): void;
    /**
     * * Compute the mean of all the entries in `data`
     * * Return the data value that is farthest away
     */
    static mostDistantFromMean(data: GrowableFloat64Array | undefined): number;
    /**
     * Append 0, 1, or 2 solutions of a quadratic to the values array.
     * @param c array of coefficients for quadratic `c[0] + c[1] * x + c[2] * x*x`
     * @param values array to be expanded.
     */
    static appendQuadraticRoots(c: Float64Array | number[], values: GrowableFloat64Array): void;
    /** Add `a` to the constant term. */
    private static addConstant;
    private static signedCubeRoot;
    /**
     * RWD Nickalls Cubic solution
     * The Mathematical Gazette (1993) (vol 77) pp 354-359
     * * ASSUME a is nonzero.
     */
    private static appendFullCubicSolutions;
    /** Compute roots of cubic 'c[0] + c[1] * x + c[2] * x^2 + c[3] * x^3 */
    static appendCubicRoots(c: Float64Array | number[], results: GrowableFloat64Array): void;
    /** Compute roots of quartic `c[0] + c[1] * x + c[2] * x^2 + c[3] * x^3 + c[4] * x^4` */
    static appendQuarticRoots(c: Float64Array | number[], results: GrowableFloat64Array): void;
    private static appendCosSinRadians;
    /**
     * * Solve the simultaneous equations in variables`c` and`s`:
     *   * A line: `alpha + beta*c + gamma*s = 0`
     *   * The unit circle `c*c + s*s = 1`
     * * Solution values are returned as 0, 1, or 2(c, s) pairs
     * * Return value indicates one of these solution states:
     *   * -2 -- all coefficients identically 0.   The entire c, s plane-- and therefore the entire unit circle-- is a solution.
     *   * -1 -- beta, gamma are zero, alpha is not.There is no line defined.There are no solutions.
     *   * 0 -- the line is well defined, but passes completely outside the unit circle.
     *     * In this case, (c1, s1) is the circle point closest to the line and(c2, s2) is the line point closest to the circle.
     *   * 1 -- the line is tangent to the unit circle.
     *     * Tangency is determined by tolerances, which calls a "close approach" point a tangency.
     *       * (c1, s1) is the closest circle point
     *       * (c2, s2) is the line point.
     *   * 2 -- two simple intersections.
     * @param alpha constant coefficient on line
     * @param beta x cosine coefficient on line
     * @param gamma y sine coefficient on line
     * @param relTol relative tolerance for tangencies
     * @param cosValues (caller allocated) array to receive solution `c` values
     * @param sinValues (caller allocated) array to receive solution `s` values
     * @param radiansValues (caller allocated) array to receive solution radians values.
     */
    static appendImplicitLineUnitCircleIntersections(alpha: number, beta: number, gamma: number, cosValues: OptionalGrowableFloat64Array, sinValues: OptionalGrowableFloat64Array, radiansValues: OptionalGrowableFloat64Array, relTol?: number): number;
}
/**
 * Manipulations of polynomials with where `coff[i]` multiplies x^i
 * @internal
 */
export declare class PowerPolynomial {
    /** Evaluate a standard basis polynomial at `x`, with `degree` possibly less than `coff.length` */
    static degreeKnownEvaluate(coff: Float64Array, degree: number, x: number): number;
    /** Evaluate the standard basis polynomial of degree `coff.length` at `x` */
    static evaluate(coff: Float64Array, x: number): number;
    /**
     * Accumulate `coffQ*scaleQ` into `coffP`.
     * * The length of `coffP` must be at least length of `coffQ`.
     * * Returns degree of result as determined by comparing trailing coefficients to zero.
     */
    static accumulate(coffP: Float64Array, coffQ: Float64Array, scaleQ: number): number;
    /** Zero all coefficients */
    static zero(coff: Float64Array): void;
}
/**
 * manipulation of polynomials with powers of sine and cosine
 * @internal
 */
export declare class TrigPolynomial {
    private static readonly _smallAngle;
    /** Standard Basis coefficients for the numerator of the y-coordinate y(t) = S(t)/W(t) in the rational semicircle parameterization. */
    static readonly S: Float64Array;
    /** Standard Basis coefficients for the numerator of the x-coordinate x(t) = C(t)/W(t) in the rational semicircle parameterization. */
    static readonly C: Float64Array;
    /** Standard Basis coefficients for the denominator of x(t) and y(t) in the rational semicircle parameterization. */
    static readonly W: Float64Array;
    /** Standard Basis coefficients for C(t) * W(t). */
    static readonly CW: Float64Array;
    /** Standard Basis coefficients for S(t) * W(t). */
    static readonly SW: Float64Array;
    /** Standard Basis coefficients for S(t) * C(t). */
    static readonly SC: Float64Array;
    /** Standard Basis coefficients for S(t) * S(t). */
    static readonly SS: Float64Array;
    /** Standard Basis coefficients for C(t) * C(t). */
    static readonly CC: Float64Array;
    /** Standard Basis coefficients for W(t) * W(t). */
    static readonly WW: Float64Array;
    /** Standard Basis coefficients for C(t) * C(t) - S(t) * S(t). */
    static readonly CCMinusSS: Float64Array;
    /**
     * Find the roots of a univariate polynomial created from substituting the rational parameterization of the unit
     * circle into a trigonometric polynomial. Roots are returned as radian angles.
     * * Currently implemented for polynomials of degree <= 4.
     * * For example, the ellipse-ellipse intersection problem reduces to finding the roots of a quartic polynomial:
     * `p(t) = coff[0] + coff[1] t + coff[2] t^2 + coff[3] t^3 + coff[4] t^4`.
     * * Particular care is given to report a root at t = +/-infinity, which corresponds to the returned angle -pi/2.
     * @param coff coefficients in the power basis
     * @param nominalDegree degree of the polynomial under the most complex root case.
     * @param referenceCoefficient a number which represents the size of coefficients at various stages of computation.
     * A small fraction of this number will be used as a zero tolerance.
     * @param radians roots are placed here.
     * @return false if equation is all zeros. This usually means any angle is a solution.
     */
    static solveAngles(coff: Float64Array, nominalDegree: number, referenceCoefficient: number, radians: number[]): boolean;
    private static readonly _coefficientRelTol;
    /**
     * Compute intersections of the unit circle `x^2 + y^2 = 1` with the general quadric (conic)
     * `axx x^2 + axy xy + ayy y^2 + ax x + ay y + a = 0`.
     * @param axx coefficient of x^2
     * @param axy coefficient of xy
     * @param ayy coefficient of y^2
     * @param ax coefficient of x
     * @param ay coefficient of y
     * @param a constant coefficient
     * @param radians up to 4 solution angles t in the quadric parameterization: x = cos(t), y = sin(t)
     */
    static solveUnitCircleImplicitQuadricIntersection(axx: number, axy: number, ayy: number, ax: number, ay: number, a: number, radians: number[]): boolean;
    /**
     * Compute intersections of unit circle x^2 + y 2 = 1 with the ellipse
     *         (x,y) = (cx + ux Math.Cos + vx sin, cy + uy Math.Cos + vy sin)
     * Solutions are returned as angles in the ellipse space.
     * @param cx center x
     * @param cy center y
     * @param ux 0 degree vector x
     * @param uy 0 degree vector y
     * @param vx 90 degree vector x
     * @param vy 90 degree vector y
     * @param ellipseRadians solution angles in ellipse parameter space
     * @param circleRadians solution angles in circle parameter space
     */
    static solveUnitCircleEllipseIntersection(cx: number, cy: number, ux: number, uy: number, vx: number, vy: number, ellipseRadians: number[], circleRadians: number[]): boolean;
    /**
     * Compute intersections of unit circle `x^2 + y^2 = w^2` (in homogeneous coordinates) with the ellipse
     * `F(t) = (cx + ux cos(t) + vx sin(t), cy + uy cos(t) + vy sin(t)) / (cw + uw cos(t) + vw sin(t))`.
     * @param cx center x
     * @param cy center y
     * @param cw center w
     * @param ux 0 degree vector x
     * @param uy 0 degree vector y
     * @param uw 0 degree vector w
     * @param vx 90 degree vector x
     * @param vy 90 degree vector y
     * @param vw 90 degree vector w
     * @param ellipseRadians solution angles in ellipse parameter space
     * @param circleRadians solution angles in circle parameter space
     */
    static solveUnitCircleHomogeneousEllipseIntersection(cx: number, cy: number, cw: number, ux: number, uy: number, uw: number, vx: number, vy: number, vw: number, ellipseRadians: number[], circleRadians: number[]): boolean;
}
/**
 * * bilinear expression
 * * `f(u,v) = a + b * u * c * v + d * u * v`
 * @internal
 */
export declare class BilinearPolynomial {
    /** constant coefficient */
    a: number;
    /** u coefficient */
    b: number;
    /** v coefficient */
    c: number;
    /** uv coefficient */
    d: number;
    /**
     *
     * @param a constant coefficient
     * @param b `u` coefficient
     * @param c `v` coefficient
     * @param d `u*v` coefficient
     */
    constructor(a: number, b: number, c: number, d: number);
    /**
     * Evaluate the bilinear expression at u,v
     */
    evaluate(u: number, v: number): number;
    /** Create a bilinear polynomial z=f(u,v) given z values at 00, 10, 01, 11.
     */
    static createUnitSquareValues(f00: number, f10: number, f01: number, f11: number): BilinearPolynomial;
    /**
     * Solve a pair of bilinear equations
     * * First equation: `a0 + b0 * u + c0 * v + d0 * u * v = 0`
     * * Second equation: `a1 + b1 * u + c1 * v + d1 * u * v = 0`
     */
    static solveBilinearPair(a0: number, b0: number, c0: number, d0: number, a1: number, b1: number, c1: number, d1: number): Point2d[] | undefined;
    /**
     * Solve the simultaneous equations
     * * `p(u,v) = pValue`
     * * `q(u,v) = qValue`
     * @param p
     * @param pValue
     * @param q
     * @param qValue
     */
    static solvePair(p: BilinearPolynomial, pValue: number, q: BilinearPolynomial, qValue: number): Point2d[] | undefined;
}
/**
 * * trigonometric expresses `f(theta) = a + cosineCoff * cos(theta) + sineCoff * sin(theta)`
 * @internal
 */
export declare class SineCosinePolynomial {
    /** constant coefficient */
    a: number;
    /** cosine coefficient */
    cosineCoff: number;
    /** sine coefficient */
    sineCoff: number;
    /**
     *
     * @param a constant coefficient
     * @param cosineCoff `cos(theta)` coefficient
     * @param sinCoff `sin(theta)` coefficient
     */
    constructor(a: number, cosCoff: number, sinCoff: number);
    /** set all coefficients */
    set(a: number, cosCoff: number, sinCoff: number): void;
    /** Return the function value at given angle in radians */
    evaluateRadians(theta: number): number;
    /** Return the range of function values over the entire angle range. */
    range(result?: Range1d): Range1d;
    /** Return the min and max values of the function over theta range from radians0 to radians1  inclusive. */
    rangeInStartEndRadians(radians0: number, radians1: number, result?: Range1d): Range1d;
    /** Return the min and max values of the function over theta range from radians0 to radians1  inclusive. */
    rangeInSweep(sweep: AngleSweep, result?: Range1d): Range1d;
    /**
     * Return a representative angle (in radians) for min and max values.
     * * The radians value is atan2(sineCoff, cosineCoff)
     * * Hence the candidates for min and max of the function are at this value and this value plus PI
     */
    referenceMinMaxRadians(): number;
}
/**
 * Support for an implicit linear equation (half space)
 * f(x,y) = a0 + x * ax + y * ay
 * @internal
 */
export declare class ImplicitLineXY {
    /**
     * constant coefficient
     */
    a: number;
    /**
    * x coefficient
    */
    ax: number;
    /**
     * y coefficient
     */
    ay: number;
    /** construct the ImplicitLineXY from coefficients */
    constructor(a: number, ax: number, ay: number);
    /** Compute 2 points of a line segment with
     * * the segment is on the zero-line of this ImplicitLineXY
     * * the start and endpoints are distance `b` from the projection of the origin onto the ImplicitLineXY
     * @returns undefined if ax,ay are both zero.   Otherwise the two points of the segment.
     */
    convertToSegmentPoints(b: number): Point3d[] | undefined;
    /**
     * Evaluate the half-space function at an xy point
     * @param xy xy values for evaluation
     * @returns evaluation.
     */
    evaluatePoint(xy: XAndY): number;
    /**
     * add scale * (a,ax,ay) to the respective coefficients.
     */
    addScaledCoefficientsInPlace(a: number, ax: number, ay: number, scale: number): void;
}
//# sourceMappingURL=Polynomials.d.ts.map