public class Analyse
{
     private Random zufall = new Random(System.currentTimeMillis());
  
     double[][] xy_stamm;
  
     public int[] ringzugehoerigkeit;

     public boolean[] offen;
  
     public Analyse(int MAXPARTIKEL)
     {
          ringzugehoerigkeit = new int[MAXPARTIKEL];
          offen = new boolean[MAXPARTIKEL];
     }

     //Bestimmt, zu welchem Ring das aktuelle Element driften sollte
     
     private double[] harmonisierungsgrad = new double[N_PULSE];
     
     public int berechneZielring(int nr,double[] yyalt)
     {
          //1. Welche Frequenz hat das aktuell angefragte Element?
          int f = frequenzen[nr%16];
          double x = yyalt[nr*6+0];
          double y = yyalt[nr*6+2];
          double z = yyalt[nr*6+4];
          //2. Harmonisierungsgrad mit jedem Ring abhängig auch von der Distanz in Z-Richtung der zugehörigen Elemente:
          for(int i=0;i<harmonisierungsgrad.length;i++)
          {
              harmonisierungsgrad[i]=0.0;
              int ANZ=0;
              for(int k=0;k<ringzugehoerigkeit.length;k++)
              {
                   if(k!=nr && ringzugehoerigkeit[k]==i+1) //0==Mitte !!!
                   {
                        int f2 = frequenzen[k%16]; 
                        for(int q=0;q<harmonisch.length;q++)
                        {
                            if( (f*harmonisch[q][0]==f2*harmonisch[q][1] || f*harmonisch[q][1]==f2*harmonisch[q][0]) && offen[k]==true)
                            {
                                harmonisierungsgrad[i]+=1.0*(1.0/(1.0+Math.abs(yyalt[k*6+4]))); //je weiter weg, desto unwichtiger
                                ANZ++;
                                break;
                            }
                        }
                   }
              }
              harmonisierungsgrad[i]/=(1.0+(double)ANZ*(double)ANZ);              
          }    
          
          int zielring = 0;
          double hmax = 0.0;
          
          for(int i=0;i<harmonisierungsgrad.length;i++)
          {
//              if(harmonisierungsgrad[i]>=hmax)
              if(i!=nr && harmonisierungsgrad[i]>=hmax)  //dadurch dauern bewegung!
              {
                  zielring = i+1;
                  hmax = harmonisierungsgrad[i];
              }
          }

//          if(zufall.nextInt(100)<5)
//              return (ringzugehoerigkeit[nr]+zufall.nextInt(N_PULSE-1))%(N_PULSE-1)+1;
          
          return zielring;
     }

     public int berechneZielringNEGATIV(int nr,double[] yyalt)
     {
          //1. Welche Frequenz hat das aktuell angefragte Element?
          int f = frequenzen[nr%16];
          double x = yyalt[nr*6+0];
          double y = yyalt[nr*6+2];
          double z = yyalt[nr*6+4];
          //2. Harmonisierungsgrad mit jedem Ring abhängig auch von der Distanz in Z-Richtung der zugehörigen Elemente:
          for(int i=0;i<harmonisierungsgrad.length;i++)
          {
              harmonisierungsgrad[i]=0.0;
              int ANZ=0;              
              for(int k=0;k<ringzugehoerigkeit.length;k++)
              {
                   if(k!=nr && ringzugehoerigkeit[k]==i+1) //0==Mitte !!!
                   {
                        int f2 = frequenzen[k%16]; 
                        for(int q=0;q<harmonisch.length;q++)
                        {
                            if(f*harmonisch[q][0]==f2*harmonisch[q][1] || f*harmonisch[q][1]==f2*harmonisch[q][0] && offen[k]==true)
                            {
                                //if(offen[k]==true)
                                    harmonisierungsgrad[i]+=1.0*(1.0/(1.0+Math.abs(yyalt[k*6+4]))); //je weiter weg, desto unwichtiger
                                    ANZ++;
                                break;
                            }
                        }
                   }
              }
              harmonisierungsgrad[i]/=(1.0+(double)ANZ*(double)ANZ);
          }    
          
          int zielring = 0;
          double hmax = 0.0;
          
          for(int i=0;i<harmonisierungsgrad.length;i++)
          {
              if(harmonisierungsgrad[i]<=hmax)
              {
                  zielring = i+1;
                  hmax = harmonisierungsgrad[i];
              }
          }

          
//          if(zufall.nextInt(100)<5)
//              return (ringzugehoerigkeit[nr]+zufall.nextInt(N_PULSE-1))%(N_PULSE-1)+1;
          
          return zielring;
     }
     
     
     public void aktualisiereRingzugehoerigkeit(double[] yyalt, int N_PULSE, double VSCHALL)
     {
           double RINGDISTANZ = VSCHALL/(double)N_PULSE;
           //herausfinden, zu welchem Ring aktuell jeder der Töne gehört:
           for(int i=0;i<ringzugehoerigkeit.length;i++)
           {
               double dist = Math.sqrt(  yyalt[i*6+0]*yyalt[i*6+0] + yyalt[i*6+2]*yyalt[i*6+2]  );  //x*x+y*y
               ringzugehoerigkeit[i] = 0; //Mitte
               for(int p=0;p<N_PULSE;p++)
               {
                   if(dist > 0.5*RINGDISTANZ + (double)p*RINGDISTANZ)
                   {
                       ringzugehoerigkeit[i] = p+1;
                   }
               }
           }
     }
     
     public void setzeStammposition(double[] yyalt)
     {
           xy_stamm = new double[yyalt.length/6][2];
           for(int i=0;i<xy_stamm.length;i++)
           {
               xy_stamm[i][0] = yyalt[i*6+0];
               xy_stamm[i][1] = yyalt[i*6+2];
           }
     }
}
