2009-08-03 7 views
1

Je veux un algorithme efficace pour remplir un polygone avec une image, je veux remplir une image en trapèze. ce que je fais actuellement en deux étapes
1) Première Perform StretchBlt sur l'image,
2) Effectuer la colonne par colonne verticale StretchBlt, Algorithme de remplissage d'image de polygone

Y at-il une meilleure méthode pour mettre en œuvre ce? Existe-t-il un algorithme générique et rapide qui peut remplir n'importe quel polygone?

Merci, Ensoleillé

+1

Essayez-vous de déformer l'image selon la forme du polygone ou simplement de l'appliquer à la forme du polygone? –

+0

Salut Michael, je veux déformer l'image à la forme. – SunnyShah

Répondre

1

Je ne peux pas vous aider avec la partie de distorsion, mais le remplissage des polygones est assez simple, surtout si elles sont convexes.

Pour chaque ligne de balayage Y ont une table indexée par Y, contenant un minX et maxX.

Pour chaque tronçon, exécutez un algorithme de tracé de lignes DDA et utilisez-le pour remplir les entrées de la table.

Pour chaque ligne Y, vous avez maintenant un minX et un maxX, donc vous pouvez simplement remplir ce segment de la ligne de balayage. La partie difficile est une astuce mentale - ne pensez pas aux coordonnées en tant que pixels spécifiants. Pensez aux coordonnées comme étant entre les pixels. En d'autres termes, si vous avez un rectangle allant du point 0,0 au point 2,2, il devrait éclairer 4 pixels, et non 9. La plupart des problèmes de remplissage de polygones tournent autour de ce problème. AJOUTE: OK, il semble que ce que vous demandez vraiment, c'est comment étirer l'image à une forme non rectangulaire (mais trapézoïdale). Je le ferais en termes de paramètres s et t, allant de 0 à 1. En d'autres termes, un emplacement dans le rectangle d'origine est (x + w0*s, y + h0*t). Définissez ensuite une fonction telle que s et t correspondent également à des positions dans le trapèze, telles que ((x+t*a) + w0*s*(t-1) + w1*s*t, y + h1*t). Ceci définit un mappage de coordonnées entre les deux formes. Ensuite, il suffit de scanner x et y, en convertissant en s et t, et de mapper les points de l'un à l'autre. Vous voulez probablement avoir un petit filtre de lissage plutôt qu'une copie directe.

AJOUTÉ pour essayer de donner une meilleure explication: Je suppose que votre rectangle et votre trapèze ont des bords supérieur et inférieur parallèles à l'axe X. Le coin inférieur gauche du rectangle est <x0,y0> et le coin inférieur gauche du trapèze est <x1,y1>. Je suppose que la largeur et la hauteur du rectangle sont <w,h>. Pour le trapèze, je suppose qu'il a la hauteur h1, et que sa largeur inférieure est w0, tandis que sa largeur supérieure est w1. Je suppose que c'est le bord gauche "incline" d'une distance a, de sorte que la position de son coin supérieur gauche est <x1+a, y1+h1>. Supposons maintenant que vous itérez <x,y> sur le rectangle. À chaque point, calculez s = (x-x0)/w et t = (y-y0)/h, qui sont tous les deux dans la plage 0 à 1. (Je vais vous laisser comprendre comment faire cela sans utiliser de virgule flottante.) Puis convertir cela en une coordonnée dans le trapèze, comme xt = ((x1 + t*a) + s*(w0*(1-t) + w1*t)), et yt = y1 + h1*t. Puis <xt,yt> est le point dans le trapèze correspondant à <x,y> dans le rectangle. Maintenant, je vais vous laisser comprendre comment faire la copie :-) Bonne chance.

P.S.Et n'oubliez pas: les coordonnées tombent entre les pixels, pas sur eux.

+0

Salut Mike, Je sais comment faire Polygon Fill, Pouvez-vous s'il vous plaît m'expliquer comment puis-je faire Image remplir Polygon. – SunnyShah

+0

Salut Mike, Merci pour votre réponse, j'ai mis en œuvre un trapèze blt mais je pense que votre méthode est optimisée que la mienne. Je n'arrive pas à comprendre votre "mapping des coordonnées entre les deux formes". Pouvez-vous l'expliquer mieux ou pouvez-vous me donner des références pour l'explorer davantage? – SunnyShah

1

Serait-il possible de contourner le problème et d'utiliser OpenGL pour le faire pour vous? OpenGL peut effectuer des rendus dans des contextes de mémoire et si vous pouvez tirer parti de toute accélération matérielle en faisant cela, cela compliquera complètement les réglages de code que vous pouvez effectuer sur le CPU (bien que sur certaines anciennes cartes le rendu de contexte ne puisse pas profiter de le matériel). Si vous voulez faire cela complètement dans le logiciel MESA peut être une option.