nues1.c

Go to the documentation of this file.
00001 #include <math.h>
00002 #include "machine.h"
00003 #include "math_graphics.h"
00004 
00005 
00006 static int nnuees __PARAMS((double *x, double *y, double *z, integer *n, double *bx, double *by, double *bz, integer *nbbary, integer *chaine, integer *ierr));
00007 
00008 static int heapi2 __PARAMS((integer *criter, integer *record, integer *n));
00009 static int bblocs __PARAMS((double *x, double *y, double *z, integer *n, double *bx, double *by, double *bz, integer *nbbary, integer *chaine, integer *ierr));
00010 int C2F(nues1)(double *xyz, integer *n, double *bxyz, integer *nbbary, integer *chaine, integer *ierr);
00011 
00012 /*------------------------------------------------------
00013  *------------------------------------------------------*/
00014 
00015 
00016 int C2F(nues1)(double *xyz, integer *n, double *bxyz, integer *nbbary, integer *chaine, integer *ierr)
00017 {
00018   bblocs(xyz, xyz+(*n), xyz+2*(*n), n, bxyz, bxyz+(*nbbary), 
00019          bxyz+2*(*nbbary), nbbary, chaine, ierr); 
00020   nnuees(xyz, xyz+(*n), xyz+2*(*n), n, bxyz, bxyz+(*nbbary), 
00021          bxyz+2*(*nbbary), nbbary, chaine, ierr); 
00022   return 0;
00023 }
00024 
00025 /*------------------------------------------------------
00026  * entry : n points x,y,z 
00027  * nbbary : initial bary_centers bx,by,bz 
00028  * out : new nbbary bary_centers  bx,by,bz 
00029  * chaine(i) point on the barycenter whom  x(i),y(i),z(i)
00030  * belongs 
00031  *------------------------------------------------------*/
00032 
00033 static int nnuees(double *x, double *y, double *z, integer *n, double *bx, double *by, double *bz, integer *nbbary, integer *chaine, integer *ierr)
00034 {
00035   integer i1, i2;
00036   double d1, d2, d3;
00037   static double d;
00038   static integer i, k, l, m, iclas;
00039   static int vvide;
00040   static double id;
00041   static integer im;
00042   static double ax[256], ay[256], az[256];
00043   static integer nn[256];
00044   static double ix;
00045   static integer nbiter;
00046   static double idx;
00047   static integer nnn;
00048 
00049     /* Parameter adjustments */
00050   --chaine;
00051   --z;
00052   --y;
00053   --x;
00054   --bz;
00055   --by;
00056   --bx;
00057 
00058   *ierr = 0;
00059   if (*nbbary > 256) 
00060     {
00061       /*     too many bary_center */
00062       *ierr = 1;
00063       return 0;
00064     } 
00065   else if (*n <= *nbbary) 
00066     {
00067       /*     number of bary_centers is greater than number of points */
00068       i1 = *n;
00069       for (i = 1; i <= i1; ++i) {
00070         bx[i] = x[i];
00071         by[i] = y[i];
00072         bz[i] = z[i];
00073         chaine[i] = i;
00074       }
00075       i1 = *nbbary;
00076       for (i = *n + 1; i <= i1; ++i) {
00077         bx[i] = (float)0.;
00078         by[i] = (float)0.;
00079         bz[i] = (float)0.;
00080         chaine[i] = 0;
00081       }
00082       return 0;
00083   }
00084   /*     init des ancients bary_centres */
00085   i1 = *nbbary;
00086   for (i = 1; i <= i1; ++i) {
00087     ax[i - 1] = bx[i];
00088     ay[i - 1] = by[i];
00089     az[i - 1] = bz[i];
00090   }
00091   /*     grande boucle d'iteration */
00092   nbiter = 0;
00093  L9999:
00094   ++nbiter;
00095   /*     raz des nouveaux bary_centres */
00096   i1 = *nbbary;
00097   for (i = 1; i <= i1; ++i) {
00098     bx[i] = (float)0.;
00099     by[i] = (float)0.;
00100     bz[i] = (float)0.;
00101     nn[i - 1] = 0;
00102   }
00103 
00104   i1 = *n;
00105   for (i = 1; i <= i1; ++i) {
00106     idx = 1e30;
00107     l = 0;
00108     /*     pour tous les ancients bary_centres */
00109     i2 = *nbbary;
00110     for (k = 1; k <= i2; ++k) {
00111       /* Computing 2nd power */
00112       d1 = x[i] - ax[k - 1];
00113       /* Computing 2nd power */
00114       d2 = y[i] - ay[k - 1];
00115       /* Computing 2nd power */
00116       d3 = z[i] - az[k - 1];
00117       ix = d1 * d1 + d2 * d2 + d3 * d3;
00118       /*     on garde le bary_centre le plus proche du point */
00119       if (ix < idx) {
00120         l = k;
00121         idx = ix;
00122       }
00123     }
00124 
00125     if (l == 0) {
00126       /*     can not find any bary center for that point */
00127       chaine[i] = 0;
00128       *ierr = 2;
00129     }
00130     /*     on affecte le point a la classe l des nouveaux bary_centres */
00131     /*     ( le plus proche) */
00132     /*     le ieme point de l'image index les points par l */
00133     chaine[i] = l;
00134     bx[l] += x[i];
00135     by[l] += y[i];
00136     bz[l] += z[i];
00137     ++nn[l - 1];
00138   }
00139 
00140   i1 = *nbbary;
00141   for (k = 1; k <= i1; ++k) {
00142     if (nn[k - 1] != 0) {
00143       bx[k] /= nn[k - 1];
00144       by[k] /= nn[k - 1];
00145       bz[k] /= nn[k - 1];
00146     }
00147   }
00148 
00149   vvide = 0;
00150   i1 = *nbbary;
00151   for (k = 1; k <= i1; ++k) {
00152     if (nn[k - 1] == 0) {
00153     L7:
00154       /*     k est une classe vide */
00155       vvide = 1;
00156       /*     on choisi la classe de plus grand nombre d'elements */
00157       im = 0;
00158       l = 1;
00159       i2 = *nbbary;
00160       for (m = 1; m <= i2; ++m) {
00161         if (nn[m - 1] >= im) {
00162           l = m;
00163           im = nn[l - 1];
00164         }
00165       }
00166       if (im <= 2) {
00167         /*     on ne peut couper la classe */
00168         bx[k] = (float)0.;
00169         by[k] = (float)0.;
00170         bz[k] = (float)0.;
00171         vvide = 0;
00172         /*     empty cluster */
00173         goto L6;
00174       }
00175       /*     empty cluster ,k, :we cut in two the cluster ,l, with , nn(l), */
00176       /*     elements */
00177       nnn = nn[l - 1] / 2;
00178       nn[l - 1] = nnn;
00179       nn[k - 1] = nnn;
00180       iclas = 1;
00181       i2 = *n;
00182       for (i = 1; i <= i2; ++i) {
00183         if (chaine[i] == l) {
00184           if (iclas == 1) {
00185             bx[k] = x[i];
00186             by[k] = y[i];
00187             bz[k] = z[i];
00188             chaine[i] = k;
00189             ++iclas;
00190           } else {
00191             chaine[i] = 0;
00192             bx[l] = x[i];
00193             by[l] = y[i];
00194             bz[l] = z[i];
00195           }
00196           idx = (d1 = bx[k] - bx[l], Abs(d1)) + (d2 = by[k] - 
00197                                                  by[l], Abs(d2)) + (d3 = bz[k] - bz[l], Abs(
00198                                                                                             d3));
00199           idx /= (d1 = bx[l], Abs(d1)) + (d2 = by[l], Abs(
00200                                                           d2)) + (d3 = bz[l], Abs(d3));
00201           if (idx > (float)1e-6) {
00202             goto L6;
00203           }
00204         }
00205       }
00206       /*     cluster',l,'has not been cut */
00207       nn[l - 1] = 1;
00208       nn[k - 1] = 0;
00209       goto L7;
00210     }
00211   L6:
00212     ;
00213   }
00214 
00215   idx = (float)0.;
00216   i1 = *nbbary;
00217   for (k = 1; k <= i1; ++k) {
00218     /* Computing 2nd power */
00219     d1 = ax[k - 1] - bx[k];
00220     /* Computing 2nd power */
00221     d2 = ay[k - 1] - by[k];
00222     /* Computing 2nd power */
00223     d3 = az[k - 1] - bz[k];
00224     id = d1 * d1 + d2 * d2 + d3 * d3;
00225     idx = Max(idx,id);
00226     ax[k - 1] = bx[k];
00227     ay[k - 1] = by[k];
00228     az[k - 1] = bz[k];
00229   }
00230 
00231   d = sqrt(idx);
00232   /*     iteration suivante */
00233   /*     teste pour iteration suivante */
00234   if (d > (sqrt(nbiter) + (float)1.) || vvide) {
00235     if (vvide) {
00236       /*     empty cluster : we iterate */
00237     }
00238     /*     d maximum displacement of the bary centers */
00239     goto L9999;
00240   }
00241   /*     d,'maximum displacement of the bary centers */
00242   return 0;
00243 } 
00244 
00245 /*------------------------------------------------------
00246  *     en entree n points x,y,z 
00247  *     et nbbary = nombre de bary_centres desires 
00248  *     en sortie les nbbary bary_centres trouves  bx,by,bz 
00249  *     chaine(i) pointe sur le bary_centre auquel 
00250  *     le point x(i),y(i),z(i) appartient 
00251  *------------------------------------------------------*/
00252 
00253 static int bblocs(double *x, double *y, double *z, integer *n, double *bx, double *by, double *bz, integer *nbbary, integer *chaine, integer *ierr)
00254 {
00255   /* System generated locals */
00256   integer i1, i2;
00257   double d1, d2;
00258 
00259   /* Local variables */
00260   static integer bmin[256], bmax[256], rang, dmax, kmin, tete[256], 
00261     rmin[256], rmax[256], vmin[256], vmax[256], next, b, i, j, k, m, r,
00262     v, w, itmax, histo[256];
00263   static integer bi, ri, nbbloc, vi, diagon[256], nbbouc;
00264   static int manque;
00265   static integer weight, clasvo[256], icompt;
00266   static double xma, yma, zma;
00267   static integer var;
00268   static double xmi, ymi, zmi;
00269 
00270   --chaine;
00271   --z;
00272   --y;
00273   --x;
00274   --bz;
00275   --by;
00276   --bx;
00277 
00278   /* Function Body */
00279   *ierr = 0;
00280   if (*nbbary > 256) {
00281     /*     le nombre de barycentres demande est trop grand */
00282     *ierr = 1;
00283     return 0;
00284   } else if (*n <= *nbbary) {
00285     i1 = *n;
00286     for (i = 1; i <= i1; ++i) {
00287       bx[i] = x[i];
00288       by[i] = y[i];
00289       bz[i] = z[i];
00290       chaine[i] = i;
00291       /* L204: */
00292     }
00293     i1 = *nbbary;
00294     for (i = *n + 1; i <= i1; ++i) {
00295       bx[i] = (float)0.;
00296       by[i] = (float)0.;
00297       bz[i] = (float)0.;
00298       chaine[i] = i;
00299     }
00300     return 0;
00301   }
00302 
00303   /*     initialisations */
00304   xmi = x[1];
00305   xma = x[1];
00306   ymi = y[1];
00307   yma = y[1];
00308   zmi = z[1];
00309   zma = z[1];
00310 
00311   i1 = *n;
00312   for (i = 1; i <= i1; ++i) {
00313     /* Computing MIN */
00314     d1 = xmi, d2 = x[i];
00315     xmi = Min(d1,d2);
00316     /* Computing MAX */
00317     d1 = xma, d2 = x[i];
00318     xma = Max(d1,d2);
00319     /* Computing MIN */
00320     d1 = ymi, d2 = y[i];
00321     ymi = Min(d1,d2);
00322     /* Computing MAX */
00323     d1 = yma, d2 = y[i];
00324     yma = Max(d1,d2);
00325     /* Computing MIN */
00326     d1 = zmi, d2 = z[i];
00327     zmi = Min(d1,d2);
00328     /* Computing MAX */
00329     d1 = zma, d2 = z[i];
00330     zma = Max(d1,d2);
00331     chaine[i] = i + 1;
00332   }
00333   if (xmi == xma) {
00334     xma += (float)1.;
00335   }
00336   if (ymi == yma) {
00337     yma += (float)1.;
00338   }
00339   if (zmi == zma) {
00340     zma += (float)1.;
00341   }
00342   chaine[*n] = 0;
00343   i1 = *nbbary;
00344   for (i = 1; i <= i1; ++i) {
00345     rmin[i - 1] = 256;
00346     vmin[i - 1] = 256;
00347     bmin[i - 1] = 256;
00348     rmax[i - 1] = 0;
00349     vmax[i - 1] = 0;
00350     bmax[i - 1] = 0;
00351     tete[i - 1] = 0;
00352     bx[i] = 0.;
00353     by[i] = 0.;
00354     bz[i] = 0.;
00355   }
00356   tete[0] = 1;
00357 
00358 /*     recherche et concentration du premier bloc */
00359 /*     initialisation du chainage */
00360 
00361   rmin[0] = 0;
00362   vmin[0] = 0;
00363   bmin[0] = 0;
00364   rmax[0] = 256;
00365   vmax[0] = 256;
00366   bmax[0] = 256;
00367 
00368 /*     recherche du nombre d'iterations a effectuer */
00369 
00370   itmax = 1;
00371   for (i = 1; i <= 9; ++i) {
00372     itmax <<= 1;
00373     if (itmax > *nbbary) {
00374       itmax = i - 1;
00375       goto L31;
00376     }
00377   }
00378   /*     division des blocs en blocs plus petits */
00379   /*     initialisation */
00380 L31:
00381   manque = 1;
00382   nbbloc = 1;
00383   rang = 1;
00384   /*     boucle de division */
00385   i1 = itmax + 1;
00386   for (nbbouc = 1; nbbouc <= i1; ++nbbouc) {
00387     /*     ajustement du nombre de boucles / a une puissance de 2 */
00388   L32:
00389     if (nbbouc > itmax) {
00390       rang = *nbbary - nbbloc;
00391       if (rang <= 0) {
00392         goto L100;
00393       }
00394       /*     classement des rang bary manquants */
00395       i2 = nbbloc;
00396       for (j = 1; j <= i2; ++j) {
00397         diagon[j - 1] = rmax[j - 1] - rmin[j - 1] + (vmax[j - 1] - 
00398                                                      vmin[j - 1]) + (bmax[j - 1] - bmin[j - 1]);
00399         clasvo[j - 1] = j;
00400       }
00401       heapi2(diagon, clasvo, &nbbloc);
00402       manque = 0;
00403     }
00404     m = nbbloc;
00405     i = 0;
00406     icompt = 1;
00407   L60:
00408     if (icompt <= rang) {
00409       if (manque==1) {
00410         ++i;
00411       } else {
00412         if (diagon[m - 1] == 0) {
00413           goto L32;
00414         }
00415         i = clasvo[m - 1];
00416         --m;
00417       }
00418       /*     division du bloc 1 */
00419       /*     recherche de la plus grande dimention */
00420       r = rmax[i - 1] - rmin[i - 1];
00421       v = vmax[i - 1] - vmin[i - 1];
00422       b = bmax[i - 1] - bmin[i - 1];
00423       if (r == 0 && v == 0 && b == 0) {
00424         goto L110;
00425       }
00426       if (r >= v) {
00427         if (r >= b) {
00428           dmax = 1;
00429         } else {
00430           dmax = 3;
00431         }
00432       } else {
00433         if (v >= b) {
00434           dmax = 2;
00435         } else {
00436           dmax = 3;
00437         }
00438       }
00439       weight = 0;
00440       /*     calcul de l'histogramme suivant cette dimention */
00441       for (j = 1; j <= 256; ++j) {
00442         histo[j - 1] = 0;
00443       }
00444       j = tete[i - 1];
00445       switch ((int)dmax) {
00446       case 1:  goto L1;
00447       case 2:  goto L2;
00448       case 3:  goto L3;
00449       }
00450     L1:
00451       if (j != 0) {
00452         ri = (integer) ((x[j] - xmi) * 255 / (xma - xmi) + 1);
00453         ++histo[ri - 1];
00454         ++weight;
00455         j = chaine[j];
00456         goto L1;
00457       }
00458       goto L4;
00459     L2:
00460       if (j != 0) {
00461         vi = (integer) ((y[j] - ymi) * 255 / (yma - ymi) + 1);
00462         ++histo[vi - 1];
00463         ++weight;
00464         j = chaine[j];
00465         goto L2;
00466       }
00467       goto L4;
00468     L3:
00469       if (j != 0) {
00470         bi = (integer) ((z[j] - zmi) * 255 / (zma - zmi) + 1);
00471         ++histo[bi - 1];
00472         ++weight;
00473         j = chaine[j];
00474         goto L3;
00475       }
00476     L4:
00477       /*     division du bloc suivant l'histogramme */
00478       weight /= 2;
00479       switch ((int)dmax) {
00480       case 1:  goto L13;
00481       case 2:  goto L14;
00482       case 3:  goto L15;
00483       }
00484     L13:
00485       k = rmin[i - 1];
00486       goto L16;
00487     L14:
00488       k = vmin[i - 1];
00489       goto L16;
00490     L15:
00491       k = bmin[i - 1];
00492     L16:
00493       kmin = k + 1;
00494       w = 0;
00495     L5:
00496       if (w <= weight) {
00497         ++k;
00498         w += histo[k - 1];
00499         goto L5;
00500       }
00501       if (k <= kmin) {
00502         ++k;
00503       }
00504       /*     reinitialisation des parametres du bloc divise */
00505       rmax[i - 1] = 0;
00506       vmax[i - 1] = 0;
00507       bmax[i - 1] = 0;
00508       rmin[i - 1] = 256;
00509       vmin[i - 1] = 256;
00510       bmin[i - 1] = 256;
00511       ++nbbloc;
00512       /*     mise a jour des chainages */
00513       /*     recompactage des blocs eclates */
00514       j = tete[i - 1];
00515       tete[i - 1] = 0;
00516       tete[nbbloc - 1] = 0;
00517     L6:
00518       if (j != 0) {
00519         next = chaine[j];
00520         ri = (integer) ((x[j] - xmi) * 255 / (xma - xmi));
00521         vi = (integer) ((y[j] - ymi) * 255 / (yma - ymi));
00522         bi = (integer) ((z[j] - zmi) * 255 / (zma - zmi));
00523         switch ((int)dmax) {
00524         case 1:  goto L7;
00525         case 2:  goto L8;
00526         case 3:  goto L9;
00527         }
00528       L7:
00529         var = ri + 1;
00530         goto L11;
00531       L8:
00532         var = vi + 1;
00533         goto L11;
00534       L9:
00535         var = bi + 1;
00536       L11:
00537         if (var >= k) {
00538           chaine[j] = tete[nbbloc - 1];
00539           tete[nbbloc - 1] = j;
00540           /* Computing MAX */
00541           i2 = rmax[nbbloc - 1];
00542           rmax[nbbloc - 1] = Max(i2,ri);
00543           /* Computing MAX */
00544           i2 = vmax[nbbloc - 1];
00545           vmax[nbbloc - 1] = Max(i2,vi);
00546           /* Computing MAX */
00547           i2 = bmax[nbbloc - 1];
00548           bmax[nbbloc - 1] = Max(i2,bi);
00549           /* Computing MIN */
00550           i2 = rmin[nbbloc - 1];
00551           rmin[nbbloc - 1] = Min(i2,ri);
00552           /* Computing MIN */
00553           i2 = vmin[nbbloc - 1];
00554           vmin[nbbloc - 1] = Min(i2,vi);
00555           /* Computing MIN */
00556           i2 = bmin[nbbloc - 1];
00557           bmin[nbbloc - 1] = Min(i2,bi);
00558         } else {
00559           chaine[j] = tete[i - 1];
00560           tete[i - 1] = j;
00561           /* Computing MAX */
00562           i2 = rmax[i - 1];
00563           rmax[i - 1] = Max(i2,ri);
00564           /* Computing MAX */
00565           i2 = vmax[i - 1];
00566           vmax[i - 1] = Max(i2,vi);
00567           /* Computing MAX */
00568           i2 = bmax[i - 1];
00569           bmax[i - 1] = Max(i2,bi);
00570           /* Computing MIN */
00571           i2 = rmin[i - 1];
00572           rmin[i - 1] = Min(i2,ri);
00573           /* Computing MIN */
00574           i2 = vmin[i - 1];
00575           vmin[i - 1] = Min(i2,vi);
00576           /* Computing MIN */
00577           i2 = bmin[i - 1];
00578           bmin[i - 1] = Min(i2,bi);
00579         }
00580         j = next;
00581         goto L6;
00582       }
00583     L110:
00584       ++icompt;
00585       goto L60;
00586     }
00587     rang <<= 1;
00588   }
00589 
00590   /*     calcul des bary_centres */
00591 
00592 L100:
00593   i1 = *nbbary;
00594   for (i = 1; i <= i1; ++i) {
00595     j = tete[i - 1];
00596     weight = 0;
00597   L12:
00598     if (j != 0) {
00599       bx[i] += x[j];
00600       by[i] += y[j];
00601       bz[i] += z[j];
00602       ++weight;
00603       k = j;
00604       j = chaine[j];
00605       chaine[k] = i;
00606       goto L12;
00607     }
00608     bx[i] /= weight;
00609     by[i] /= weight;
00610     bz[i] /= weight;
00611   }
00612   return 0;
00613 } 
00614 
00615 
00616 
00617 
00618 /*------------------------------------------------------
00619  *     trie selon les valeurs de criter croissantes 
00620  *     record suit le reordonnancement 
00621  *------------------------------------------------------*/
00622 
00623 static int heapi2(integer *criter, integer *record, integer *n)
00624 {
00625   static integer crit, i, j, l, r, rec;
00626   --record;
00627   --criter;
00628   if (*n <= 1) return 0;
00629 
00630   l = *n / 2 + 1;
00631   r = *n;
00632  L2:
00633   if (l <= 1)  goto L20;
00634   --l;
00635   rec = record[l];
00636   crit = criter[l];
00637   goto L3;
00638 L20:
00639   rec = record[r];
00640   crit = criter[r];
00641   record[r] = record[1];
00642   criter[r] = criter[1];
00643   --r;
00644   if (r == 1)  goto L999;
00645  L3:
00646   j = l;
00647  L4:
00648   i = j;
00649   j <<= 1;
00650   if (j - r < 0) {
00651     goto L5;
00652   } else if (j == r) {
00653     goto L6;
00654   } else {
00655     goto L8;
00656   }
00657  L5:
00658   if (criter[j] < criter[j + 1]) {
00659     ++j;
00660   }
00661  L6:
00662   if (crit >= criter[j]) {
00663     goto L8;
00664   }
00665   record[i] = record[j];
00666   criter[i] = criter[j];
00667   goto L4;
00668  L8:
00669   record[i] = rec;
00670   criter[i] = crit;
00671   goto L2;
00672 L999:
00673   record[1] = rec;
00674   criter[1] = crit;
00675   return 0;
00676 } 
00677 

Generated on Sun Mar 4 15:03:52 2007 for Scilab [trunk] by  doxygen 1.5.1