function [raggi punti]=associa2(raggi_1, raggi_2, punti_1, punti_2,epsilon,dim_stanza_x,dim_stanza_y,d_max)
%sfrutto strutture a celle per memorizzare i raggi/telecamere
%raggi saranno in formato cella e ogni cella corrisponde ad una diversa
%telecamera, in questo modo velocizzo il confronto tra i raggi di diverse
%telecamere.

%punti saranno un array con 2 colonne

%epsilon distanza punto retta che identifica il punto

%confronto raggi_1 con punti_2: se raggi-punto vicini scarto il raggio
 

for i=1:length(punti_2(:,1))  %indice che scorre i punti
   if punti_2(i,1)~=-1
    for j=1:length(raggi_1)    %indice che scorre le tecamere
       bound=length(raggi_1{j}(:,1));
       k=1;
       while k<bound+1
         if (distanza_punto_retta(punti_2(i,1:2),raggi_1{j}(k,1:3))<epsilon && distanza_punto_punto(punti_2(i,1:2),[raggi_1{j}(k,4) raggi_1{j}(k,5)]))
           raggi_1{j}=[raggi_1{j}(1:(k-1),:) ; raggi_1{j}((k+1):length(raggi_1{j}(:,1)),:)]; %elimino raggio
           bound=length(raggi_1{j}(:,1)); %avendo eliminato raggio, array più corto e quindi aggiorno il bound
         else
             k=k+1; 
         end
       end
    end
end
end

%confronto raggi_2 con punti_1: 

for i=1:length(punti_1(:,1))  %indice che scorre i punti
     if punti_1(i,1)~=-1
    for j=1:length(raggi_2) %indice che scorre le tecamere
       bound=length(raggi_2{j}(:,1));
       k=1;
       while k<bound+1
         if (distanza_punto_retta(punti_1(i,1:2),raggi_2{j}(k,1:3))<epsilon && distanza_punto_punto(punti_1(i,1:2),[raggi_2{j}(k,4) raggi_2{j}(k,5)]))
           raggi_2{j}=[raggi_2{j}(1:(k-1),:) ; raggi_2{j}((k+1):length(raggi_2{j}(:,1)),:)];                     
           bound=length(raggi_2{j}(:,1));
         else
             k=k+1;
         end
      end 
    end
     end
end

%ricostruisco punti con 2 telecamere di raggi_1 e una di raggi_2

for i=1:(length(raggi_1)-1) %telecamera 1 da raggi_1
    for j=(i+1):length(raggi_1) %telecamera 2 da raggi_1
        for k=1:length(raggi_2)  %telecamera 3 da raggi_2
           bound1=length(raggi_1{i}(:,1)); %numero raggi telecamera 1
           bound2=length(raggi_1{j}(:,1)); %numero raggi telecamera 2           
           bound3=length(raggi_2{k}(:,1)); %numero raggi telecamera 3
           ii=1; %indice raggi telecamera i/1
           while ii<bound1+1
               jj=1; %indice raggi telecamera j/2
               while jj<bound2+1
                   kk=1; %indice raggi telecamera k/3
                   while kk<bound3+1
                       [x y] = min_quad( raggi_1{i}(ii,1:3) ,raggi_1{j}(jj,1:3) ,raggi_2{k}(kk,1:3) ); %calcolo il punto di minima distanza
                       dt1=distanza_punto_punto([x y],[raggi_1{i}(ii,4) raggi_1{i}(ii,5)]);
                       dt2=distanza_punto_punto([x y],[raggi_1{j}(jj,4) raggi_1{j}(jj,5)]);
                       dt3=distanza_punto_punto([x y],[raggi_2{k}(kk,4) raggi_2{k}(kk,5)]);
                       if (x>0 && y>0 && x<dim_stanza_x && y<dim_stanza_y && dt1<=d_max && dt2<=d_max && dt3<=d_max) %controllo che il punto sia valido ovvero interno alla stanza
                         d1=distanza_punto_retta([x y], raggi_1{i}(ii,1:3));  %calcolo distanze punto retta
                         d2=distanza_punto_retta([x y], raggi_1{j}(jj,1:3));
                         d3=distanza_punto_retta([x y], raggi_2{k}(kk,1:3));
                         d=max([d1 d2 d3]); %considero distanza maggiore
                         if  d<epsilon
                            punti_1=[punti_1 ; [x y d]];
                            raggi_1{i}=[raggi_1{i}(1:(ii-1),:) ; raggi_1{i}((ii+1):length(raggi_1{i}(:,1)),:)]; %accorcio i raggi
                            raggi_1{j}=[raggi_1{j}(1:(jj-1),:) ; raggi_1{j}((jj+1):length(raggi_1{j}(:,1)),:)];
                            raggi_2{k}=[raggi_2{k}(1:(kk-1),:) ; raggi_2{k}((kk+1):length(raggi_2{k}(:,1)),:)];
                            bound1=length(raggi_1{i}(:,1)); %aggiorno i bound
                            bound2=length(raggi_1{j}(:,1));            
                            bound3=length(raggi_2{k}(:,1));                          
                            kk=bound3;
                            jj=bound2;
                         end
                       end
                       kk=kk+1;
                   end
                   jj=jj+1;
               end
               ii=ii+1;
           end
        end
    end
end

%ricostruisco punti con 1 telecamere di raggi_1 e 2 di raggi_2


for i=1:(length(raggi_2)-1) %telecamera 1 da raggi_2
    for j=(i+1):length(raggi_2) %telecamera 2 da raggi_2
        for k=1:length(raggi_1)  %telecamera 3 da raggi_1
           bound1=length(raggi_2{i}(:,1));
           bound2=length(raggi_2{j}(:,1));            
           bound3=length(raggi_1{k}(:,1));           
           ii=1; %indice raggi telecamera i
           while ii<bound1+1
              jj=1; %indice raggi telecamera j
               while jj<bound2+1
                   kk=1; %indice raggi telecamera k
                   while kk<bound3+1
                       [x y]=min_quad(raggi_2{i}(ii,1:3),raggi_2{j}(jj,1:3),raggi_1{k}(kk,1:3));
                       dt1=distanza_punto_punto([x y],[raggi_2{i}(ii,4) raggi_2{i}(ii,5)]);
                       dt2=distanza_punto_punto([x y],[raggi_2{j}(jj,4) raggi_2{j}(jj,5)]);
                       dt3=distanza_punto_punto([x y],[raggi_1{k}(kk,4) raggi_1{k}(kk,5)]);
                       if (x>0 && y>0 && x<dim_stanza_x && y<dim_stanza_y && dt1<=d_max && dt2<=d_max && dt3<=d_max)
                         d1=distanza_punto_retta([x y], raggi_2{i}(ii,1:3));
                         d2=distanza_punto_retta([x y], raggi_2{j}(jj,1:3));
                         d3=distanza_punto_retta([x y], raggi_1{k}(kk,1:3));
                         d=max([d1 d2 d3]);
                         if d<epsilon
                            punti_2=[punti_2 ; [x y d]];
                            raggi_2{i}=[raggi_2{i}(1:(ii-1),:) ; raggi_2{i}((ii+1):length(raggi_2{i}(:,1)),:)];
                            raggi_2{j}=[raggi_2{j}(1:(jj-1),:) ; raggi_2{j}((jj+1):length(raggi_2{j}(:,1)),:)];
                            raggi_1{k}=[raggi_1{k}(1:(kk-1),:) ; raggi_1{k}((kk+1):length(raggi_1{k}(:,1)),:)];
                            bound1=length(raggi_2{i}(:,1));
                            bound2=length(raggi_2{j}(:,1));            
                            bound3=length(raggi_1{k}(:,1)); 
                            kk=bound3;
                            jj=bound2;
                         end
                       end
                       kk=kk+1;
                   end
                   jj=jj+1;
               end
               ii=ii+1;
           end
        end
    end
end

%merge raggi e punti

punti=[punti_1 ; punti_2];
raggi=[raggi_1 raggi_2];

