import '../../../assert/js/assert.js';
import '../../../globals.js';
/**
 * An elliptical arc (a continuous sub-part of an ellipse).
 *
 * Additional helpful notes:
 * - http://www.w3.org/TR/SVG/implnote.html#PathElementImplementationNotes
 * - http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-ellipse
 *   (note: context.ellipse was removed from the Canvas spec)
 *
 * @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 Transform3 from '../../../dot/js/Transform3.js';
import Vector2 from '../../../dot/js/Vector2.js';
import Enumeration from '../../../phet-core/js/Enumeration.js';
import EnumerationValue from '../../../phet-core/js/EnumerationValue.js';
import { Arc, Line, Overlap, RayIntersection, Segment, SegmentIntersection } from '../imports.js';
export type SerializedEllipticalArc = {
    type: 'EllipticalArc';
    centerX: number;
    centerY: number;
    radiusX: number;
    radiusY: number;
    rotation: number;
    startAngle: number;
    endAngle: number;
    anticlockwise: boolean;
};
export default class EllipticalArc extends Segment {
    private _center;
    private _radiusX;
    private _radiusY;
    private _rotation;
    private _startAngle;
    private _endAngle;
    private _anticlockwise;
    private _unitTransform;
    private _start;
    private _end;
    private _startTangent;
    private _endTangent;
    private _actualEndAngle;
    private _isFullPerimeter;
    private _angleDifference;
    private _unitArcSegment;
    private _bounds;
    private _svgPathFragment;
    private possibleExtremaAngles?;
    /**
     * If the startAngle/endAngle difference is ~2pi, this will be a full ellipse
     *
     * @param center - Center of the ellipse
     * @param radiusX - Semi-major radius
     * @param radiusY - Semi-minor radius
     * @param rotation - Rotation of the semi-major axis
     * @param startAngle - Angle (radians) of the start of the arc
     * @param endAngle - Angle (radians) of the end of the arc
     * @param anticlockwise - Decides which direction the arc takes around the center
     */
    constructor(center: Vector2, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise: boolean);
    /**
     * Sets the center of the EllipticalArc.
     */
    setCenter(center: Vector2): this;
    set center(value: Vector2);
    get center(): Vector2;
    /**
     * Returns the center of this EllipticalArc.
     */
    getCenter(): Vector2;
    /**
     * Sets the semi-major radius of the EllipticalArc.
     */
    setRadiusX(radiusX: number): this;
    set radiusX(value: number);
    get radiusX(): number;
    /**
     * Returns the semi-major radius of this EllipticalArc.
     */
    getRadiusX(): number;
    /**
     * Sets the semi-minor radius of the EllipticalArc.
     */
    setRadiusY(radiusY: number): this;
    set radiusY(value: number);
    get radiusY(): number;
    /**
     * Returns the semi-minor radius of this EllipticalArc.
     */
    getRadiusY(): number;
    /**
     * Sets the rotation of the EllipticalArc.
     */
    setRotation(rotation: number): this;
    set rotation(value: number);
    get rotation(): number;
    /**
     * Returns the rotation of this EllipticalArc.
     */
    getRotation(): number;
    /**
     * Sets the startAngle of the EllipticalArc.
     */
    setStartAngle(startAngle: number): this;
    set startAngle(value: number);
    get startAngle(): number;
    /**
     * Returns the startAngle of this EllipticalArc.
     */
    getStartAngle(): number;
    /**
     * Sets the endAngle of the EllipticalArc.
     */
    setEndAngle(endAngle: number): this;
    set endAngle(value: number);
    get endAngle(): number;
    /**
     * Returns the endAngle of this EllipticalArc.
     */
    getEndAngle(): number;
    /**
     * Sets the anticlockwise of the EllipticalArc.
     */
    setAnticlockwise(anticlockwise: boolean): this;
    set anticlockwise(value: boolean);
    get anticlockwise(): boolean;
    /**
     * Returns the anticlockwise of this EllipticalArc.
     */
    getAnticlockwise(): boolean;
    /**
     * 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): EllipticalArc[];
    /**
     * Clears cached information, should be called when any of the 'constructor arguments' are mutated.
     */
    invalidate(): void;
    /**
     * Computes a transform that maps a unit circle into this ellipse's location.
     *
     * Helpful, since we can get the parametric position of our unit circle (at t), and then transform it with this
     * transform to get the ellipse's parametric position (at t).
     */
    getUnitTransform(): Transform3;
    get unitTransform(): Transform3;
    /**
     * Gets the start point of this ellipticalArc
     */
    getStart(): Vector2;
    get start(): Vector2;
    /**
     * Gets the end point of this ellipticalArc
     */
    getEnd(): Vector2;
    get end(): Vector2;
    /**
     * Gets the tangent vector (normalized) to this ellipticalArc at the start, pointing in the direction of motion (from start to end)
     */
    getStartTangent(): Vector2;
    get startTangent(): Vector2;
    /**
     * Gets the tangent vector (normalized) to this ellipticalArc at the end point, pointing in the direction of motion (from start to end)
     */
    getEndTangent(): Vector2;
    get endTangent(): Vector2;
    /**
     * Gets the end angle in radians
     */
    getActualEndAngle(): number;
    get actualEndAngle(): number;
    /**
     * Returns a boolean value that indicates if the arc wraps up by more than two Pi
     */
    getIsFullPerimeter(): boolean;
    get isFullPerimeter(): boolean;
    /**
     * Returns an angle difference that represents how "much" of the circle our arc covers
     *
     * The answer is always greater or equal to zero
     * The answer can exceed two Pi
     */
    getAngleDifference(): number;
    get angleDifference(): number;
    /**
     * A unit arg segment that we can map to our ellipse. useful for hit testing and such.
     */
    getUnitArcSegment(): Arc;
    get unitArcSegment(): Arc;
    /**
     * Returns the bounds of this segment.
     */
    getBounds(): Bounds2;
    get bounds(): Bounds2;
    /**
     * Returns a list of non-degenerate segments that are equivalent to this segment. Generally gets rid (or simplifies)
     * invalid or repeated segments.
     */
    getNondegenerateSegments(): Segment[];
    /**
     * Attempts to expand the private _bounds bounding box to include a point at a specific angle, making sure that
     * angle is actually included in the arc. This will presumably be called at angles that are at critical points,
     * where the arc should have maximum/minimum x/y values.
     */
    private includeBoundsAtAngle;
    /**
     * Maps a contained angle to between [startAngle,actualEndAngle), even if the end angle is lower.
     *
     * TODO: remove duplication with Arc https://github.com/phetsims/kite/issues/76
     */
    mapAngle(angle: number): number;
    /**
     * Returns the parametrized value t for a given angle. The value t should range from 0 to 1 (inclusive).
     *
     * TODO: remove duplication with Arc https://github.com/phetsims/kite/issues/76
     */
    tAtAngle(angle: number): number;
    /**
     * Returns the angle for the parametrized t value. The t value should range from 0 to 1 (inclusive).
     */
    angleAt(t: number): number;
    /**
     * Returns the position of this arc at angle.
     */
    positionAtAngle(angle: number): Vector2;
    /**
     * Returns the normalized tangent of this arc.
     * The tangent points outward (inward) of this arc for clockwise (anticlockwise) direction.
     */
    tangentAtAngle(angle: number): Vector2;
    /**
     * Returns an array of straight lines that will draw an offset on the logical left (right) side for reverse false (true)
     * It discretizes the elliptical arc in 32 segments and returns an offset curve as a list of lineTos/
     *
     * @param r - distance
     * @param reverse
     */
    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 straight lines  that will draw an offset on the logical left side.
     */
    strokeLeft(lineWidth: number): Line[];
    /**
     * Returns an array of straight 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
     * 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 resultant winding number of this ray intersecting this arc.
     */
    windingIntersection(ray: Ray2): number;
    /**
     * Draws this arc to the 2D Canvas context, assuming the context's current location is already at the start point
     */
    writeToContext(context: CanvasRenderingContext2D): void;
    /**
     * Returns this elliptical arc transformed by a matrix
     */
    transformed(matrix: Matrix3): EllipticalArc;
    /**
     * 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(): EllipticalArc;
    /**
     * Returns an object form that can be turned back into a segment with the corresponding deserialize method.
     */
    serialize(): SerializedEllipticalArc;
    /**
     * 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 the matrix representation of the conic section of the ellipse.
     * See https://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections
     */
    getConicMatrix(): Matrix3;
    /**
     * Returns an EllipticalArc from the serialized representation.
     */
    static deserialize(obj: SerializedEllipticalArc): EllipticalArc;
    /**
     * Returns what type of overlap is possible based on the center/radii/rotation. We ignore the start/end angles and
     * anticlockwise information, and determine if the FULL ellipses overlap.
     */
    static getOverlapType(a: EllipticalArc, b: EllipticalArc, epsilon?: number): EllipticalArcOverlapType;
    /**
     * Determine whether two elliptical arcs overlap over continuous sections, and if so finds the a,b pairs such that
     * p( t ) === q( a * t + b ).
     *
     * @returns - Any overlaps (from 0 to 2)
     */
    static getOverlaps(a: EllipticalArc, b: EllipticalArc): Overlap[];
    /**
     * Returns any (finite) intersection between the two elliptical arc segments.
     */
    static intersect(a: EllipticalArc, b: EllipticalArc, epsilon?: number): SegmentIntersection[];
    /**
     * Matrix that transforms the unit circle into our ellipse
     */
    static computeUnitMatrix(center: Vector2, radiusX: number, radiusY: number, rotation: number): Matrix3;
    /**
     * Transforms the unit circle into our ellipse.
     *
     * adapted from http://www.w3.org/TR/SVG/implnote.html#PathElementImplementationNotes
     */
    static computeUnitTransform(center: Vector2, radiusX: number, radiusY: number, rotation: number): Transform3;
}
export declare class EllipticalArcOverlapType extends EnumerationValue {
    static readonly MATCHING_OVERLAP: EllipticalArcOverlapType;
    static readonly OPPOSITE_OVERLAP: EllipticalArcOverlapType;
    static readonly NONE: EllipticalArcOverlapType;
    static readonly enumeration: Enumeration<EllipticalArcOverlapType>;
}
//# sourceMappingURL=EllipticalArc.d.ts.map