Cercle discret (point par point) en c++

Soyez le premier à donner votre avis sur cette source.

Snippet vu 14 335 fois - Téléchargée 29 fois

Contenu du snippet

Ce programme permet de dessiner un cercle discret (point par point) et d?arrondis les cordonnées réels

Source / Exemple :


int xd=0,yd=0;
int n=0;
int s=0;
/* Plot generates a point of the circle */
void plot(x,y)
int x,y;
{
  s++;
  cout<<"Val Of X= "<<x+xd<< " and Val of y= "<<y+yd;
}
//------------------------------------------------------void main(void)
{
  s=0;
  int ri,x,y; /* Integer part of radius point */

 float a,rph,rpxo,rmxo,rpyo,rmyo; /* constants */
 float xoph,xomh,yoph,yomh;
 float r,xo,yo; /* radius and center */
 double d; /* control value */
 float tmp,tmp1; /* temp. value */
 n=0;
//Provide the radius and the center:R,xo,yo
 
 cout<<" val of R= ";
 sin>>r;
 
 xo=0;yo=0 ;
 ri=(int)r; /* integer part of the radius */
 r=r-0.5; /* circle of radius r'=r-0.5 is generated */
 a=r-ri; /* corresponding fractional part of radius */
/* CIRCLE WITH SMALL RADIUS */
if (ri<=1)
{
    tmp=2*r+1;
    for(x=-2;x<=2;x++) /* the generation is brute force */
    for(y=-2;y<=2;y++)
    {
       tmp1=x*x+y*y-r*r;
       if ((tmp1>=0) && (tmp1<tmp))
       plot(x,y);
    }
}
else
{
   // ri>1
   /* GENERAL CASE */
   /* Initialization of loop constants */
   rph=r+0.5;
   rpxo=r; rmxo=r-xo; rpyo=r+yo; rmyo=r-yo;
   xoph=xo+0.5; xomh=xo-0.5; yoph=yo+0.5; yomh=yo-0.5;
/* STARTING POINT COMPUTATION */
    y=0;
    d=((ri-rpxo)*(ri+rmxo)+yo*yo)/2.0; /* Initial value of d for (ri,0) */
   if (d<(a+xo)) /* does (ri+1,0) belong to the circle ? */
{ plot(ri+1,0); /* (ri+1,0) does belong to the circle */
if (d>=0) { plot(ri,0); x=ri;} /* (ri,0) belongs also to the circle */
else { x=ri+1; d+=ri-xomh;} /* (ri,0) doesn't belong to the circle */
}
else if ((d>=0) && (d<rph)) /* does (ri,0) belong to the circle ? */
{ plot(ri,0);
  x=ri;
}
else /* if neither (ri+1,0) nor (ri,0) belong to the
circle then (ri-1,0) does */
 {
   x=ri-1; plot(x,0);
   d+=xoph-ri;
 }
/* END OF STARTING POINT PHASE */
/* GENERATION OF QUADRANT 1 */
while (x>0)
 {
   if (d<(rpyo-y)) /* Type (a) ? */
 {  d+=y-yomh;
 y++;
 plot(x,y);
}
else
{ d+=xoph-x;
x--;
if (d>=0) plot(x,y); /* Type (b) ? */
else
{ d+=y-yomh; /* Type (c) !*/
y++;
plot(x,y);
}
}
}
/* END OF GENERATION OF QUADRANT 1 */
/* LIMIT POINTS BETWEEN QUADRANT #1 AND QUADRANT #2 */
if (d<(rpyo-y)) /* Does (0,y+1) belong to the circle ? */
{ d+=xoph; plot(0,y+1); x--; plot(-1,y); }
/* GENERATION OF QUADRANT 2 */
while (y>0 )
{ if (d<(rmxo+x))
{
d+=xoph-x;
x--;
plot(x,y);
}
else
{ d+=yoph-y;
y--;
if (d>=0) plot(x,y);
else
{ d+=xoph-x;
  x--;
plot(x,y);
}
}
}
/* END OF GENERATION OF QUADRANT #2 */
/* LIMIT POINTS BETWEEN QUADRANT #2 AND QUADRANT #3 */
if (d<(rpxo+x))
{ d+=yoph; plot(x-1,0); y--; plot(x,-1); }
/* GENERATION OF QUADRANT #3 */
while (x<0)
{ if (d<(rmyo+y))
{ d+=yoph-y;

y--;
plot(x,y);
}
else
{ d+=x-xomh;
x++;
if (d>=0) plot(x,y);
else
 { d+=yoph-y;
   y--;
   plot(x,y);
 }
}
}
/* END OF GENERATION OF QUADRANT #3 */
/* LIMIT POINTS BETWEEN QUADRANT #3 AND QUADRANT #4 */
if (d<(rmyo+y))
{ d-=xomh; plot(0,y-1); x++; plot(1,y); }
/* GENERATION OF QUADRANT #4 */
while (y<0)
{ if (d<(rpxo-x))
  { d+=x-xomh;
    x++;
    plot(x,y);
  }
else
{  d+=y-yomh;
   y++;
   if ((d>=0)&&(y)) plot(x,y);
   else
{  d+=x-xomh;
   x++;
   if (y) plot(x,y);
}
}
}
/* END OF GENERATION OF QUADRANT #4 */
} /* END OF THE GENERAL CASE */
}
//------------------------------------------------------
  GO and test

Conclusion :


pour plus de détailles contactez moi à l'adresse suivante: bob_carlos2006@yahoo.fr

A voir également

Ajouter un commentaire Commentaires
Messages postés
573
Date d'inscription
samedi 16 novembre 2002
Statut
Membre
Dernière intervention
9 avril 2008
1
1 -

En assembleur, chaque opération modifie les états du flag et on peut directement faire un jump en fonction de l'état de ses bits.

Par exemple:
addition register, regiter
bcc \label ; <- branch carry clear, => aller à \label si le bit du flag qui correspond a un resultat nul est a 1

A la limite, un: if (hFile == NULL) {...} else {...} peut être parfaitement bien compilé.

Et encore c'est le plus simple. Certains bits du flag correspond a des débordements sur le registre d'"arrivé", des comparaisons des registres (plus grand ?, plus petit ?), des états des bits de poids fort et faible, et autres ...

Bref, beaucoup d'optimisation qui ne peuvent pas être automatiquement faites par un compilateur si l'utilisateur n'utilise pas volontairement (dans l'algorithme lui même) les avantages des flags.


2 -

2 programmes en assembleur en tournent pas forcement à la même vitesse.
sin et cos sont en assembleur mais plus lentes qu'une suite d'opérations élementaires rapides.

Dans le cas du cercle avec sin et cos tu calcules plusieurs fois la meme pixel, pas avec brensenham.

Quand je dis assembleur c'est le langage, genre le 8808, 8086, 80386, 80286, pas le module d'assemblage du compilateur.
Perso j'ai fait que du 68000 pour ti et l'assembleur change la vitesse de façon ultra-sensible.


Je code en anglais depuis un an, c'est plus stylé :D
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
a ce niveau la l'assembleur n'optimisera rien du tout
1 -> un compilo en mode release c'est loin d'etre stupide il te sort souvent un code plus rapide que le tien
2 -> de toute facon les fonctions sin et cos, eles y sont deja,em asm

[edit] heu j' ai un doute la, ad tu dis
'Seul l'assembleur permet d'optimiser ce code." tu parles duquel ? :p

et heu dit voir.... vu la qte d'anglais dans ton code, t'est sur que c'est toi qui l'a fait ? :p
Messages postés
573
Date d'inscription
samedi 16 novembre 2002
Statut
Membre
Dernière intervention
9 avril 2008
1
Par rapport à des opérations élémentaires sur des entiers, c'est sûr que c'est infiniment plus lent.
Les programmes C qui tracent des lignes en calculant le coefficient directeur ou des cercles en utilisant sin et cos
se font larguer par leur homologue VB qui utilise Brensenham.

Même avec un ordinateur qui a une puissante FPU et en créant une table de sinus et de cosinus, l'algo de Brensenham est plus rapide.


Seul l'assembleur permet d'optimiser ce code.
Messages postés
536
Date d'inscription
mercredi 27 avril 2005
Statut
Membre
Dernière intervention
22 août 2008

ah car les fonction trigo sont super lente ...
Messages postés
573
Date d'inscription
samedi 16 novembre 2002
Statut
Membre
Dernière intervention
9 avril 2008
1
Bien, mais avez-vous un seul appel à une fonction trigonometrique ?
C'est l'algorithme de Brensenham, un ingé d'IBM qui a aussi fait un algorithme ultra rapide de tracé de ligne (algo utilisé partout).
Afficher les 7 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.