Ir al contenido principal

Quiéres estos diseños en tu ropa o en diferentes productos?

Publicidad

Cálculo, Algoritmo y graficación de las curvas de Bézier con Love2D


 

Se denomina curvas de Bézier a un tipo de línea curva modelada por medio de un método de descripción matemático utilizando una ecuación paramétrica que permite generar curvas y superficies suavizadas que pueden ser escaladas indefinidamente.

La curva es definida a través de una serie de puntos, donde el primer y último punto son los extremos de la curva.

Cálculo de las curvas de Bézier 


Curvas cuadráticas de Bézier

La ecuación para esta curva es la siguiente:

B(t) = (1-t)² P1 + 2t(1-t) P2 + t² P3, donde t toma valores desde 0 a 1

Para realizar el cálculo de algún punto de la curva, primero debemos definir los valores de P1, P2 y P3.

Digamos que estos valore son los siguientes:

P1 = (0,0), P2 = (100,100), P3 = (200,0), siendo los valores dentro del paréntesis las coordenadas (x,y) del plano.

Entonces vamos a calcular el punto de la curva Bézier cuando t = 1/2 o 0.5, tomamos solo los valores de la coordenada "X" de los puntos.

Bx(0.5) = (1 - 0.5)² * 0 + 2 * 0.5 * (1 - 0.5) * 100 + (0.5)² * 200, quedando entonces

Bx(0.5) = 0 + 50 +50

Bx(0,5) = 100

Ahora la coordenada "Y"

By(0.5) = (1 - 0.5)² * 0 + 2 * 0.5 * (1 - 0.5) * 100 + (0.5)² * 0

By(0.5) = 0 + 50 + 0

By(0.5) = 50

Quedando entonces uno de los puntos de la curva cuando t = 0.5 de esta manera

B(0.5) = (100,50)

Ahora si realizamos esta operación repetidamente partiendo desde t = 0 y con intervalos de 1/50, es decir sumamos 0.02 cada vez al valor anterior hasta llegar a 1 de la manera 0, 0.02, 0.04,… etc. obtenemos la siguiente curva.

El punto B(0.5) quedaría en el centro entre los dos puntos P1 y P3 con una altura que intenta alcanzar a P2.

curva cuadrática de bézier

La curva nunca pasa por el punto P2, pues este solo sirve de guía para la construcción de la misma. Se pueden tomar cuantos puntos se quieran dentro de los valores 0 y 1 y de esta manera se tendrán curvas más suavizadas. Para la curva de la imagen anterior se utilizaron 50 valores.

 

Curvas cúbicas de Bézier

Esta curva se diferencia de la anterior en que posee un punto más de control, los extremos serán P1 y P4 y los puntos de control P2 y P3, quedando el proceso de cálculo igual y obviamente la ecuación cambia para acomodar este punto extra.

B(t) = (1 - t)³P1 + 3t(1 - t)²P2 + 3t²(1 - t)P3 + t³P4, donde "t" toma valores desde 0 a 1

Ahora veamos como sería una curva cúbica de Bézier si los puntos son los siguientes:

P1 = (0,0), P2 = (0,100), P3 = (200,0), P4 = (100,100)

Nuevamente usando 50 valores entre 0 y 1 con distancia de 1/50 tenemos la siguiente curva.

curva cúbica de bézier
La curva va desde P1 a P4 y en su camino se podría decir que es desviada hacia los puntos de control P2 y P3.

Algoritmo de las curvas de Bézier en Lua

Calcular constantemente una curva Bézier con muchos puntos sería muy lento, por eso el algoritmo debe realizarlo una vez y luego utilizar los puntos calculados para dibujar la curva.

 

Algoritmo de la curva Bézier cuadrática

El algoritmo toma el numero de puntos y calcula "dt" que es utilizado para calcular el valor siguiente de "t" en cada ciclo, la tabla "curva" almacenará el conjunto de valores de los puntos calculados de manera que quede de la siguiente manera: {p1x,p1y,p2x,p2y,p3x,p3y,...}, la variable "j" solo nos facilita ingresar los valores en la tabla como se especifica.

-- pc una tabla que contiene los puntos de control de la forma {x=0,y=0}
-- nPuntos, cantidad de puntos que se calcularan entre 0 y 1

function BezierCuadratica(pc, nPuntos)

    local dt = 1/nPuntos
    local curva = {}
    local j = 1
    for i = 0, nPuntos - 1, 1 do
        local t = i*dt
        local puntox = (1 - t) * ( (1 - t) * pc[1].x + t * pc[2].x ) + t * ( (1 - t) * pc[2].x + t * pc[3].x)
        local puntoy = (1 - t) * ( (1 - t) * pc[1].y + t * pc[2].y ) + t * ( (1 - t) * pc[2].y + t * pc[3].y)
        curva[j] = puntox
        curva[j+1] = puntoy
        j = j + 1
    end

    return curva

end

 

Algoritmo de la curva Bézier cúbica en Lua

Aquí vamos a utilizar una función extra llamada PuntoBezierCubica para facilitar el cálculo, y que nos devolverá una tabla de la forma {x=0,y=0} con el valor de x,y del punto de la curva al pasarle el valor de t correspondiente. La función principal queda igual a la BezierCuadratica con solo ese pequeño cambio como observaras a continuación.

function PuntoBezierCubica(pc, t )
    local ax, bx, cx
    local ay, by, cy
    local tCuadrado, tCubo
    local punto = {x = 0, y = 0}

    --cálculo de los coeficientes polinomiales

    cx = 3.0 * (pc[2].x - pc[1].x)
    bx = 3.0 * (pc[3].x - pc[2].x) - cx
    ax = pc[4].x - pc[1].x - cx - bx

    cy = 3.0 * (pc[2].y - pc[1].y)
    by = 3.0 * (pc[3].y - pc[2].y) - cy
    ay = pc[4].y - pc[1].y - cy - by

    --cálculo del punto de la curva en t

    tCuadrado = t * t
    tCubo = tCuadrado * t

    punto.x = (ax * tCubo) + (bx * tCuadrado) + (cx * t) + pc[1].x
    punto.y = (ay * tCubo) + (by * tCuadrado) + (cy * t) + pc[1].y
    return punto
end


function BezierCubica(pc, nPuntos)
    local dt = 1/nPuntos
    local curva = {}
    local j = 1
    for i = 0, nPuntos - 1, 1 do
        local t = i*dt
        local punto = PuntoBezierCubica(pc,t)
        curva[j] = punto.x
        curva[j+1] = punto.y
        j = j + 1
    end
    return curva
end

Si queremos dibujar nuestra curva usando Love2D podemos hacerlo fácilmente pasando la tabla que obtenemos de alguna de las funciones a la función de dibujado de líneas de Love2D.

function love.load()

    puntosControl = {{x=0,y=0},{x=100,y=100},{x=200,y=0}}

    bz = BezierCuadratica(puntosControl,50)

 end

function love.draw()

    love.graphics.line(bz)

end

Les dejo un video corto donde pueden ver los diferentes tipos de curva Bézier mientras se modifican los puntos de control y que fue creado con Love2D.



Comentarios