Je travaille sur une bibliothèque graphique depuis un certain temps maintenant et j'en suis arrivé au point où je dois dessiner des polices Bézier et basées sur des lignes. Jusqu'à ce point, je suis coincé avec ceci:
Les lignes vertes sont les chemins de Bézier et la partie blanche est ce qui est rendu.
Le code que j'utilise pour Béziers est ici . Celui pour les lignes est ici . Pour ceux qui ne le savent pas, c'est Lua.
Rendu du chemin (lignes): 32 - 39 L'algorithme est le suivant:
- Itération de 0 à 1 à certains intervalles
- calculer le x et y avec cette formule:
(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3
Jusqu'à ce point, tout fonctionne bien. Les lignes vertes sont générées à l'aide de la méthode du chemin.
La partie blanche est rendue d'une manière complètement différente:
- J'obtiens les coordonnées x des Béziers et des lignes à un Y particulier, puis je les mets dans un tableau.
- Je parcours le tableau et chaque fois que je rencontre un point, je change la valeur de l'état. De même, la boucle for vérifie également si l'état est activé. Si c'est le cas, je dessine un pixel à l'écran.
Pour trouver les valeurs x de ay, j'utilise la méthode getX (ligne 46 dans Bézier et ligne 31 dans Line).
Le code que j'utilise pour le dessin lui-même est celui-ci:
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
Explication rapide: pour i, v par paires, parcourt le tableau donné en argument aux paires. love.graphics.points (x, y) définit un point à x, y.
Merci d'avance.
la source
Réponses:
Si vous êtes pressé de faire fonctionner votre moteur de rendu et que la routine polygonale remplie fonctionne correctement , puis-je suggérer une approche alternative, peut-être plus simple? Bien que je ne connaisse pas Lua, il semble que vous résolviez l'intersection exacte d'une ligne de balayage avec le Bézier quadratique qui, bien qu'admirable, est peut-être exagéré.
Au lieu de cela, tesselez vos Béziers en segments de ligne, puis jetez-les dans le convertisseur de balayage polygonal. Je suggère d'utiliser simplement une subdivision binaire (récursive): ie le Bézier quadratique avec des points de contrôle,(UNE¯¯¯¯,B¯¯¯¯,C¯¯¯¯) peut être divisé en deux Béziers, (UNE¯¯¯¯,r鯯¯¯,E¯¯¯¯) et (E¯¯¯¯,F¯¯¯¯,C¯¯¯¯)
où
IIRC, chaque fois que vous subdivisez, l'erreur entre le Bézier et juste un segment de ligne droite joignant les points d'extrémité diminue d'un facteur de ~ 4x, donc il ne faut pas beaucoup de subdivisions avant que l'approximation linéaire par morceaux soit indiscernable de la vraie courbe. Vous pouvez également utiliser le cadre de délimitation des points de contrôle pour décider si vous pouvez ignorer le processus de subdivision tôt car ce sera également une limite conservatrice sur la courbe.
la source