Estou trabalhando em uma biblioteca de gráficos há algum tempo e cheguei ao ponto em que tenho que desenhar fontes baseadas em Bezier e em linhas. Até este ponto, estou preso a isso:
As linhas verdes são os caminhos de Bezier e a parte branca é o que é renderizado.
O código que eu uso para Beziers está aqui . O de linhas está aqui . Para quem não sabe, isso é Lua.
Renderização de caminho (linhas): 32 - 39 O algoritmo é o seguinte:
- Iterando de 0 para 1 em determinados intervalos
- calculando xey com esta fórmula:
(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3
Até este ponto, tudo funciona bem. As linhas verdes são geradas usando o método path.
A parte branca é renderizada de uma maneira completamente diferente:
- Pego as coordenadas x dos Beziers e as linhas em um Y específico e as coloco em uma mesa.
- Eu percorro a tabela e cada vez que encontro um ponto, altero o valor do estado. No mesmo loop for também é verificado se o estado está ativado. Se for, eu desenho um pixel na tela.
Para encontrar os valores x de ay, eu uso o método getX (linha 46 em Bezier e linha 31 na linha).
O código que eu uso para o desenho em si é 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
Explicação rápida: para i, v em pares itera pela tabela fornecida como argumento para pares. love.graphics.points (x, y) define um ponto em x, y.
Desde já, obrigado.
fonte
Respostas:
Se você estiver com pressa de fazer o renderizador funcionar e já tiver a rotina poligonal preenchida funcionando corretamente , posso sugerir uma abordagem alternativa e possivelmente mais fácil? Embora eu não esteja familiarizado com Lua, parece que você está resolvendo a interseção exata de uma linha de varredura com o Bezier quadrático que, embora admirável, é possivelmente um exagero.
Em vez disso, agrupe seus Beziers em segmentos de linha e jogue-os no conversor de varredura de polígonos. Sugiro apenas o uso de subdivisão binária (recursiva): ou seja, o Bezier quadrático com pontos de controle,(A¯¯¯¯,B¯¯¯¯,C¯¯¯¯) pode ser dividido em dois Beziers, (A¯¯¯¯,D¯¯¯¯,E¯¯¯¯) e (E¯¯¯¯,F¯¯¯¯,C¯¯¯¯)
Onde
IIRC, sempre que você subdividir, o erro entre o Bezier e apenas um segmento de linha reta que une os pontos finais diminui em um fator de ~ 4x, portanto, não são necessárias muitas subdivisões antes que a aproximação linear por partes seja indistinguível da verdadeira curva. Você também pode usar a caixa delimitadora dos pontos de controle para decidir se pode pular o processo de subdivisão mais cedo, pois também será um limite conservador na curva.
fonte