export default Graph;
declare class Graph {
    /**
     * Recreate a Graph based on serialized state from serialize()
     * @public
     *
     * @param {Object} obj
     */
    public static deserialize(obj: Object): Graph;
    static isInternal(point: any, t: any, segment: any, distanceThreshold: any, tThreshold: any): boolean;
    /**
     * "Union" binary winding map filter for use with Graph.binaryResult.
     * @public
     *
     * This combines both shapes together so that a point is in the resulting shape if it was in either of the input
     * shapes.
     *
     * @param {Object} windingMap - See computeFaceInclusion for more details
     * @returns {boolean}
     */
    public static BINARY_NONZERO_UNION(windingMap: Object): boolean;
    /**
     * "Intersection" binary winding map filter for use with Graph.binaryResult.
     * @public
     *
     * This combines both shapes together so that a point is in the resulting shape if it was in both of the input
     * shapes.
     *
     * @param {Object} windingMap - See computeFaceInclusion for more details
     * @returns {boolean}
     */
    public static BINARY_NONZERO_INTERSECTION(windingMap: Object): boolean;
    /**
     * "Difference" binary winding map filter for use with Graph.binaryResult.
     * @public
     *
     * This combines both shapes together so that a point is in the resulting shape if it was in the first shape AND
     * was NOT in the second shape.
     *
     * @param {Object} windingMap - See computeFaceInclusion for more details
     * @returns {boolean}
     */
    public static BINARY_NONZERO_DIFFERENCE(windingMap: Object): boolean;
    /**
     * "XOR" binary winding map filter for use with Graph.binaryResult.
     * @public
     *
     * This combines both shapes together so that a point is in the resulting shape if it is only in exactly one of the
     * input shapes. It's like the union minus intersection.
     *
     * @param {Object} windingMap - See computeFaceInclusion for more details
     * @returns {boolean}
     */
    public static BINARY_NONZERO_XOR(windingMap: Object): boolean;
    /**
     * Returns the resulting Shape obtained by combining the two shapes given with the filter.
     * @public
     *
     * @param {Shape} shapeA
     * @param {Shape} shapeB
     * @param {function} windingMapFilter - See computeFaceInclusion for details on the format
     * @returns {Shape}
     */
    public static binaryResult(shapeA: Shape, shapeB: Shape, windingMapFilter: Function): Shape;
    /**
     * Returns the union of an array of shapes.
     * @public
     *
     * @param {Array.<Shape>} shapes
     * @returns {Shape}
     */
    public static unionNonZero(shapes: Array<Shape>): Shape;
    /**
     * Returns the intersection of an array of shapes.
     * @public
     *
     * @param {Array.<Shape>} shapes
     * @returns {Shape}
     */
    public static intersectionNonZero(shapes: Array<Shape>): Shape;
    /**
     * Returns the xor of an array of shapes.
     * @public
     *
     * TODO: reduce code duplication? https://github.com/phetsims/kite/issues/76
     *
     * @param {Array.<Shape>} shapes
     * @returns {Shape}
     */
    public static xorNonZero(shapes: Array<Shape>): Shape;
    /**
     * Returns a simplified Shape obtained from running it through the simplification steps with non-zero output.
     * @public
     *
     * @param {Shape} shape
     * @returns {Shape}
     */
    public static simplifyNonZero(shape: Shape): Shape;
    /**
     * Returns a clipped version of `shape` that contains only the parts that are within the area defined by
     * `clipAreaShape`
     * @public
     *
     * @param {Shape} clipAreaShape
     * @param {Shape} shape
     * @param {Object} [options]
     * @returns {Shape}
     */
    public static clipShape(clipAreaShape: Shape, shape: Shape, options?: Object | undefined): Shape;
    vertices: any[];
    edges: any[];
    innerBoundaries: any[];
    outerBoundaries: any[];
    boundaries: any[];
    shapeIds: any[];
    loops: any[];
    unboundedFace: Face;
    faces: Face[];
    /**
     * Returns an object form that can be turned back into a segment with the corresponding deserialize method.
     * @public
     *
     * @returns {Object}
     */
    public serialize(): Object;
    /**
     * Adds a Shape (with a given ID for CAG purposes) to the graph.
     * @public
     *
     * @param {number} shapeId - The ID which should be shared for all paths/shapes that should be combined with
     *                           respect to the winding number of faces. For CAG, independent shapes should be given
     *                           different IDs (so they have separate winding numbers recorded).
     * @param {Shape} shape
     * @param {Object} [options] - See addSubpath
     */
    public addShape(shapeId: number, shape: Shape, options?: Object | undefined): void;
    /**
     * Adds a subpath of a Shape (with a given ID for CAG purposes) to the graph.
     * @public
     *
     * @param {number} shapeId - See addShape() documentation
     * @param {Subpath} subpath
     * @param {Object} [options]
     */
    public addSubpath(shapeId: number, subpath: Subpath, options?: Object | undefined): void;
    /**
     * Simplifies edges/vertices, computes boundaries and faces (with the winding map).
     * @public
     */
    public computeSimplifiedFaces(): void;
    /**
     * Sets whether each face should be filled or unfilled based on a filter function.
     * @public
     *
     * The windingMapFilter will be called on each face's winding map, and will use the return value as whether the face
     * is filled or not.
     *
     * The winding map is an {Object} associated with each face that has a key for every shapeId that was used in
     * addShape/addSubpath, and the value for those keys is the winding number of the face given all paths with the
     * shapeId.
     *
     * For example, imagine you added two shapeIds (0 and 1), and the iteration is on a face that is included in
     * one loop specified with shapeId:0 (inside a counter-clockwise curve), and is outside of any segments specified
     * by the second loop (shapeId:1). Then the winding map will be:
     * {
     *   0: 1 // shapeId:0 has a winding number of 1 for this face (generally filled)
     *   1: 0 // shapeId:1 has a winding number of 0 for this face (generally not filled)
     * }
     *
     * Generally, winding map filters can be broken down into two steps:
     * 1. Given the winding number for each shapeId, compute whether that loop was originally filled. Normally, this is
     *    done with a non-zero rule (any winding number is filled, except zero). SVG also provides an even-odd rule
     *    (odd numbers are filled, even numbers are unfilled).
     * 2. Given booleans for each shapeId from step 1, compute CAG operations based on boolean formulas. Say you wanted
     *    to take the union of shapeIds 0 and 1, then remove anything in shapeId 2. Given the booleans above, this can
     *    be directly computed as (filled0 || filled1) && !filled2.
     *
     * @param {function} windingMapFilter
     */
    public computeFaceInclusion(windingMapFilter: Function): void;
    /**
     * Create a new Graph object based only on edges in this graph that separate a "filled" face from an "unfilled"
     * face.
     * @public
     *
     * This is a convenient way to "collapse" adjacent filled and unfilled faces together, and compute the curves and
     * holes properly, given a filled "normal" graph.
     */
    public createFilledSubGraph(): Graph;
    /**
     * Returns a Shape that creates a subpath for each filled face (with the desired holes).
     * @public
     *
     * Generally should be called on a graph created with createFilledSubGraph().
     *
     * @returns {Shape}
     */
    public facesToShape(): Shape;
    /**
     * Releases owned objects to their pools, and clears references that may have been picked up from external sources.
     * @public
     */
    public dispose(): void;
    /**
     * Adds an edge to the graph (and sets up connection information).
     * @private
     *
     * @param {Edge} edge
     */
    private addEdge;
    /**
     * Removes an edge from the graph (and disconnects incident information).
     * @private
     *
     * @param {Edge} edge
     */
    private removeEdge;
    /**
     * Replaces a single edge (in loops) with a series of edges (possibly empty).
     * @private
     *
     * @param {Edge} edge
     * @param {Array.<HalfEdge>} forwardHalfEdges
     */
    private replaceEdgeInLoops;
    /**
     * Tries to combine adjacent edges (with a 2-order vertex) into one edge where possible.
     * @private
     *
     * This helps to combine things like collinear lines, where there's a vertex that can basically be removed.
     */
    private collapseAdjacentEdges;
    /**
     * Gets rid of overlapping segments by combining overlaps into a shared edge.
     * @private
     */
    private eliminateOverlap;
    /**
     * Splits/combines edges when there is an overlap of two edges (two edges who have an infinite number of
     * intersection points).
     * @private
     *
     * NOTE: This does NOT dispose aEdge/bEdge, due to eliminateOverlap's needs.
     *
     * Generally this creates an edge for the "shared" part of both segments, and then creates edges for the parts
     * outside of the shared region, connecting them together.
     *
     * @param {Edge} aEdge
     * @param {Edge} bEdge
     * @param {Overlap} overlap
     * @returns {Array.<Edge>}
     */
    private splitOverlap;
    /**
     * Handles splitting of self-intersection of segments (happens with Cubics).
     * @private
     */
    private eliminateSelfIntersection;
    /**
     * Replace intersections between different segments by splitting them and creating a vertex.
     * @private
     */
    private eliminateIntersection;
    /**
     * Handles splitting two intersecting edges.
     * @private
     *
     * @param {Edge} aEdge
     * @param {Edge} bEdge
     * @param {number} aT - Parametric t value of the intersection for aEdge
     * @param {number} bT - Parametric t value of the intersection for bEdge
     * @param {Vector2} point - Location of the intersection
     *
     * @returns {{addedEdges: Edge[], removedEdges: Edge[]}|null}
     */
    private simpleSplit;
    /**
     * Splits an edge into two edges at a specific parametric t value.
     * @private
     *
     * @param {Edge} edge
     * @param {number} t
     * @param {Vertex} vertex - The vertex that is placed at the split location
     */
    private splitEdge;
    /**
     * Combine vertices that are almost exactly in the same place (removing edges and vertices where necessary).
     * @private
     */
    private collapseVertices;
    /**
     * Scan a given vertex for bridges recursively with a depth-first search.
     * @private
     *
     * Records visit times to each vertex, and back-propagates so that we can efficiently determine if there was another
     * path around to the vertex.
     *
     * Assumes this is only called one time once all edges/vertices are set up. Repeated calls will fail because we
     * don't mark visited/etc. references again on startup
     *
     * See Tarjan's algorithm for more information. Some modifications were needed, since this is technically a
     * multigraph/pseudograph (can have edges that have the same start/end vertex, and can have multiple edges
     * going from the same two vertices).
     *
     * @param {Array.<Edge>} bridges - Appends bridge edges to here.
     * @param {Vertex} vertex
     */
    private markBridges;
    /**
     * Removes edges that are the only edge holding two connected components together. Based on our problem, the
     * face on either side of the "bridge" edges would always be the same, so we can safely remove them.
     * @private
     */
    private removeBridges;
    /**
     * Removes vertices that have order less than 2 (so either a vertex with one or zero edges adjacent).
     * @private
     */
    private removeLowOrderVertices;
    /**
     * Sorts incident half-edges for each vertex.
     * @private
     */
    private orderVertexEdges;
    /**
     * Creates boundaries and faces by following each half-edge counter-clockwise
     * @private
     */
    private extractFaces;
    /**
     * Given the inner and outer boundaries, it computes a tree representation to determine what boundaries are
     * holes of what other boundaries, then sets up face holes with the result.
     * @public
     *
     * This information is stored in the childBoundaries array of Boundary, and is then read out to set up faces.
     */
    public computeBoundaryTree(): void;
    /**
     * Computes the winding map for each face, starting with 0 on the unbounded face (for each shapeId).
     * @private
     */
    private computeWindingMap;
    /**
     * Computes the differential in winding numbers (forward face winding number minus the reversed face winding number)
     * ("forward face" is the face on the forward half-edge side, etc.)
     * @private
     *
     * @param {Edge} edge
     * @param {number} shapeId
     * @returns {number} - The difference between forward face and reversed face winding numbers.
     */
    private computeDifferential;
    /**
     * Sets the unbounded face as unfilled, and then sets each face's fill so that edges separate one filled face with
     * one unfilled face.
     * @private
     *
     * NOTE: Best to call this on the result from createFilledSubGraph(), since it should have guaranteed properties
     *       to make this consistent. Notably, all vertices need to have an even order (number of edges)
     */
    private fillAlternatingFaces;
    /**
     * Returns the boundary that contains the specified half-edge.
     * @private
     *
     * TODO: find a better way, this is crazy inefficient https://github.com/phetsims/kite/issues/76
     *
     * @param {HalfEdge} halfEdge
     * @returns {Boundary}
     */
    private getBoundaryOfHalfEdge;
}
import { Face } from '../imports.js';
import { Subpath } from '../imports.js';
//# sourceMappingURL=Graph.d.ts.map