import '../../../assert/js/assert.js';
import '../../../globals.js';
/**
 * Cubic Bezier segment.
 *
 * See http://www.cis.usouthal.edu/~hain/general/Publications/Bezier/BezierFlattening.pdf for info
 *
 * Good reference: http://cagd.cs.byu.edu/~557/text/ch2.pdf
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import Bounds2 from '../../../dot/js/Bounds2.js';
import Matrix3 from '../../../dot/js/Matrix3.js';
import Ray2 from '../../../dot/js/Ray2.js';
import Vector2 from '../../../dot/js/Vector2.js';
import { Line, Overlap, Quadratic, RayIntersection, Segment, SegmentIntersection } from '../imports.js';
export type SerializedCubic = {
    type: 'Cubic';
    startX: number;
    startY: number;
    control1X: number;
    control1Y: number;
    control2X: number;
    control2Y: number;
    endX: number;
    endY: number;
};
export default class Cubic extends Segment {
    private _start;
    private _control1;
    private _control2;
    private _end;
    private _startTangent;
    private _endTangent;
    private _r;
    private _s;
    private _tCusp;
    private _tDeterminant;
    private _tInflection1;
    private _tInflection2;
    private _quadratics;
    private _xExtremaT;
    private _yExtremaT;
    private _bounds;
    private _svgPathFragment;
    /**
     * @param start - Start point of the cubic bezier
     * @param control1 - First control point (curve usually doesn't go through here)
     * @param control2 - Second control point (curve usually doesn't go through here)
     * @param end - End point of the cubic bezier
     */
    constructor(start: Vector2, control1: Vector2, control2: Vector2, end: Vector2);
    /**
     * Sets the start point of the Cubic.
     */
    setStart(start: Vector2): this;
    set start(value: Vector2);
    get start(): Vector2;
    /**
     * Returns the start of this Cubic.
     */
    getStart(): Vector2;
    /**
     * Sets the first control point of the Cubic.
     */
    setControl1(control1: Vector2): this;
    set control1(value: Vector2);
    get control1(): Vector2;
    /**
     * Returns the first control point of this Cubic.
     */
    getControl1(): Vector2;
    /**
     * Sets the second control point of the Cubic.
     */
    setControl2(control2: Vector2): this;
    set control2(value: Vector2);
    get control2(): Vector2;
    /**
     * Returns the second control point of this Cubic.
     */
    getControl2(): Vector2;
    /**
     * Sets the end point of the Cubic.
     */
    setEnd(end: Vector2): this;
    set end(value: Vector2);
    get end(): Vector2;
    /**
     * Returns the end of this Cubic.
     */
    getEnd(): Vector2;
    /**
     * Returns the position parametrically, with 0 <= t <= 1.
     *
     * NOTE: positionAt( 0 ) will return the start of the segment, and positionAt( 1 ) will return the end of the
     * segment.
     *
     * This method is part of the Segment API. See Segment.js's constructor for more API documentation.
     */
    positionAt(t: number): Vector2;
    /**
     * Returns the non-normalized tangent (dx/dt, dy/dt) of this segment at the parametric value of t, with 0 <= t <= 1.
     *
     * NOTE: tangentAt( 0 ) will return the tangent at the start of the segment, and tangentAt( 1 ) will return the
     * tangent at the end of the segment.
     *
     * This method is part of the Segment API. See Segment.js's constructor for more API documentation.
     */
    tangentAt(t: number): Vector2;
    /**
     * Returns the signed curvature of the segment at the parametric value t, where 0 <= t <= 1.
     *
     * The curvature will be positive for visual clockwise / mathematical counterclockwise curves, negative for opposite
     * curvature, and 0 for no curvature.
     *
     * NOTE: curvatureAt( 0 ) will return the curvature at the start of the segment, and curvatureAt( 1 ) will return
     * the curvature at the end of the segment.
     *
     * This method is part of the Segment API. See Segment.js's constructor for more API documentation.
     */
    curvatureAt(t: number): number;
    /**
     * Returns an array with up to 2 sub-segments, split at the parametric t value. Together (in order) they should make
     * up the same shape as the current segment.
     *
     * This method is part of the Segment API. See Segment.js's constructor for more API documentation.
     */
    subdivided(t: number): Cubic[];
    /**
     * Clears cached information, should be called when any of the 'constructor arguments' are mutated.
     */
    invalidate(): void;
    /**
     * Gets the start position of this cubic polynomial.
     */
    getStartTangent(): Vector2;
    get startTangent(): Vector2;
    /**
     * Gets the end position of this cubic polynomial.
     */
    getEndTangent(): Vector2;
    get endTangent(): Vector2;
    /**
     * TODO: documentation https://github.com/phetsims/kite/issues/76
     */
    getR(): Vector2;
    get r(): Vector2;
    /**
     * TODO: documentation https://github.com/phetsims/kite/issues/76
     */
    getS(): Vector2;
    get s(): Vector2;
    /**
     * Returns the parametric t value for the possible cusp location. A cusp may or may not exist at that point.
     */
    getTCusp(): number;
    get tCusp(): number;
    /**
     * Returns the determinant value for the cusp, which indicates the presence (or lack of presence) of a cusp.
     */
    getTDeterminant(): number;
    get tDeterminant(): number;
    /**
     * Returns the parametric t value for the potential location of the first possible inflection point.
     */
    getTInflection1(): number;
    get tInflection1(): number;
    /**
     * Returns the parametric t value for the potential location of the second possible inflection point.
     */
    getTInflection2(): number;
    get tInflection2(): number;
    /**
     * If there is a cusp, this cubic will consist of one or two quadratic segments, typically "start => cusp" and
     * "cusp => end".
     */
    getQuadratics(): Quadratic[] | null;
    /**
     * Returns a list of parametric t values where x-extrema exist, i.e. where dx/dt==0. These are candidate locations
     * on the cubic for "maximum X" and "minimum X", and are needed for bounds computations.
     */
    getXExtremaT(): number[];
    get xExtremaT(): number[];
    /**
     * Returns a list of parametric t values where y-extrema exist, i.e. where dy/dt==0. These are candidate locations
     * on the cubic for "maximum Y" and "minimum Y", and are needed for bounds computations.
     */
    getYExtremaT(): number[];
    get yExtremaT(): number[];
    /**
     * Returns the bounds of this segment.
     */
    getBounds(): Bounds2;
    get bounds(): Bounds2;
    /**
     * Computes all cusp-related information, including whether there is a cusp, any inflection points, etc.
     */
    private computeCuspInfo;
    /**
     * If there is a cusp, this computes the 2 quadratic Bezier curves that this Cubic can be converted into.
     */
    private computeCuspSegments;
    /**
     * Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies)
     * invalid or repeated segments.
     */
    getNondegenerateSegments(): Segment[];
    /**
     * Returns whether this cubic has a cusp.
     */
    hasCusp(): boolean;
    toRS(point: Vector2): Vector2;
    offsetTo(r: number, reverse: boolean): Line[];
    /**
     * Returns a string containing the SVG path. assumes that the start point is already provided, so anything that calls this needs to put
     * the M calls first
     */
    getSVGPathFragment(): string;
    /**
     * Returns an array of lines that will draw an offset curve on the logical left side
     */
    strokeLeft(lineWidth: number): Line[];
    /**
     * Returns an array of lines that will draw an offset curve on the logical right side
     */
    strokeRight(lineWidth: number): Line[];
    /**
     * Returns a list of t values where dx/dt or dy/dt is 0 where 0 < t < 1. subdividing on these will result in monotonic segments
     * The list does not include t=0 and t=1
     */
    getInteriorExtremaTs(): number[];
    /**
     * Hit-tests this segment with the ray. An array of all intersections of the ray with this segment will be returned.
     * For details, see the documentation in Segment.js
     */
    intersection(ray: Ray2): RayIntersection[];
    /**
     * Returns the winding number for intersection with a ray
     */
    windingIntersection(ray: Ray2): number;
    /**
     * Draws the segment to the 2D Canvas context, assuming the context's current location is already at the start point
     */
    writeToContext(context: CanvasRenderingContext2D): void;
    /**
     * Returns a new cubic that represents this cubic after transformation by the matrix
     */
    transformed(matrix: Matrix3): Cubic;
    /**
     * Returns a degree-reduced quadratic Bezier if possible, otherwise it returns null
     */
    degreeReduced(epsilon: number): Quadratic | null;
    /**
     * Returns the contribution to the signed area computed using Green's Theorem, with P=-y/2 and Q=x/2.
     *
     * NOTE: This is this segment's contribution to the line integral (-y/2 dx + x/2 dy).
     */
    getSignedAreaFragment(): number;
    /**
     * Returns a reversed copy of this segment (mapping the parametrization from [0,1] => [1,0]).
     */
    reversed(): Cubic;
    /**
     * If it exists, returns the point where the cubic curve self-intersects.
     *
     * @returns - Null if there is no intersection
     */
    getSelfIntersection(): SegmentIntersection | null;
    /**
     * Returns an object form that can be turned back into a segment with the corresponding deserialize method.
     */
    serialize(): SerializedCubic;
    /**
     * Determine whether two lines overlap over a continuous section, and if so finds the a,b pair such that
     * p( t ) === q( a * t + b ).
     *
     * @param segment
     * @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more
     *                             in one component.
     * @returns - The solution, if there is one (and only one)
     */
    getOverlaps(segment: Segment, epsilon?: number): Overlap[] | null;
    /**
     * Returns a Cubic from the serialized representation.
     */
    static deserialize(obj: SerializedCubic): Cubic;
    /**
     * Finds what t values the cubic extrema are at (if any). This is just the 1-dimensional case, used for multiple purposes
     */
    static extremaT(v0: number, v1: number, v2: number, v3: number): number[];
    /**
     * Determine whether two Cubics overlap over a continuous section, and if so finds the a,b pair such that
     * p( t ) === q( a * t + b ).
     *
     * NOTE: for this particular function, we assume we're not degenerate. Things may work if we can be degree-reduced
     * to a quadratic, but generally that shouldn't be done.
     *
     * @param cubic1
     * @param cubic2
     * @param [epsilon] - Will return overlaps only if no two corresponding points differ by this amount or more
     *                    in one component.
     * @returns - The solution, if there is one (and only one)
     */
    static getOverlaps(cubic1: Cubic, cubic2: Cubic, epsilon?: number): Overlap[];
    degree: number;
}
//# sourceMappingURL=Cubic.d.ts.map