¿Cómo debo llenar una forma que consta de curvas Bezier y líneas rectas?

8

He estado trabajando en una biblioteca de gráficos durante algún tiempo y he llegado al punto en que tengo que dibujar Bezier y fuentes basadas en líneas. Hasta este punto, estoy atrapado con esto:

yo

una

Las líneas verdes son los caminos de Bezier, y la parte blanca es lo que se representa.

El código que uso para Beziers está aquí . El de las líneas está aquí . Para aquellos que no saben que es Lua.

Representación de ruta (líneas): 32 - 39 El algoritmo es el siguiente:

  1. Iterando de 0 a 1 a ciertos intervalos
  2. calculando x e y con esta fórmula: (1-index)^2*x1+2*(1-index)*index*x2+index^2*x3

Hasta este punto, todo funciona bien. Las líneas verdes se generan utilizando el método de ruta.

La parte blanca se representa de una manera completamente diferente:

  1. Obtengo las coordenadas x de los Béziers y las líneas en una Y particular, y las pongo en una tabla.
  2. Repito en la tabla y cada vez que encuentro un punto cambio el valor del estado. En el mismo bucle for también se verifica si el estado está activado. Si es así, dibujo un píxel en la pantalla.

Para encontrar los valores x de ay, utilizo el método getX (línea 46 en Bezier y línea 31 en Línea).

El código que uso para el dibujo en sí es este:

local xBuffer = {}
local state = false

for i=0,500 do
    for k,v in pairs(beziers) do
        a,b = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
            if b then
                xBuffer[round(a)] = 1
            end
        end
    end
    for k,v in pairs(lines) do
        a = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
        end
    end
    state = false
    for x=0,600 do
        if xBuffer[x] then
            state = not state
        end
        if state then
            love.graphics.points(x,i)
        end
    end
end

Explicación rápida: para i, v en pares itera a través de la tabla dada como argumento para los pares. love.graphics.points (x, y) establece un punto en x, y.

Gracias por adelantado.

Creador
fuente
¿Hay alguna razón por la que nadie responde? ¿Debo reformular la pregunta?
Creador el
1
En sus primeros días solo hay muchas personas que tienen tiempo para responder y hasta ahora solo has alcanzado 5 puntos de vista. Este stackexchange todavía es un bebé y no tiene muchos usuarios que le den tiempo.
joojaa
OKAY. Gracias. No me di cuenta de que había poca gente aquí.
Creador

Respuestas:

6

Si tiene prisa por hacer funcionar su renderizador y ya tiene la rutina poligonal llena funcionando correctamente , ¿puedo sugerir un enfoque alternativo, posiblemente más fácil? Aunque no estoy familiarizado con Lua, parece que está resolviendo la intersección exacta de una línea de exploración con el Bezier cuadrático que, aunque admirable, es posiblemente exagerado.

En su lugar, coloque sus Béziers en segmentos de línea y luego tírelos al convertidor de exploración poligonal. Sugiero usar una subdivisión binaria (recursiva): es decir, el Bezier cuadrático con puntos de control, se puede dividir en dos Beziers, y donde (que también es genial si solo tiene matemáticas de punto fijo).(UNA¯,si¯,C¯)(UNA¯,re¯,mi¯)(mi¯,F¯,C¯)

re¯=UNA¯+si¯2mi¯=UNA¯+2si¯+C¯4 4F¯=si¯+C¯2

IIRC, cada vez que se subdivide, el error entre el Bézier y solo un segmento de línea recta que une los puntos finales disminuye en un factor de ~ 4x, por lo que no toma muchas subdivisiones antes de que la aproximación lineal por partes sea indistinguible de la verdadera curva. También puede usar el cuadro delimitador de los puntos de control para decidir si puede omitir el proceso de subdivisión temprano, ya que también será un límite conservador en la curva.

Simon F
fuente
1
¡Gracias! A, B, C son vectores ¿verdad? Además, estoy usando el método de línea de exploración porque me permite obtener el número exacto de puntos que necesito. ¿Podrías echar un vistazo al código y adivinar por qué no funciona? Solo las fórmulas. También votaría la respuesta, pero no tengo 15 reputación.
Creador
Sí, AB y C son vectores; 2D en su caso, pero se aplica igualmente bien a N dimensiones. En cuanto a revisar el código ... como dije, no conozco a Lua e incluso obtener un renderizador de línea de exploración de polígono estándar correcto puede ser complicado, por ejemplo, debe tener mucho cuidado al contar cruces que se encuentran exactamente en las posiciones de los vértices. Cuando extiendes eso al manejo de Béziers directamente (lo que hice hace más de 20 años) es aún más difícil. Lo siento, no tengo tiempo.
Simon F
1
Gracias por la ayuda. Acabo de encontrar el problema. La ayc en la ecuación cuadrática se invirtieron.
Creador