declare class Vector {
    x: number;
    y: number;
    origen: Punto;
    id: number;
    private constructor();
    get magnitud(): number;
    get angulo(): number;
    static cero(): Vector;
    static arriba(magnitud?: number): Vector;
    static abajo(magnitud?: number): Vector;
    static izquierda(magnitud?: number): Vector;
    static derecha(magnitud?: number): Vector;
    /**Retorna un Vector aleatorio con magnitud definida.
     * Si no se determina una magnitud, retorna un vector normalizado.
     */
    static aleatorio(magnitud?: number): Vector;
    /**Retorna un vector nuevo a partir de las componentes x e y ingresadas.*/
    static crear(x: number, y: number): Vector;
    /**Retorna un vector nuevo que va desde un punto origen a un punto extremo.*/
    static segunPuntos(origen: Punto, extremo: Punto): Vector;
    /**Retorna una copia de un conjunto de vectores.*/
    static clonarConjunto(vectores: Vector[]): Vector[];
    /**Retorna el vector normal de un segmento formado por dos vectores.
     * El ángulo de la normal va en sentido antihorario según la dirección del primer al segundo vector.
     * (Según la inverción de ejes de las coordenadas de JS, donde los ángulos crecen en sentido horario).
    */
    static normal(vectorUno: Vector, vectorDos: Vector): Vector;
    /**Retorna una copia del vector.*/
    clonar(): Vector;
    /**Retorna la suma de dos vectores como un vector nuevo.*/
    sumar(vectorSumar: Vector): Vector;
    /**Retorna la resta de dos vectores como un vector nuevo.*/
    restar(vectorRestar: Vector): Vector;
    /**Retorna un vector nuevo resultante de multiplicar las componentes de un vector por un escalar.*/
    escalar(escalar: number): Vector;
    /**Retorna una copia del vector ingresado con magnitud 1.*/
    normalizar(): Vector;
    /**Retorna un vector resultante de invertir la dirección del vector ingresado.*/
    invertir(): Vector;
    /**Retorna el producto punto, o escalar, entre dos vectores.*/
    punto(vectorProducto: Vector): number;
    /**Retorna el módulo del producto cruz, o vectorial, entre dos vectores de 2 dimensiones.*/
    cruz(vectorProducto: Vector): number;
    /**Retorna el valor de la proyección de un vector sobre un eje representado por otro vector.*/
    proyeccion(vectorEje: Vector): number;
    /**Retorna el valor del ángulo entre dos vectores.*/
    anguloVectores(vectorAngulo: Vector): number;
    /**Retorna un vector nuevo a partir de un vector rotado.*/
    rotar(angulo: number): Vector;
}

declare class Celda {
    posicion: Vector;
    tamano: number;
    color: string;
    estado: number;
    distanciaVecindad: number;
    posicionVecinos: Vector[];
    constructor(posicionX: number, posicionY: number, tamano: number, estado?: number, color?: string);
    get columna(): number;
    get fila(): number;
    /**Retorna un vector con el área de las casillar que comprenden la vecindad de Moore de la celda, según su distancia de vecindad.
     * Ejemplo: el vector (-1, 1) representa a todas las cuadrículas en las posiciones entre (x-1, y-1) y (x+1, y+1) con respecto a la celda.
    */
    get vecindad(): Vector;
    /**Pinta el interior de la celda. Usa como argumento una instancia de la clase Lapiz o Dibujante.*/
    rellenar(lapiz: Lapiz): void;
}

/**MÓDULO DE DIBUJO
 * Instancia una herramienta lapiz.
 * Métodos para definir colores hsla y rgba, dibujar objetos tipo Forma y escribir.
 */
declare class Lapiz {
    colorCelda: string;
    /**Interfaz de dibujo sobre el canvas. 2D*/
    context: CanvasRenderingContext2D;
    /**Opciones del método en que se graficará.
     * 'colorTrazo', 'colorRelleno', 'trazada', 'rellenada', 'grosorTrazo' y 'opacidad'.
    */
    estiloForma: OpcionesGraficasForma;
    /**Opciones de 'color', 'tamano', 'fuente', 'opacidad' y 'alineacion'.*/
    estiloTexto: OpcionesGraficasTexto;
    /**Opciones del método en que se graficará.
    * 'color' y 'grosorTrazo'.
    */
    estiloVector: OpcionesGraficasVector;
    constructor(context: CanvasRenderingContext2D);
    /**
     * Retorna un string con el color en formato HSL.
     * (hue) recibe grados entre 0 y 360,
     * (saturation) y (lightness) reciben porcentajes.
     */
    static colorHSL(hue: number, saturation: number, lightness: number): string;
    /**
     * Retorna un string con el color en formato HSLA.
     * (hue) recibe grados entre 0 y 360,
     * (saturation) y (lightness) reciben porcentajes, y (alpha)
     * valores entre 0 y 1.
     */
    static colorHSLA(hue: number, saturation: number, lightness: number, alpha: number): string;
    /**
     * Retorna un string con el color en formato RGB.
     * (red), (green) y (blue) reciben valores entre 0 y 255.
     */
    static colorRGB(red: number, green: number, blue: number): string;
    /**
     * Retorna un string con el color en formato RGBA.
     * (red), (green) y (blue) reciben valores entre 0 y 255,
     * y (alpha) valores entre 0 y 1.
     */
    static colorRGBA(red: number, green: number, blue: number, alpha: number): string;
    protected recorrerPath(forma: Forma): void;
    /**Traza en el canvas la forma ingresada como argumento.*/
    trazar(forma: Forma): void;
    /**Rellena en el canvas la forma ingresada como argumento.*/
    rellenar(forma: Forma): void;
    /**Rellena y/o traza una forma, según su estilo gráfico.*/
    dibujar(forma: Forma): void;
    /**Rellena en el canvas la celda ingresada como argumento.*/
    rellenarCelda(celda: Celda): void;
    /** Traza en el canvas el vector ingresado como argumento.
     * Usa como color el atributo .estiloVector.color.
     */
    trazarVector(vector: Vector): void;
    /**Rellena un texto en el canvas en la posicion ingresada.
     * Usa como opciones gráficas el atributo .estiloTexto
    */
    escribir(texto: string, posicionX: number, posicionY: number): void;
    /**Método interno.
    * Crea un recorrido para una forma con id "circunferencia", usando el método .arc de la interfaz context.
    */
    protected pathCircunferencia(forma: Forma): void;
    /**Método interno.
    * Crea un recorrido para una forma con id "poligono". Registra líneas entre cada vértice del polígono.
    */
    protected pathPoligono(forma: Forma): void;
    /**Método interno.
    * Crea un recorrido para una forma con id "linea". Registra una línea entre los dos vértices.
    */
    protected pathLinea(forma: Forma): void;
}

declare enum TipoFormas {
    circunferencia = "circunferencia",
    poligono = "poligono",
    linea = "linea",
    vector = "vector"
}

/**
        =============================================
                * MÓDULO DE TRANSFORMACIONES *
        =============================================
        Trabaja sobre conjuntos de vectores.

        Almacena las transformaciones como atributos.

        Siempre retorna copias nuevas de los conjuntos de vectores ingresados.

 */

/**Aplica transformaciones de escala, rotación y desplazamiento sobre arreglos de vectores.
 * Siempre retorna copias nuevas de los arreglos.
 * Almacena en sus atributos los valores de las transformaciones que aplica.
 */
declare class Transformacion {
    escala: number;
    rotacion: number;
    posicion: Vector;
    constructor(x?: number, y?: number, rotacion?: number, escala?: number);
    /**Retorna el arreglo de vectores resultante de aplicar las transformaciones de escala, rotación y desplazamiento
     * sobre un arreglo de vectores de entrada.
     * Permite aumentar puntualmente la rotación en un ángulo específico sin modificar la propiedad de rotación de la transformación.*/
    transformarConjuntoVectores(vectores: Vector[]): Vector[];
    /**Escala cada uno de los vectores del arreglo ingresado y los retorna en un arreglo nuevo.*/
    aplicarEscalaVectores(vectores: Vector[]): Vector[];
    /**Desplaza cada uno de los vectores del arreglo ingresado y los retorna en un arreglo nuevo.*/
    aplicarDesplazamientoVectores(vectores: Vector[]): Vector[];
    /**Rota cada uno de los vectores del arreglo ingresado según el ángulo de rotación almacenado y los retorna en un arreglo nuevo.
    */
    aplicarRotacionVectores(vectores: Vector[]): Vector[];
    /**Rota cada uno de los vectores de un arreglo según el ángulo ingresado y los retorna en un arreglo nuevo.
    */
    static rotarVectores(vectores: Vector[], angulo: number): Vector[];
    /**Retorna una copia de la transformación.*/
    clonarTransformación(): Transformacion;
}

/**MÓDULO FORMA
 * Instancias de formas geométricas.
 * Permite cambiar su posición, rotar, escalar, crear formas básicas y personalizadas, y dibujarlas.
 */
declare class Forma {
    protected _vertices: Vector[];
    protected _verticesTransformados: Vector[];
    protected _transformacion: Transformacion;
    protected verticesTransformadosAnteriores: Vector[];
    protected transformacionAnterior: Transformacion;
    protected transformar: boolean;
    id?: number;
    radio: number;
    lados: number;
    tipo: TipoFormas;
    colorTrazo: string | undefined;
    colorRelleno: string | undefined;
    /**Determina si la forma debe ser trazada al dibujar.*/
    trazada: boolean;
    /**Determina si la forma debe ser rellenada al dibujar.*/
    rellenada: boolean;
    grosorTrazo: number | undefined;
    opacidad: number | undefined;
    protected constructor();
    /**Retorna el valor del radio con la transformación de escala aplicada.*/
    get radioTransformado(): number;
    /**Retorna una copia de la transformación de la forma.*/
    get transformacion(): Transformacion;
    /**Retorna una copia del vector de la posición después de aplicar las transformaciones.*/
    get posicion(): Vector;
    /**Retorna una copia del vector de la posición antes de aplicar las transformaciones.*/
    get posicionAnterior(): Vector;
    /**Retorna el ángulo de rotación actual de la forma.*/
    get rotacion(): number;
    /**Retorna el valor de la escala de la forma.*/
    get escala(): number;
    /**Retorna una copia del arreglo de vértices sin transformaciones.*/
    get vertices(): Vector[];
    /**Retorna una copia del arreglo de vértices después de aplicar las transformaciones de escala, rotación y desplazamiento.*/
    get verticesTransformados(): Vector[];
    /**Retorna el conjunto de vectores normales de cada arista del polígono.
     * El orden de las aristas es en sentido horario.
    */
    get normales(): Vector[];
    /**Retorna la distancia entre el centro del polígono y el punto más cercano de sus aristas.*/
    get apotema(): number;
    /**Reemplaza la transformación de la forma.*/
    set transformacion(transformacion: Transformacion);
    /**Reemplaza el vector posición de la forma.*/
    set posicion(nuevaPosicion: Vector);
    /**Modifica el valor de la rotación de la figura con respecto a su forma sin transformaciones.*/
    set rotacion(rotacion: number);
    /**Reemplaza el valor de la escala de la forma.*/
    set escala(nuevaEscala: number);
    /**Reemplaza el conjunto de vértices base de la forma.*/
    set vertices(vertices: Vector[]);
    /**Permite modificar las opciones gráficas con la interfaz OpcionesGraficasForma*/
    set estiloGrafico(opciones: OpcionesGraficasForma);
    moverVertice(indice: number, punto: Punto): void;
    /**Inicia los vértices de la forma creada.*/
    private crearVertices;
    /**Retorna una forma de tipo polígono. El radio es el valor de la distancia entre el centro y cualquiera de sus vértices.*/
    static poligono(x: number, y: number, lados: number, radio: number, opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**Retorna una forma de tipo circunferencia. */
    static circunferencia(x: number, y: number, radio: number, opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**Retorna una forma de tipo rectángulo. El radio es el valor de la distancia entre el centro y cualquiera de sus vértices.*/
    static rectangulo(x: number, y: number, base: number, altura: number, opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**Crea una recta centrada en la posición ingresada.*/
    static recta(puntoUno: Punto, puntoDos: Punto, opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**
     * Crea un conjunto de rectas a partir de un grupo de vértices.
     * Calcula el centro de los vértices y centra el trazo en la posición ingresada.
     */
    static trazo(vertices: Vector[], opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**
     * Crea un polígono a partir de un grupo de vértices.
     * Calcula el centro de los vértices ingresados y lo asigna a su posición.
     */
    static poligonoSegunVertices(vertices: Vector[], opciones?: OpcionesForma & OpcionesGraficasForma): Forma;
    /**Crea una transformación nueva para formas nuevas, con la posición ingresada.*/
    protected iniciarTransformacion(x: number, y: number): void;
    /**Actualiza el conjunto de vectores transformados.*/
    protected transformarVertices(): void;
    /**Retorna una copia de la forma como una forma nueva.*/
    clonar(): Forma;
    /**Suma el ángulo ingresado al ángulo de rotación de la forma.*/
    rotar(angulo: number): void;
    /**Suma el vector ingresado al vector de posición de la forma.*/
    desplazar(vector: Vector): void;
    /**Rota la forma alrededor del punto (0, 0)*/
    rotarSegunOrigen(angulo: number): void;
    /**Rota la forma alrededor del punto ingresado.*/
    rotarSegunPunto(punto: Punto, angulo: number): void;
    /**Traza el contorno de la forma. Usa una instancia de la clase Lapiz o Dibujante.*/
    trazar(lapiz: Lapiz): void;
    /**Rellena el interior de la forma. Usa una instancia de la clase Lapiz o Dibujante.*/
    rellenar(lapiz: Lapiz): void;
    /**Rellena el interior de la forma. Usa una instancia de la clase Lapiz o Dibujante.*/
    dibujar(lapiz: Lapiz): void;
}

interface Punto {
    x: number;
    y: number;
    id?: number;
    contenido?: Forma;
}
interface OpcionesForma {
    escala?: number;
    rotacion?: number;
}
interface OpcionesCuerpo extends OpcionesForma {
    /**Determina si el cuerpo rotará ajustándose al ángulo del vector velocidad.*/
    rotarSegunVelocidad?: boolean;
    /**Determina si el cuerpo permanecerá o no estático al colisionar con otro cuerpo.*/
    fijo?: boolean;
    /**El valor de la masa del cuerpo.*/
    masa?: number;
    /**El valor de la densidad del cuerpo.*/
    densidad?: number;
    /**Si el cuerpo se verá afectado por eventos de teclado o mouse.*/
    controlable?: boolean;
}
interface OpcionesGraficasForma {
    /**Color de trazado de la forma.*/
    colorTrazo?: string;
    /**Color de relleno de la forma.*/
    colorRelleno?: string;
    /**Determina si la forma debe ser trazada.*/
    trazada?: boolean;
    /**Determina si la forma debe ser rellenada.*/
    rellenada?: boolean;
    /**Determina el ancho de la línea trazada.*/
    grosorTrazo?: number;
    /**Determina la opacidad con que es graficada la forma. */
    opacidad?: number;
}
interface OpcionesGraficasVector {
    /**Color del trazo del vecto.*/
    color: string;
    /**Ancho del trazo del vector en pixeles. */
    grosorTrazo: number;
}
interface OpcionesGraficasTexto {
    tamano?: number;
    /**Opciones: 'center', 'end', 'left', 'right', 'start' */
    alineacion?: CanvasTextAlign;
    fuente?: string;
    /**Valor de opacidad, entre 0 y 1.*/
    opacidad?: number;
    color?: string;
}
interface OpcionesControlesCuerpo {
    arriba: boolean;
    abajo: boolean;
    izquierda: boolean;
    derecha: boolean;
    rotarIzquierda: boolean;
    rotarDerecha: boolean;
    rapidez: number;
    anguloRotacion: number;
}

/**MÓDULO DE GEOMETRÍA EN ESPAÑOL
 * Útilitario para mui.js
 * Incluye métodos de conversión de grados y distancia entre puntos.
 */
declare class Geometria {
    /**Retorna el doble del valor de PI.*/
    static get DOS_PI(): number;
    /**Retorna la mitad del valor de PI.*/
    static get PI_MEDIO(): number;
    /**Transforma grados sexagesimales a radianes.*/
    static gradoARadian(grado: number): number;
    /**Transfoma radianes a grados sexagesimales.*/
    static radianAGrado(rad: number): number;
    /**Retorna la longitud de la hipotenusa según la longitud de los dos catetos ingresados.*/
    static hipotenusa(cateto1: number, cateto2: number): number;
    /**Retorna la longitud de un cateto según la longitud de la hipotenusa y del otro cateto.*/
    static cateto(hipotenusa: number, cateto: number): number;
    /**Retorna el valor de la distancia entre dos puntos de un plano cartesiano.*/
    static distanciaEntrePuntos(puntoUno: Punto, puntoDos: Punto): number;
    /**Retorna el punto medio entre dos puntos de un plano cartesiano.*/
    static puntoMedio(puntoUno: Punto, puntoDos: Punto): Punto;
    /**Compara las coordenadas de dos puntos.
     * Retorna true si son iguales y false si no lo son.
    */
    static compararPuntos(puntoUno: Punto, puntoDos: Punto): boolean;
}

/**Clase que permite capturar lo que se proyecte en un canvas. */
declare class Grabador {
    constructor();
    /**Graba la animación de un canvas en formato .avi y asocia la grabación a un link de descarga en el documento HTML.
     * Permite definir la duración de la grabación, en milisegundos, el número de FPS y la id del <anchor> HTML que iniciará la descarga.
     * Si no se define un elemento <anchor>, el método creará uno.
     */
    static grabarCanvas(canvas: HTMLCanvasElement, milisegundos: number, fps: number, anchor?: string): void;
}

/**
 * MÓDULO MATEMÁTICO EN ESPAÑOL
 * Reducido. Contiene solo funciones útiles de números aleatorios.
 */
declare class Matematica {
    /**Retorna un número aleatorio entre dos números.*/
    static aleatorio(min: number, max: number): number;
    /**Retorna un número aleatorio entero entre dos números, ambos incluídos.*/
    static aleatorioEntero(min: number, max: number): number;
    static compararNumeros(numeroUno: number, numeroDos: number, epsilon?: number): boolean;
}

/**
        =============================================
                 * MÓDULO DE COLISIONES *
        =============================================
        Trabaja usando objetos de tipo Forma.

        Usa el Teorema de ejes de separación (SAT) para detectar colisiones.

 */

/**MÓDULO DE COLISIONES
 * Trabaja usando objetos de tipo Forma.
 * Usa el Teorema de ejes de separación (SAT) para detectar colisiones.
*/
declare class Colision {
    static get iteraciones(): number;
    /**Detecta colisiones usando el teorema SAT entre formas de tipo circunferencia y/o polígono.
     * Retorna true si detecta una colisión.
     * Retorna false si no detecta colisión.
    */
    static detectar(formaUno: Forma, formaDos: Forma): boolean;
    /**Detecta la intersección entre dos circunferencias.
     * Retorna true si hay intersección.
     * Retorna false si no hay intersección.
     * Compara la distancia entre ambos centros con la suma de sus radios.
     */
    static circunferencias(circunferenciaUno: Forma, circunferenciaDos: Forma): boolean;
    /**Detecta la colisión entre dos polígonos.
     * Retorna true si hay colisión.
     * Retorna false si no hay colisión.
     * Usa el teorema SAT. Proyecta los vértices sobre las normales de las caras de ambos polígonos y busca ejes de separación.
     */
    static poligonos(poligonoUno: Forma, poligonoDos: Forma): boolean;
    /**Detecta la colisión entre una circunferencia y un polígono.
     * Retorna true si hay colisión.
     * Retorna false si no hay colisión.
     * Usa el teorema SAT. Proyecta los vértices del polígono y dos puntos de la circunferencia sobre las normales de las caras del polígono y busca ejes de separación.
     */
    static circunferenciaPoligono(circunferencia: Forma, poligono: Forma): boolean;
    /**Retorna el valor menor entre las proyecciones de un conjunto de vértices sobre un eje representado por un vector normal.*/
    private static proyeccionMenor;
    /**Retorna el valor mayor entre las proyecciones de un conjunto de vértices sobre un eje representado por un vector normal.*/
    private static proyeccionMayor;
    /**Retorna un arreglo de dos vectores correspondiente a las normales de las caras de contacto entre dos formas.
     * El primero vector del arreglo corresponde a la normal de la primera forma.
     * El segundo vector del arreglo corresponde a la normal de la segunda forma.
    */
    static normalesContacto(formaUno: Forma, formaDos: Forma): Vector[];
    /**Detecta la colisión entre una circunferencia y su entorno que la contiene.
     * Retorna el valor de solapamiento.
     * Retorna null si no hay colisión.
     * Usa el teorema SAT. Proyecta los vértices del entorno y dos puntos de la circunferencia sobre las normales de las caras del polígono
     * y verifica si hay proyecciones de la circunferencia mayores a la de los vértices del entorno.
     */
    static circunferenciaEntorno(circunferencia: Forma, entorno: Forma): number | null;
    /**Retorna la normal del borde del entorno contra el que ha colisionado una forma.*/
    static normalContactoConEntorno(forma: Forma, entorno: Forma): Vector;
}

/**
        =============================================
                 * MÓDULO DE CUERPOS *
        =============================================
        Trabaja usando objetos de tipo Forma.

        Crea cuerpos geométricos con masa y densidad.

        Contiene métodos para mover según velocidad y aceleración.

 */

/**MÓDULO DE CUERPOS
 * Trabaja usando objetos de tipo Forma.
 */
declare class Cuerpo extends Forma {
    protected _velocidad: Vector;
    protected _aceleracion: Vector;
    /**Determina si el cuerpo rotará o no según la dirección y sentido de su velocidad.*/
    rotarSegunVelocidad: boolean;
    /**Propiedad útil para determinar si un cuerpo será controlado por el usuario.*/
    controlable: boolean;
    /**Determina si un cuerpo se moverá o no producto de la interacción con otros cuerpos.*/
    fijo: boolean;
    masa: number;
    densidad: number;
    /**Propiedades para activar y desactivar acciones relacionadas con el control del movimiento de cuerpos por parte del usuario.*/
    controles: OpcionesControlesCuerpo;
    private constructor();
    /**Retorna una copia del vector velocidad.*/
    get velocidad(): Vector;
    /**Retorna una copia del vector aceleración.*/
    get aceleracion(): Vector;
    get verticesTransformados(): Vector[];
    /**Modifica el vector velocidad.*/
    set velocidad(velocidad: Vector);
    /**Modifica el vector aceleración.*/
    set aceleracion(aceleracion: Vector);
    /**Retorna un cuerpo geométrico regular.
     * El radio corresponde a la distancia entre el centro y cualquiera de sus vértices.*/
    static poligono(x: number, y: number, lados: number, radio: number, opciones?: OpcionesCuerpo): Cuerpo;
    /**Retorna un cuerpo geométrico regular.
     * El radio corresponde a la distancia entre el centro y cualquiera de sus vértices.*/
    static poligonoSegunVertices(vertices: Vector[], opciones?: OpcionesCuerpo): Cuerpo;
    /**Retorna un cuerpo rectangular.*/
    static rectangulo(x: number, y: number, base: number, altura: number, opciones?: OpcionesCuerpo): Cuerpo;
    /**Retorna un cuerpo con forma de circunferencia.*/
    static circunferencia(x: number, y: number, radio: number, opciones?: OpcionesCuerpo): Cuerpo;
    /**Método auxiliar. Crea un cuerpo base a partir de una forma.*/
    private static cuerpoSegunForma;
    /**Retorna una copia del cuerpo como un cuerpo nuevo.*/
    clonar(): Cuerpo;
    /**Suma la aceleración a la velocidad y la velocidad a la posición.*/
    mover(): void;
    /**Traza el vector velocidad del cuerpo a partir de su centro.*/
    trazarVelocidad(lapiz: Lapiz): void;
    /**Aplica las transformaciones definidas para cada evento (de teclado, mouse u otro) sobre el cuerpo.*/
    usarControles(): void;
}

declare class Contenedor {
    cuerpo: Cuerpo;
    cuerposContenidos: Cuerpo[];
    constructor(cuerpo: Cuerpo);
    /**Retorna el conjunto de vectores normales de cada arista del contenedor. */
    get normales(): Vector[];
    /**Retorna un objeto Contenedor a partir de un cuerpo.*/
    static crearContenedor(cuerpo: Cuerpo): Contenedor;
    /**Agrega cuerpos al conjunto de cuerpos que estarán dentro del contenedor.*/
    agregarCuerposContenidos(...cuerpos: Cuerpo[]): void;
    rebotarCircunferenciasConBorde(): void;
    /**Suma la aceleración a la velocidad y la velocidad a la posición.*/
    mover(): void;
}

declare class Entorno extends Contenedor {
    private canvas;
    private alto;
    private ancho;
    constructor(canvas: HTMLCanvasElement, cuerpo: Cuerpo);
    get normales(): Vector[];
    /**Crea un entorno con un cuerpo del tamaño del canvas.
     * Un entorno funciona como un cuerpo contenedor.
     */
    static crearEntornoCanvas(canvas: HTMLCanvasElement): Entorno;
    /**Mueve un vector que ha excedido las coordenadas de alguno de los bordes al borde opuesto.
     * Convierte al entorno en un entorno infinito.
    */
    envolverBorde(vector: Vector): Vector;
    colisionConBorde(...cuerpos: Cuerpo[]): Cuerpo[];
}

declare class Interaccion {
    static get iteraciones(): number;
    /**Retorna una copia del conjunto de cuerpos con la resolución de rebote para cuerpos que han colisionado.      */
    static reboteEntreCuerpos(cuerpos: Cuerpo[]): Cuerpo[];
    /**Retorna una copia del conjunto de cuerpos con la resolución de contacto sólido para cuerpos que han colisionado.      */
    static contactoSimple(cuerpos: Cuerpo[]): Cuerpo[];
    private static resolverSolapamiento;
    /**Retorna una copia del conjunto de circunferencias con la resolución de rebote para cuerpos que han colisionado con los bordes de un entorno.      */
    static reboteCircunferenciasConEntorno(circunferencias: Cuerpo[], entorno: Cuerpo): Cuerpo[];
    private static resolverSolapamientoEntorno;
}

declare class Restriccion {
    /**Limita la magnitud de la velocidad de un cuerpo.
     * Retorna una copia del vector velocidad si se ha modificado su magnitud.
    */
    static limitarVelocidad(cuerpo: Cuerpo, limite: number): Vector;
    /**Retorna un vector de aceleracion escalado de tal manera que al sumarlo a la velocidad del cuerpo, la magnitud
     * de la velocidad no supere el límite ingresado.*/
    static limitarAceleracionSegunVelocidad(cuerpo: Cuerpo, limiteVelocidad: number): Vector;
}

/**
 * Inicio Quadtree
 */

declare class QuadTree {
    x: number;
    y: number;
    ancho: number;
    alto: number;
    capacidad: number;
    capacidadEspecifica: number;
    puntos: Punto[];
    private idPunto;
    private subDividido;
    private subDivisiones;
    private niveles;
    longitudMinima: number;
    private longitudMenor;
    contorno: Forma;
    constructor(x: number, y: number, ancho: number, alto: number, capacidad?: number, niveles?: number);
    /**Agrega un punto a un QuadTree. Si al agregar el punto se sobrepasa la capacidad del QuadTree, se subdivide en cuatro QuadTrees nuevos. */
    insertarPunto(punto: Punto, contenido?: Forma): boolean;
    private crearSubdivisiones;
    private insertarEnSubdivisiones;
    private validarInsercion;
    trazar(lapiz: Lapiz, opciones?: OpcionesGraficasForma): void;
    private formaCuadrante;
    private verificarPuntoRepetido;
    puntosEnRango(limiteIzquierda: number, limiteDerecha: number, limiteSuperior: number, limiteInferior: number, arregloPuntos?: Punto[]): Punto[];
    contactoSimpleCuerpos(): void;
    reboteEslasticoCuerpos(): void;
}

declare class Cinematica {
    /**Retorna un vector velocidad de un cuerpo que colisiona con una superficie.*/
    static reboteSimple(cuerpo: Cuerpo, normal: Vector): Vector;
    /**Retorna en un arreglo las velocidades finales después de un choque elástico entre dos cuerpos.*/
    static reboteElastico(cuerpoUno: Cuerpo, cuerpoDos: Cuerpo): Vector[];
    private static velocidadUnoFinal;
    private static velocidadDosFinal;
}

declare class Fuerza {
    /**Retorna un vector correspondiente a la aceleración de un cuerpo atraído hacia un cuerpo atractor.
     * TODAVÍA NO HE INCORPORADO LA MASA NI LA DISTANCIA.
    */
    static atraer(cuerpo: Cuerpo, atractor: Cuerpo, magnitudAtraccion: number): Vector;
    /**Retorna un vector correspondiente a la aceleración de un cuerpo atraído hacia un vector atractor.
     * TODAVÍA NO HE INCORPORADO LA MASA NI LA DISTANCIA.
    */
    static atraerAVector(cuerpo: Cuerpo, atractor: Vector, magnitudAtraccion: number): Vector;
    /**Retorna un vector correspondiente a la aceleración de un cuerpo repelido por un cuerpo repulsor.
    * TODAVÍA NO HE INCORPORADO LA MASA NI LA DISTANCIA.
    */
    static repeler(cuerpo: Cuerpo, repulsor: Cuerpo, magnitudRepulsion: number): Vector;
    /**Retorna un vector correspondiente a la aceleración de un cuerpo repelido por un vector repulsor.
    * TODAVÍA NO HE INCORPORADO LA MASA NI LA DISTANCIA.
   */
    static repelerDeVector(cuerpo: Cuerpo, repulsor: Vector, magnitudRepulsion: number): Vector;
}

/**MÓDULO DE DIBUJANTE
 * Extiende las funciones de Lapiz.
 * Permite trabajar con conjuntos de formas y sobre el canvas.
 * Se instancia usando el canvas.
 */

declare class Dibujante extends Lapiz {
    canvas: HTMLCanvasElement;
    private _anchoCanvas;
    private _altoCanvas;
    private _colorFondo?;
    private constructor();
    /**Retorna la medida horizontal del canvas.*/
    get anchoCanvas(): number;
    /**Retorna la media vertical del canvas. */
    get altoCanvas(): number;
    /**Retorna un punto ubicado en el centro del canvas.*/
    get centroCanvas(): Punto;
    /**Retorna el color del canvas.*/
    get colorCanvas(): string | undefined;
    /**Modifica la medida horizontal del canvas.*/
    set anchoCanvas(ancho: number);
    /**Modifica la medida vertical del canvas. */
    set altoCanvas(alto: number);
    /**Modifica el color del canvas.*/
    set colorCanvas(color: string);
    /**Retorna una instancia de Dibujante usando como parámetro el id de un canvas presente en el documento HTML. */
    static crearConIdCanvas(idCanvas: string): Dibujante;
    /**Retorna una instancia de Dibujante usando como parámetro el canvas presente en el documento HTML. */
    static crearConCanvas(canvas: HTMLCanvasElement): Dibujante;
    /**Traza un conjunto de formas.*/
    trazarFormas(formas: Forma[]): void;
    /**Rellena un conjunto de formas.*/
    rellenarFormas(formas: Forma[]): void;
    /**Rellena y/o traza, según el caso, un conjunto de formas.*/
    dibujarFormas(formas: Forma[]): void;
    /**Borra el contenido del canvas.
     * Si se especifica opacidad, pinta el canvas completo usando como color el atributo colorCanvas y con la opacidad especificada.
     * Si no hay colorCanvas especificado, se pintará de blanco.
     */
    limpiarCanvas(opacidad?: number): void;
    /**Traza las normales de una forma geométrica.*/
    trazarNormales(forma: Forma): void;
}

declare class Cuadricula {
    filas: number;
    columnas: number;
    /**La dimensión del lado de una celda cuadrada.*/
    tamanoCelda: number;
    private _bordesInfinitos;
    celdas: Celda[][];
    /**El número de estados posibles que puede adoptar cada celda.*/
    estados: number;
    private _colorCeldas;
    constructor(columnas: number, filas: number, tamanoCelda: number, estados: number);
    /**Retorna el ancho de la cuadrícula (la multiplicación del número de columnas por el tamaño de cada celda).*/
    get anchoCuadricula(): number;
    /**Retorna el alto de la cuadrícula (la multiplicación del número de filas por el tamaño de cada celda).*/
    get altoCuadricula(): number;
    set bordesInfinitos(borderInfinitos: boolean);
    /**Ajusta el color con que se pintarán las celdas.*/
    set colorCeldas(color: string);
    private crearCeldas;
    /**Retorna un arreglo con las posiciones de los vecinos de la celda ingresada.
     * Permite definir si las celdas de los bordes incluirán o a las celdas de los bordes opuestos de la cuadrícula entre sus vecinos.
     */
    private determinarVecinosPorCelda;
    /**Retorna un arreglo de tuplas con el número de vecinos de la celda que están en cada estado posible.
     * [[estado, número de vecinos en ese estado], [estado, número de vecinos en ese estado]...]
     */
    estadosVecinosPorCelda(celda: Celda): [number, number][];
    /**Pinta todas las celdas de la cuadrícula. Asigna la opacidad de acuerdo al estado de cada celda.*/
    rellenarCeldas(lapiz: Lapiz): void;
    /**Retorna la celda ubicada en la posicion (columna, fila) respecto a la cuadrícula.*/
    celdaSegunCoordenada(columna: number, fila: number): Celda;
    /**Retorna la celda ubicada en la posición del mouse sobre el canvas.*/
    celdaEnPosicionMouse(mouseX: number, mouseY: number): Celda;
    /**Asigna un estado aleatorio a cada celda de la cuadrícula.*/
    estadosAleatorios(): void;
    /**Asigna un estado aleatorio a cada celda de la cuadrícula.*/
    estadosCero(): void;
    /**Asigna el estado máximo a cada celda de la cuadrícula.*/
    estadosMaximos(): void;
}

/**Contador de tiempo, en milisegundos.
 * Su propiedad 'activo' se vuelve false cuando ha transcurrido el tiempo ingresado.
*/
declare class Temporizador {
    private tiempoInicial;
    duracion: number;
    activo: boolean;
    constructor(duracionMilisegundos: number);
    /**Retorna el tiempo, en milisegundos, transcurrido desde la creación del temporizador.*/
    get tiempoTranscurrido(): number;
}

declare class Tiempo {
    private _tiempoInicial;
    private tiempoActual?;
    private tiempoPrevio?;
    private temporizadores;
    constructor();
    /**Retorna el número de temporizadores activos.*/
    get numeroTemporizadores(): number;
    /**Retorna el momento en milisegundos de la instanciación de este objeto.*/
    get tiempoInicial(): number;
    /**Retorna el tiempo en milisegundos transcurrido desde la última vez que se consultó .delta.
     * Si no se lo ha consultado antes, retorna el tiempo transcurrido desde la instanciación del objeto Tiempo.
    */
    get delta(): number;
    /**Ejecuta una función un número determinado de veces por segundo.*/
    iterarPorSegundo(funcion: () => void, numeroIteraciones: number): void;
    /**Crea un termporizador nuevo con la duración ingresada y lo agrega a la lista de temporizadores de la composición.*/
    crearTemporizador(tiempoMilisegundos: number): Temporizador;
    /**Elimina del registro de temporizadores aquellos que estén inactivos.*/
    actualizarTemporizadores(): void;
}

declare class Composicion {
    /**Herramienta Dibujante.*/
    dibujante: Dibujante;
    /**Conjunto de cuerpos sobre los que trabaja la composición.*/
    cuerpos: Cuerpo[];
    /**Conjunto de formas sobre las que trabaja la composición.*/
    formas: Forma[];
    cuadricula: Cuadricula;
    tiempo: Tiempo;
    contenedores: Contenedor[];
    private _entorno;
    fps: number;
    usarfpsNativos: boolean;
    tick: number;
    /**Si es "true" la animación se ejecuta, si es "false" se pausa.*/
    animar: boolean;
    /**El id del proceso que está ejecutando la animación.*/
    private _idFuncionAnimationFrame?;
    nivelesQuadTree: number;
    trazarQuadTree: boolean;
    private constructor();
    /**Retorna el canvas sobre el que se creó la Composición.*/
    get canvas(): HTMLCanvasElement;
    /**Retorna la medida horizontal del canvas.*/
    get anchoCanvas(): number;
    /**Retorna la media vertical del canvas. */
    get altoCanvas(): number;
    /**Retorna un punto ubicado en el centro del canvas.*/
    get centroCanvas(): Punto;
    /**Retorna el color del canvas.*/
    get colorCanvas(): string | undefined;
    /**Modifica la medida horizontal del canvas.*/
    set anchoCanvas(ancho: number);
    /**Modifica la medida vertical del canvas. */
    set altoCanvas(alto: number);
    /**Modifica el color del canvas.*/
    set colorCanvas(color: string);
    set entorno(entorno: Entorno);
    get entorno(): Entorno;
    /**Retorna un objeto de tipo Composicion a partir del id de un canvas.*/
    static crearConIdDelCanvas(idCanvas: string): Composicion;
    /**Retorna un objeto de tipo Composicion a partir de un canvas.*/
    static crearConCanvas(canvas: HTMLCanvasElement): Composicion;
    /**Define el ancho y el alto del canvas, en pixeles. */
    tamanoCanvas(ancho: number, alto: number): void;
    /**Agrega cuerpos al conjunto de cuerpos manipulados por la composición. */
    agregarCuerpos(...cuerpos: Cuerpo[]): void;
    /**Actualiza la posición del conjunto de cuerpos sumando la velocidad instantánea a la posición.*/
    moverCuerpos(): void;
    /**Calcula la colisión entre los cuerpos de la composición y resuelve sus choques como choques elásticos.*/
    reboteElasticoCuerpos(): void;
    /**Calcula la colisión entre los cuerpos de la composición y evita que los cuerpos se solapen.*/
    contactoSimpleCuerpos(): void;
    /**Método gráfico. Pinta el interior de los cuerpos de la composición en el canvas.*/
    rellenarCuerpos(): void;
    /**Método gráfico. Traza los cuerpos de la composición en el canvas.*/
    trazarCuerpos(): void;
    /**Método gráfico. Pinta y/o rellena los cuerpos de la composición, según lo definido para cada cuerpo.*/
    dibujarCuerpos(): void;
    /**Método gráfico. Pinta y/o rellena las formas de la composición, según lo definido para cada forma.*/
    dibujarFormas(): void;
    /**Crea un loop para ejecutar dos funciones, una asociada a la duración de cada tick y otra a los fps.
     * El atributo .tick permite cambiar su duración en milisegundos.
     * La propiedad .fps permite ajustar su número.
     */
    animacion(funcionCalcular: () => void, funciondibujar: () => void): void;
    bordesEntornoInfinitos(entorno: Entorno): void;
    limitarVelocidad(magnitudVelMaxima: number): void;
    /**Detiene definitivamente la animación en en curso.*/
    cancelarAnimacion(): void;
}

declare class ManejadorEventos {
    /**Agrega un eventListener para eventos de teclado. Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static eventoTeclado<Type>(tipoEvento: EventoTeclado, tecla: CodigoTecla, manejarEvento: (param: Type) => void, parametro?: Type): void;
    /**Agrega un eventListener para eventos de teclado tipo keyup. Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static eventoKeyup<Type>(tecla: CodigoTecla, manejarEvento: (param: Type) => void, parametro?: Type): void;
    /**Agrega un eventListener para eventos de teclado tipo keydown. Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static eventoKeydown<Type>(tecla: CodigoTecla, manejarEvento: (param: Type) => void, parametro?: Type): void;
    /**Agrega un eventListener para eventos de teclado tipo keypress. Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static eventoKeypress<Type>(tecla: CodigoTecla, manejarEvento: (param: Type) => void, parametro?: Type): void;
    /**Agrega un eventListener para eventos de mouse y para trabajar con las propiedades del evento.
     * Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static eventoMouseEnCanvas<K>(tipoEvento: EventoMouse, canvas: HTMLCanvasElement, manejarEvento: (eventoMouse: MouseEvent, param: K) => void, parametro?: K): void;
    /**Agrega un eventListener para detectar cambios en el mouse, mas no trabaja con el evento.
     * Recibe una función callback y opcionalmente un parámetro si la función lo requiere.*/
    static mouseEnCanvas<K>(tipoEvento: EventoMouse, canvas: HTMLCanvasElement, manejarEvento: (param: K) => void, parametro?: K): void;
    /**Previene que se activen acciones por defecto al presionar la tecla definida. */
    static anularAccionPorDefecto(tecla: CodigoTecla): void;
}
/**Constante que almacena los códigos de eventos de teclado.*/
declare const CODIGOSTECLA: {
    readonly espacio: " ";
    readonly enter: "Enter";
    readonly arriba: "ArrowUp";
    readonly abajo: "ArrowDown";
    readonly izquierda: "ArrowLeft";
    readonly derecha: "ArrowRight";
    readonly a: "a";
    readonly b: "b";
    readonly c: "c";
    readonly d: "d";
    readonly e: "e";
    readonly f: "f";
    readonly g: "g";
    readonly h: "h";
    readonly i: "i";
    readonly j: "j";
    readonly k: "k";
    readonly l: "l";
    readonly m: "m";
    readonly n: "n";
    readonly ñ: "ñ";
    readonly o: "o";
    readonly p: "p";
    readonly q: "q";
    readonly r: "r";
    readonly s: "s";
    readonly t: "t";
    readonly u: "u";
    readonly v: "v";
    readonly w: "w";
    readonly x: "x";
    readonly y: "y";
    readonly z: "z";
    readonly mas: "+";
    readonly menos: "-";
};
/**Tipo para los códigos de eventos de teclado.*/
type CodigoTecla = keyof typeof CODIGOSTECLA;
/**Tipo para los tipos de evento de teclado.*/
type EventoTeclado = keyof Pick<WindowEventMap, 'keydown' | 'keypress' | 'keyup'>;
/**Tipo para los tipos de evento de mouse.*/
type EventoMouse = keyof Pick<WindowEventMap, 'mousedown' | 'mouseenter' | 'mousemove' | 'mouseleave' | 'mouseup' | 'mouseout' | 'mouseover' | 'click'>;

export { Celda, Cinematica, Colision, Composicion, Contenedor, Cuadricula, Cuerpo, Dibujante, Entorno, Forma, Fuerza, Geometria, Grabador, Interaccion, Lapiz, ManejadorEventos, Matematica, type OpcionesControlesCuerpo, type OpcionesCuerpo, type OpcionesForma, type OpcionesGraficasForma, type OpcionesGraficasTexto, type OpcionesGraficasVector, type Punto, QuadTree, Restriccion, Temporizador, Tiempo, TipoFormas, Vector };
