"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectHalfCosineSpiralEvaluator = void 0;
/** @packageDocumentation
 * @module Curve
 */
const Geometry_1 = require("../../Geometry");
const XYCurveEvaluator_1 = require("./XYCurveEvaluator");
const Newton_1 = require("../../numerics/Newton");
/**
 * @internal
 */
class DirectHalfCosineSpiralEvaluator extends XYCurveEvaluator_1.XYCurveEvaluator {
    nominalLength1;
    nominalRadius1;
    _c;
    _c1;
    _c2;
    constructor(length1, radius1) {
        super();
        this.nominalLength1 = length1;
        this.nominalRadius1 = radius1;
        const pi = Math.PI;
        this._c1 = 1.0 / (2.0 * pi * pi);
        this._c2 = 0.25;
        this._c = 0.0; // TO BE UPDATED BELOW
        this.updateConstants();
    }
    updateConstants() {
        this._c = this.nominalLength1 * this.nominalLength1 / this.nominalRadius1;
    }
    scaleInPlace(scaleFactor) {
        this.nominalLength1 *= scaleFactor;
        this.nominalRadius1 *= scaleFactor;
        this.updateConstants();
    }
    /** Return a deep copy of the evaluator. */
    clone() {
        return new DirectHalfCosineSpiralEvaluator(this.nominalLength1, this.nominalRadius1);
    }
    /** Member by member matchup. */
    isAlmostEqual(other) {
        if (other instanceof DirectHalfCosineSpiralEvaluator) {
            return Geometry_1.Geometry.isSameCoordinate(this.nominalLength1, other.nominalLength1)
                && Geometry_1.Geometry.isSameCoordinate(this.nominalRadius1, other.nominalRadius1);
            // remark: c,c1,c2 are computed, need not be tested.
        }
        return false;
    }
    /** Evaluate X at fractional position. */
    fractionToX(fraction) {
        return fraction * this.nominalLength1;
    }
    /** Evaluate Y at fractional position. */
    fractionToY(fraction) {
        const theta = fraction * Math.PI;
        return this._c * (this._c2 * fraction * fraction - this._c1 * (1.0 - Math.cos(theta)));
    }
    /** Evaluate derivative of X with respect to fraction at fractional position. */
    fractionToDX(_fraction) {
        return this.nominalLength1;
    }
    /** Evaluate derivative of Y with respect to fraction at fractional position. */
    fractionToDY(fraction) {
        const pi = Math.PI;
        const theta = fraction * pi;
        return this._c * (2.0 * this._c2 * fraction - this._c1 * pi * Math.sin(theta));
    }
    /** Evaluate second derivative of X with respect to fraction at fractional position. */
    fractionToDDX(_fraction) {
        return 0.0;
    }
    /** Evaluate third derivative of Y with respect to fraction at fractional position. */
    fractionToDDY(fraction) {
        const pi = Math.PI;
        const theta = fraction * pi;
        return this._c * (2.0 * this._c2 - this._c1 * pi * pi * Math.cos(theta));
    }
    /** Evaluate second derivative of X with respect to fraction at fractional position. */
    fractionToD3X(_fraction) {
        return 0.0;
    }
    /** Evaluate third derivative of Y with respect to fraction at fractional position. */
    fractionToD3Y(fraction) {
        const pi = Math.PI;
        const theta = fraction * pi;
        return this._c * this._c1 * pi * pi * pi * Math.sin(theta);
    }
    /** Return the magnitude of the first vector at fractional coordinate. */
    fractionToTangentMagnitude(fraction) {
        return Geometry_1.Geometry.hypotenuseXY(this.fractionToDX(fraction), this.fractionToDY(fraction));
    }
    /** Invert the fractionToX function for given X. */
    xToFraction(x) {
        const fraction0 = x / this.nominalLength1;
        const fraction1 = Newton_1.SimpleNewton.runNewton1D(fraction0, (f) => (this.fractionToX(f) - x), (f) => this.fractionToDX(f));
        if (fraction1 === undefined)
            return undefined;
        return fraction1;
    }
}
exports.DirectHalfCosineSpiralEvaluator = DirectHalfCosineSpiralEvaluator;
//# sourceMappingURL=DirectHalfCosineSpiralEvaluator.js.map