Comment rendre un bitmap carré à un polygone à quatre faces arbitraire en utilisant GDI?
j'ai besoin de peindre une image carrée, mappée ou transformée en un polygone à quatre faces inconnu à la compilation. Comment puis-je faire cela?
explication plus longue
le problème spécifique est de rendre une tuile de carte avec une projection de carte non rectangulaire. Supposons que j'ai la tuile suivante:
et je sais que les quatre points d'angle doivent être ici:
etant Donné que je voudrais obtenir le sortie suivante:
la tuile carrée peut être:
- Rotation; et/ou
- Être plus étroite à une extrémité qu'à l'autre.
I penser le deuxième élément signifie que cela nécessite une transformation sans affine.
notes supplémentaires aléatoires
à quatre côtés? il est plausible que pour être complètement correct, la tuile devrait être mappé à un polygone avec plus de quatre points, mais pour nos fins et à l'échelle, il est établi, d'une place -> quatre autres pôles-polygone la transformation devrait suffire.
pourquoi de préférence GDI seulement? tout le rendu jusqu'à présent est fait en utilisant GDI, et je veux garder le code (a) rapide et (b) nécessitant aussi peu d'extra les bibliothèques que possible. Je suis au courant de un certain soutien pour les transformations de la GDI et ont expérimenté avec eux aujourd', mais même après avoir expérimenté avec eux, je ne suis pas sûr qu'ils soient suffisamment souple pour cet usage. Si elles le sont, je n'ai pas réussi à trouvez-le, et j'apprécierais vraiment un exemple de code.
GDI+ est aussi ok puisque nous l'utilisons ailleurs, mais je sais qu'il peut être lent, et la vitesse est important ici.
Une autre alternative est rien Delphi- / C++Builder - spécifique; ce programme est écrit principalement en C++ en utilisant la VCL, et les graphismes en question sont actuellement peints à un TCanvas avec un mélange de méthodes de TCanvas et appels bruts WinAPI / GDI.
images de superposition: une dernière mise en garde est qu'une couleur dans la tuile peut être pour la couleur-clé transparence: c'est-à-dire, tous les carrés blancs (par exemple) dans la tuile ci-dessus doit être transparent lorsqu'il est dessiné sur tout ce qui est en dessous. Actuellement, les carreaux sont dessinés à carré ou aligné sur l'axe rectangulaire cibles à l'aide de TransparentBlt.
je suis désolé pour toutes les mises en garde supplémentaires qui rendent cette question plus compliquée que " que l'algorithme doit-je utiliser?"Mais j'accepterai volontiers les réponses avec seulement des informations algorithmiques aussi.
3 réponses
Vous pourriez également jeter un coup d'oeil à Graphics32. L'écran tourné bewlow montre à quoi ressemble la démonstration de transfrom dans GR32
regardez 3D Lab graphiques Vectoriels. (Spécialement "terrain de Football", dans la démo).
une autre ressource cool est AggPas avec source complète incluse (télécharger)
AggPas est une bibliothèque de graphiques vectoriels 2D libre accès et gratuite. C'est un port natif D'objet Pascal de la bibliothèque de géométrie Anti-Grain - AGG, écrit à l'origine par Maxim Shemanarev en C++. AggPas ne dépend d'aucun API ou technologie graphique. Fondamentalement, vous pouvez penser AggPas comme d'un moteur de rendu qui produit des images de pixels en mémoire à partir de certaines données vectorielles.
Voici comment le perspective
démo ressemble à:
après transformation:
la technique générale est décrite dans "Digital Image Warping"de George Wolberg. Il ressemble à abrégé contient les maths pertinentes, comme le fait ce document. Vous devez créer une matrice de perspective qui correspond d'un quad à l'autre. Les liens ci-dessus montrent comment créer la matrice. Une fois que vous avez la matrice, vous pouvez scanner votre tampon de sortie, effectuer la transformation (ou éventuellement l'inverse-selon ce qu'ils vous donnent), et cela vous donnera des points dans l'image d'origine que vous pouvez copier.
il pourrait être plus facile D'utiliser OpenGL pour dessiner un quad texturé entre les 4 points, mais cela n'utilise pas GDI comme vous le vouliez.