2010-12-27 4 views
8

Un bref contexte: Je travaille sur une application de dessin basée sur le Web et ai besoin de dessiner des splines épaisses de 1px qui passent à travers leurs points de contrôle.Alignement des splines 1px alias, pixel-parfait (Catmull-Rom, spécifiquement)

Le problème avec lequel je me bats est que j'ai besoin de dessiner chacun des pixels entre p1 et p2 comme si j'utilisais un outil crayon 1px. Donc, pas d'anti-aliasing et un pixel à la fois. Cela doit être fait manuellement sans l'utilisation d'un code de bibliothèque ligne/courbe car mon système de pinceau dépend de la présence d'une coordonnée de pixel pour appliquer la pointe du pinceau à la toile. Essentiellement, j'ai besoin de combiner le pixel d'un pas de quelque chose comme l'algorithme de Bresenham avec les coordonnées renvoyées par l'équation Catmull-Rom. J'ai des problèmes parce que les points Catmull-Rom ne sont pas uniformément distribués (donc je ne peux pas dire qu'il devrait y avoir 100 pixels dans la courbe et exécuter l'équation 100 fois). J'ai essayé d'utiliser une valeur de départ estimée du maximum des deltas X et Y et de combler les lacunes avec Bresenham, mais en raison des arrondis, je me retrouve avec des sections «sales» (c'est-à-dire que la ligne remonte clairement vers le haut). à droite mais j'ai toujours deux pixels avec le même composant Y, résultant en une section "grasse" de la ligne).

Je suis sûr que cela a été résolu car presque chaque programme graphique qui dessine des splines doit prendre en charge les courbes de pixels propres que je recherche. Après un peu de recherche en mathématiques, cependant, je suis un peu confus et toujours sans solution. Aucun conseil?

EDIT: Voici un exemple d'une courbe que je pourrais avoir à rendre:

alt text

Ce qui pourrait avoir un résultat attendu qui ressemble à ceci (notez que ceci est une estimation):

En utilisant l'équation de spline Catmull-Rom, nous avons besoin de quatre points pour créer un segment. P0 et P3 sont utilisés comme tangentes pour la direction entrante et sortante du segment P1-> P2. Avec une spline Catmull-Rom, la section bleue est tout ce qui est interpolé lorsque t passe de 0 à 1. P0 et P3 peuvent être dupliqués pour s'assurer que la partie verte est restituée, donc ce n'est pas un problème pour moi.

Par souci de simplicité, j'ai besoin de rendre les pixels sur la courbe entre P1 et P2, étant donné que j'ai des tangentes sous la forme de P0 et P3. Je n'ai pas nécessairement besoin d'utiliser les splines Catmull-Rom, mais elles semblent être le bon outil pour ce travail car les points de contrôle doivent être passés. La distribution non uniforme des points d'interpolation est ce qui me lance pour une boucle.

EDIT2: Voici un exemple de ce que je veux dire quand je dis ma courbe résultante est sale:

alt text

Les flèches rouges indiquent quelques endroits où il ne devrait pas être un pixel. Cela se produit car les composantes X et Y de la coordonnée calculée ne changent pas au même rythme. Donc, quand chacun des composants est arrondi (donc j'ai un emplacement de pixel exact), il peut arriver que X ou Y ne soit pas bousillé parce que la coordonnée calculée est, disons, (42.4999, 50.98). L'échange de la ronde contre un sol ou un plafond ne résout pas le problème, car il change juste où il se produit.

+0

Ce serait génial si vous pouvez ajouter un autre dessin montrant votre résultat attendu de P1 à P2. –

+0

@belisarius Je n'ai pas calculé le nombre de pixels qui seraient remplis en fonction de l'équation Catmull-Rom, mais la seconde image devrait vous donner une idée de ce que j'essaie d'obtenir. – Xenethyl

+0

Je l'ai demandé en raison de votre commentaire: _mais j'ai toujours deux pixels avec le même composant Y_ –

Répondre

2

Ici, vous avez a paper describing method for the re-parametrization of splines afin d'obtenir des points espacés le long de la longueur de la courbe.Je pense que cela peut résoudre votre problème si vous pouvez l'adapter aux courbes Catmull-Rom (ne devrait pas être trop difficile, je suppose)

+0

Merci pour le lien au papier. Je n'avais pas inclus "longueur d'arc" dans mon Google. Je viens de faire un peu plus de recherche et a obtenu des résultats bien meilleurs (voir http://www.actionscript.org/forums/showthread.php3?t=213252). Il semble que la solution acceptée dépende beaucoup de l'approximation et du pré-calcul. Cela peut poser un problème de performance pour moi puisque cela est fait en JavaScript. Je pourrais re-poster mon problème différemment après que j'ai réfléchi à cela, mais pour l'instant merci pour l'aide. Vous m'avez certainement indiqué dans la bonne direction. – Xenethyl

+0

@Xenethyl Content de vous aider! J'espère que vous pouvez l'optimiser pour votre scénario. –