Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1047 connectés 

  FORUM HardWare.fr
  Programmation
  Algo

  calcul coordonnées pixels d'un droite

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

calcul coordonnées pixels d'un droite

n°1662948
gtaman31
Posté le 25-12-2007 à 21:43:42  profilanswer
 

Bonjour,  
 
j'aimerai trouver les coordonnées des pixels qui se trouvent sur une droite que je trace sur une image.
J'explique, j'ai une image qui a bien évidemment des pixels qui se trouvent aux coordonnées (x,y).  
Je connais le point d'arrivée et le point de départ de ma droite, j'aimerai connaitre tous les pixels (coordonnées) qui se trouvent sur ma droite (aux erreurs de précisions près bien sur).  
Comment puis-je faire ?  
 
Une méthode consiste à calculer l'équation de la droite, pour chaque point vérifier si ses coordonnées vérifient l'équation (ou à peu près). Mais bon, cette méthode est très peu pratique car faut tester tous les pixels.  
J'aimerai faire une méthode par incrémentation mais j'ai du mal à trouver la formule.
 
Avez vous une idée ? merci !

mood
Publicité
Posté le 25-12-2007 à 21:43:42  profilanswer
 

n°1662951
Trap D
Posté le 25-12-2007 à 22:21:23  profilanswer
 

vec(A,M) = k vec(A,B)
Donc si je ne me trompe pas
x = k (xB - xA) + xA
y = k (yB - yA) + yA
avec k variant de -l'infini à + l'infini.
Garanti comme peut l'être une formule donnée après les agapes de Noël  :pt1cable:


Message édité par Trap D le 25-12-2007 à 22:21:45
n°1662959
gtaman31
Posté le 25-12-2007 à 22:35:37  profilanswer
 

ok merci, je vérifierai ça demain, car la hop au dodo.  
 
Si quelqu'un à d'autres solutions je suis preneur !  
 
bonne fin de soirée !


Message édité par gtaman31 le 25-12-2007 à 22:36:23
n°1664190
nargy
Posté le 31-12-2007 à 00:30:50  profilanswer
 
n°1664238
gzii
court-circuit
Posté le 31-12-2007 à 13:16:58  profilanswer
 

J'utilisais un algo similaire (enfin comme tout le monde je crois, c'est le seul que j'avais trouvé) mais il me semble que le code était bien plus court.
Au lieu de faire tous les cas ils ne pourraient pas inverser ?

n°1664357
nargy
Posté le 31-12-2007 à 19:59:20  profilanswer
 

c'est l'algo le plus rapide connu pour l'affichage de segments. il est possible de ne coder qu'un seul octant, mais pour des raisons simples de perfs coder les 4 octants est bien meilleur (c'est rapide en fait: 3 copié/collé, 2 relectures, 4 tests).
Un algo dérivé consiste à traiter les pixels par lot (de pixels horizontaux/verticaux), mais celà n'apporte véritablement de gains de perfs que pour l'affichage direct en mémoire/buffer vidéo et optims en assembleur.

n°1664433
gzii
court-circuit
Posté le 01-01-2008 à 15:16:29  profilanswer
 

C'est pas d'inverser deux coordonnées ou de les remettre en négatif qui prendra tant de temps.
Enfin ça dépend surtout de l'optimisation nécessaire.

n°1664636
nargy
Posté le 02-01-2008 à 10:03:50  profilanswer
 

Mettre des 'if's à l'intérieur de la boucle au lieu d'à l'extérieur, ajoute un délai proportionnel au nombre de pixels du segment, au lieu du délai constant correspondant à une instruction 'if' par segment.
Si tu n'as qu'un petit nombre de segments, d'un point de vue algorithmique, tu peux zapper cette optim.

n°1664656
bjone
Insert booze to continue
Posté le 02-01-2008 à 11:05:42  profilanswer
 

Bresenham c'est pas le plus rapide façe a une bête interpolation, et surtout pour paramétrer d'autres grandeurs, ça doit poser des problèmes.

n°1665956
nargy
Posté le 04-01-2008 à 17:41:03  profilanswer
 

la 'bête interpolation' est 3 à 10 fois plus lente à cause des calculs flotants vs entiers et de la multiplication vs addition.

mood
Publicité
Posté le 04-01-2008 à 17:41:03  profilanswer
 

n°1666248
bjone
Insert booze to continue
Posté le 05-01-2008 à 00:13:12  profilanswer
 

tu connais le concept de virgule fixe ?

n°1666292
nargy
Posté le 05-01-2008 à 03:10:57  profilanswer
 

Oui, et alors? Tu m'expliques comment faire une interpolation sans multiplication?
 
En plus la virgule fixe n'arrange pas les choses: celà ajoute au moins un shift de bit (voire une division qui est encore plus lente qu'une multiplication) pour pouvoir multiplier deux virgules fixes ensembles. Enfin, la virgule fixe nécessite que tu connaisse par avance un ordre de grandeur pour la résolution de l'image sans quoi le résultat n'est soit qu'approché, ou soit exact mais la précision interne y est surestimée.
 
pseudo code avec interpolation:

Code :
  1. calculer les coefficients a et b de la droite y=a*x+b passant par (x0,y0), (x1,y1)
  2. pour chaque coordonnée x
  3.   y=a*x+b


 
pseudo code style bresenham:

Code :
  1. initialiser le reste R de la division dy/dx
  2. pour chaque coordonnée x
  3.   si(reste<0) alors reste+=R; sinon {  y++; reste-=dy; }


 
La différence est dans le corps de la boucle pour:

  • 1 multiplication + 1 addition
  • 1 condition + 2 additions au pire (la division en octants permet en plus aux microprocesseurs de raccourcir le temps d'exécution de la condition car le 'then' est exécuté plus de fois (ici) et plus rapidement (en général) que le 'else')


Or la multiplication est environ 3 (calculs entiers), 5 (calculs fixes), voire 7 fois (flottants) plus lente qu'une addition (avec le même mode de calcul) sur la plupart des PCs (AMD est jusqu'à 2 fois plus rapide en flottant mais chauffe plus).
 
Bon, c ptet plus de l'algorithmique pratique que théorique... mais il n'y a pas à ma connaissance de processeur (ou peut être très spécifique?) qui multiplie plus vite qu'il n'additionne.


Message édité par nargy le 05-01-2008 à 03:26:31
n°1666472
Joel F
Real men use unique_ptr
Posté le 05-01-2008 à 17:22:19  profilanswer
 

+1 avec Nargy, hors de bresenham point de salut.

n°1666511
bjone
Insert booze to continue
Posté le 05-01-2008 à 18:52:52  profilanswer
 

la virgule fixe a des contraintes et des limites, mais qui cite brensenham (a juste titre), sans avoir expérimenté de la virgule fixe, bah bof.  
 
pseudo-code mélangé avec du C en virgule fixe:
 
pour l'itération en y:
 
sx = x0 << 16
dx = (x1-x0)<<16 / dy
pour chaque coordoonnée y:
       tracer( y, sx >> 16 )
       sx += dx
 
variante texturée/ombrée linéairement:
 
sx = x0 << 16
su = u0 << 16
sv = v0 << 16  
sm = m0 << 16
 
dx = (x1-x0)<<16 / dy
du = (u1-u0)<<16 / dy
dv = (v1-v0)<<16 / dy
dm = (m1-m0)<<16 / dy
pour chaque coordoonnée y:
       tracer( y, sx >> 16,  su>>16, sv>>16, sm>>16 )
       sx += dx
       su += du
       sv += dv
       sm += dm
       
 
quand on a un branchement par pixel, on évite de se palucher sur le reste hein.
 
avec brensenham, montre moi du pseudo code sur comment tu ferais évoluer d'autres gradients. (ça m'interresse, vu que j'ai jamais cherché à le faire en asm)
   

n°1666579
nargy
Posté le 05-01-2008 à 22:41:15  profilanswer
 

Je pige pas ta question... Pour faire de l'anticrénelage: la ligne se situe exactement là où reste==0. La valeur abs(reste)/dy est la transparence entre 0 = opaque et 1= transparent. C'est le même principe que celui décrit dans l'algo de bresenham pour transformer cette division en algo incrémental.
 
La version anglaise de cette page:
http://fr.wikipedia.org/wiki/Algor [...] _Bresenham
donne aussi l'algo de tracé de cercle (x²+y²=r²).
 
Le cartes graphiques affichent des textures 2D/3D par projection avec perspective avec un algo qu'on pourrait qualifier de double-bresenham: d'un côté la texture est balayée hyperboliquement (perspective) suivant un plan 3D, de l'autre les pixels de l'écran sont balayés horizontalement et verticalement pour afficher un polygone texturé de gauche à droite et de haut en bas.


Message édité par nargy le 05-01-2008 à 22:42:42
n°1666599
bjone
Insert booze to continue
Posté le 05-01-2008 à 23:17:36  profilanswer
 

justement, comment tu les détermines tes gradients à l'intérieur de boucle de bresenham ?
 
---
 
l'approche par virgule fixe, a été utilisée dans tous les renderers 3d logiciels de l'époque pré-gpu.
 
sinon pour le rendu gpu y'a pas de double balyage (dans le sens boucle), y'a une n gradients interpolés en virgule flottante le long des bords de triangles et à l'intérieur des scanlines (groupés par bloc de pixels carrés) (enfin là est ptet d'accord).
 
bref, c'est pas pour dire que bresenham c'est mal, loin du contraire, mais y'a d'autres approches valables, et à connaitre, dans le domaine de traçage de formes.  
 
en l'occurence le traçage de ligne (pour en revenir à nos moutons), je suis vraiment pas sûr que bresenham soit plus rapide que de la virugle fixe. après c'est suivant l'architecture (qui rends déjà la virgule fixe faisable ou pas).


Message édité par bjone le 05-01-2008 à 23:21:31
n°1666633
nargy
Posté le 06-01-2008 à 00:34:14  profilanswer
 

Si on prend comme référence le temps pris par une opération + - SHIFT ROT, et que le 'if < 0' prends T unités de temps. Le 'else' (vu la division en quadrans) est exécuté 1 fois quand le 'then' est exécuté 2 fois, en moyenne. Un incrément (y++), borné par le temps pris par une addition, est donc exécuté durant 0.33 unités de temps par tour de boucle.
 
Bresenham reste plus rapide que la virgule fixe, dans le cas moyen, tant que: Temps_du_if < 2/3 Temps_d_une_addition. C'est généralement le cas pour le test "if x<0" sur la plupart des architectures (test d'un seul bit en fait). Sur les PC cette valeur avoisine les 0.5, me semble-t-il.


Message édité par nargy le 06-01-2008 à 00:41:53
n°1666641
bjone
Insert booze to continue
Posté le 06-01-2008 à 01:41:05  profilanswer
 

c'est pas le test le problème c'est si il y a un branchement vidant le pipeline derrière.

n°1666739
nargy
Posté le 06-01-2008 à 13:58:43  profilanswer
 

heu.. je dirais que le pipeline rentre très peu en compte, en tout cas dans le sens calculatoire et données, par contre c'est vrai que le 'else' vide le cache de code. Ça se traduit concrètement par une rapidité accrue du 'then' par rapport au 'else', comme sans pipeline d'ailleurs, et j'en tiens compte en prenant une valeur moyenne T.
 
En fait, en y repensant, il y a bien un cas particulier pour lequel la virgule fixe est plus rapide: dans le cas où on dispose d'un registre à décalage. Un registre à décalage permet d'effectuer un shift de bits sans passer par l'unité de calcul, rendant cette opération aussi courte que possible: idéalement 1 cycle.
 
J'étudie plus haut le cas seulement où les registres sont généraux, c'est le cas le plus courant pour les CPUs, mais ce n'est pas forcément le cas pour les périphériques, dont le matériel utilise souvent les registres à décalage pour éviter l'emploi d'unités de calculs supplémentaires.

n°1666774
bjone
Insert booze to continue
Posté le 06-01-2008 à 15:52:30  profilanswer
 

oulà :D


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Algo

  calcul coordonnées pixels d'un droite

 

Sujets relatifs
Calcul d'une somme un peu spéciale...Besoin Vitesse de calcul
Calcul de l'agecalendrier et calcul auto de montants sur bulletin reservation
[PHP/MySQL] Calcul d'un prix en fonction d'une dimensionsupprimer tous les graphiques dans une feuille de calcul
[JAVA]Algorithme de calcul de la limite de la somme des entiersEXCELfeuille de calcul
calcul matricielComsol / Extraction ou calcul de la matrice jacobienne
Plus de sujets relatifs à : calcul coordonnées pixels d'un droite


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR