Come devo riempire una forma composta da curve di Bezier e linee rette?


8

Ho lavorato su una libreria grafica da qualche tempo e sono arrivato al punto in cui devo disegnare Bezier e caratteri basati su linee. Fino a questo punto sono bloccato con questo:

io

un'

Le linee verdi sono i percorsi di Bezier e la parte bianca è ciò che viene reso.

Il codice che uso per Beziers è qui . Quello per le linee è qui . Per coloro che non sanno che è Lua.

Rendering del tracciato (linee): 32 - 39 L'algoritmo è il seguente:

  1. Iterazione da 0 a 1 a determinati intervalli
  2. calcolando xey con questa formula: (1-index)^2*x1+2*(1-index)*index*x2+index^2*x3

Fino a questo punto tutto funziona bene. Le linee verdi sono generate usando il metodo path.

Il rendering della parte bianca è completamente diverso:

  1. Ottengo le coordinate x di Beziers e le linee in una Y particolare, le metto in una tabella.
  2. Esamino la tabella e ogni volta che incontro un punto cambio il valore di stato. Allo stesso modo per il ciclo è anche verificare se lo stato è attivo. Se lo è, disegno un pixel sullo schermo.

Per trovare i valori x di ay, uso il metodo getX (riga 46 in Bezier e riga 31 in Line).

Il codice che uso per il disegno stesso è questo:

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

Spiegazione rapida: per i, v in coppie scorre la tabella fornita come argomento alle coppie. love.graphics.points (x, y) imposta un punto su x, y.

Grazie in anticipo.


C'è una ragione per cui nessuno risponde? Dovrei riformulare la domanda?
Creatore

1
All'inizio ci sono solo così tante persone che hanno il tempo di rispondere e finora hai raggiunto solo 5 visualizzazioni. Questo stackexchange è ancora un bambino e non ha molti utenti che gli danno tempo.
joojaa,

OK. Grazie. Non mi rendevo conto che c'erano così poche persone qui.
Creatore

Risposte:


6

Se hai fretta di far funzionare il tuo renderer e hai già il corretto funzionamento della routine poligonale piena , posso suggerire un approccio alternativo, forse più semplice? Sebbene non conosca Lua, sembra che tu stia risolvendo l'intersezione esatta di una linea di scansione con il quadratico Bezier che, sebbene ammirevole, è probabilmente eccessivo.

Invece, tessellate i vostri Bezier in segmenti di linea e poi gettateli nel convertitore di scansione poligonale. Suggerisco solo di usare la suddivisione binaria (ricorsiva): cioè il Bezier quadratico con punti di controllo,(UN¯,B¯,C¯) può essere diviso in due bezier, (UN¯,D¯,E¯) e (E¯,F¯,C¯) dove

D¯=UN¯+B¯2E¯=UN¯+2B¯+C¯4F¯=B¯+C¯2
(il che è fantastico anche se hai solo matematica a punto fisso).

IIRC, ogni volta che si suddivide, l'errore tra Bezier e solo un segmento di linea retta che unisce i punti finali scende di un fattore di ~ 4x, quindi non ci vogliono molte suddivisioni prima che l'approssimazione lineare a tratti sia indistinguibile dal vero curva. È inoltre possibile utilizzare il rettangolo di selezione dei punti di controllo per decidere se è possibile saltare in anticipo il processo di suddivisione poiché sarà anche un limite conservativo sulla curva.


1
Grazie! A, B, C sono i vettori giusto? Inoltre, sto usando il metodo scanline perché mi permette di ottenere il numero esatto di punti di cui ho bisogno. Potresti dare un'occhiata al codice e indovinare perché non funziona? Solo le formule. Vorrei anche votare la risposta, ma non ho 15 reputazione.
Creatore

Sì, AB e C sono vettori; 2D nel tuo caso, ma si applica ugualmente bene a N dimensioni. Per quanto riguarda l'esame del codice ... come ho detto, non conosco Lua e persino ottenere un renderizzatore di scanline poligonale standard corretto può essere complicato - ad esempio, devi fare molta attenzione quando conti gli incroci che si trovano esattamente sulle posizioni dei vertici. Quando lo estendi alla gestione diretta di Beziers (cosa che ho fatto circa 20+ anni fa), è ancora più difficile. Mi dispiace di non avere tempo.
Simon F,

1
Grazie per l'aiuto. Ho appena trovato il problema. A e C nell'equazione quadratica sono state invertite.
Creatore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.