Distanza tra due punti generici

di il
2 risposte

Distanza tra due punti generici

Ciao a tutti!!
Mi servirebbe un aiuto in quanto non sono molto pratico di Matlab.
Il mio problema è quello di trovare la distanza tra due punti generici del piano, quindi P1(x1,y1) e P2(x2,y2) con 0<x<1 e 0<y<1 considerando uno step di 0.01 sia per la x che per la y. La funzione distanza è y1+(x2-x1)+y2. Come posso creare un codice che mi calcoli tutte le possibili combinazioni? Considerando che i miei punti iniziali sono 100*100 e i punti di destinazione sono 100*100. Quindi un totale di 100000000 di coppie!!!
Se il calcolo dovesse risultare molto laborioso per Matlab posso sostituire il passo con 0.05.

Grazie mille in anticipo e mi scuso se non sono stato chiaro o se non è la sezione corretta!

Francesco

2 Risposte

  • Re: Distanza tra due punti generici

    Mi spiego meglio. Io ho questi generici punti P1 e P2. Per ogni possibile coppia devo calcolare i tre possibili itinerari con le tre funzioni:

    y1+x2-x1+y2
    x1*tan(alfa)-y1+(x2-x1)/cos(alfa)+x2*tan(alfa)-y2
    2-y1-y2+(x2-x1)

    Per ogni coppia di punti mi servirebbe il valore relativo ad ogni funzione, perchè poi di questi tre valori per coppia devo prendere il minore. Dovrò sommare i minori di ogni coppia e fare il valore medio. Per questo chiedevo come è possibile modificare il codice in modo tale da avere come output i singoli valori.

    Grazie di nuovo!
  • Re: Distanza tra due punti generici

    La difficoltà non sta tanto nella generazione di tutte le possibili combinazioni quanto piuttosto nella enorme quantità di dati e la relativa quantità di RAM utilizzata.

    Bisogna inoltre evitare di usare dei cicli "for" per non rallentare in modo eccessivo i calcoli.

    Una possibile soluzione potrebbe essere generare le varie coppie (cioè le 4 coordinate per ognuno dei due punti esaminati) in "anticipo" e poi utilizzare le tre formule.

    Se ho capito come vuoi create le coppie, considerando, come esempio semplice, due matrici (3 x 3) con valori di x e y pari a (1 2 3), dovresti avere:
    
       1   1   1   1
       1   1   1   2
       1   1   1   3
       1   1   2   1
       1   1   2   2
       1   1   2   3
       1   1   3   1
       1   1   3   2
       1   1   3   3
       1   2   1   1
       1   2   1   2
       1   2   1   3
       1   2   2   1
       1   2   2   2
       1   2   2   3
       1   2   3   1
       1   2   3   2
       1   2   3   3
       1   3   1   1
       1   3   1   2
       1   3   1   3
       1   3   2   1
       1   3   2   2
       1   3   2   3
       1   3   3   1
       1   3   3   2
       1   3   3   3
       2   1   1   1
       2   1   1   2
       2   1   1   3
       2   1   2   1
       2   1   2   2
       2   1   2   3
       2   1   3   1
       2   1   3   2
       2   1   3   3
       2   2   1   1
       2   2   1   2
       2   2   1   3
       2   2   2   1
       2   2   2   2
       2   2   2   3
       2   2   3   1
       2   2   3   2
       2   2   3   3
       2   3   1   1
       2   3   1   2
       2   3   1   3
       2   3   2   1
       2   3   2   2
       2   3   2   3
       2   3   3   1
       2   3   3   2
       2   3   3   3
       3   1   1   1
       3   1   1   2
       3   1   1   3
       3   1   2   1
       3   1   2   2
       3   1   2   3
       3   1   3   1
       3   1   3   2
       3   1   3   3
       3   2   1   1
       3   2   1   2
       3   2   1   3
       3   2   2   1
       3   2   2   2
       3   2   2   3
       3   2   3   1
       3   2   3   2
       3   2   3   3
       3   3   1   1
       3   3   1   2
       3   3   1   3
       3   3   2   1
       3   3   2   2
       3   3   2   3
       3   3   3   1
       3   3   3   2
       3   3   3   3
    
    dove le prime due colonne contengono le x e y della prima serie di punti e la terza e quarta colonna le x e y della seconda serie di punti in modo che ogni riga della matrice rappresenta una coppia di punti.

    Se così è e considerando le formule che vuoi utilizzare per i calcoli, puoi generare separatamente le colonne considerando come, tra di esse si ripetono le sequenze di valori.
    [*] nella quarta colonna si ripete sempre la sequenza completa dei valori possibili; nel caso dell'esempio in questione: 1 2 3 1 2 3 1 2 3 ...
    [*] nella terza colonna, ogni valore della sequenza si ripete tante volte quanti sono i valori possibili della sequenza (in questo caso 3): 1 1 1 2 2 2 3 3 3 ...
    [*] analogamente per la seconda e la prima colonna

    Le sequenze si possono generare, senza utilizzare cicli "for" usando la funzione "repmat".
    A questo punto ci sono due alternative:
    [*] si possono creare le quattro colonne della matrice e poi utilizzare le formule
    [*] creare una colonna alla volta ed calcolare i valori utilizzando ogni formula "in sequenza"

    La prima alternativa consente do avere la matrice a disposizione per poterla esaminare, ma richiede una grande quantità di memoria.
    La seconda alternativa consente di avere tutta la matrice a disposizione, ma solo una colonna alla volta; questo però richiede solo un quarto della memoria rispetto alla prima alternativa.

    Nell'esempio che segue sono state implementate entrambe le alternative ed un flag è stato utilizzato per impedire che la prima venga eseguita nel caso ci siano troppi valori (e venga richiesta troppa memoria - il che potrebbe mandare in crash il sistema) inoltre è stato definito in modo arbitrario il valore di "alfa" (nella domanda non è specificato come venga definito).

    Di seguito, una possibile implementazione.

    DISCLAIMER 1: verifica con attenzione la correttezza dell'implementazione e la correttezza delle coppie create

    DISCLAIMER 2: data la quantità di risorse occupate del codice, non si può escludere che il sistema possa andare in crash e che eventuali dati, documenti o altro vengano persi cosa della quale non mi assumo nessuna responsabilità

    Avendo definito:
    [*] "n" è il numero di valori della sequenza, in questo caso 3 (1 2 3)
    [*] "n_col" è il numero delle colonne della matrice totale delle combinazioni

    
    % Creazione della lista dei valori possibili
    base_val=0.01:.01:1;
    % Numero di vlori della lista
    n=length(base_val);
    % Numero di colonne della matrice delle combinazioni
    n_col=4;
    % Flag di controllo per la verifica dfei risultati
    chk_flg=0;
    % Controllo per evitare che venga eseguita la modalità che richiede maggiore
    % memoria nel caso di sequenze troppo lunghe
    if(n > 60)
       disp('Tropppi valori')
    else
    %   Modalità "estesa": viene creata tutta la matrice
       chk_flg=1;
       % Colonna "y2"
       y2=repmat(base_val,n^0,n^(n_col-1))';
       % Colonna "x2"
       x2=repmat(base_val,n^1,n^(n_col-2));
       x2=x2(:);
       % Colonna "y1"
       y1=repmat(base_val,n^2,n^(n_col-3));
       y1=y1(:);
       % Colonna "x1"
       x1=repmat(base_val,n^3,n^(n_col-4));
       x1=x1(:);
       % Matrice completa, nel caso la si voglia visualizzare
       [x1 y1 x2 y2];
    
       % Prima formula
       printf('Formula 1: y1+x2-x1+y2\n')
       r0=y1+x2-x1+y2;
       % Seconda formula (è stato definito un valore arbitrasrio di alfa)
       printf('\nFormula 2: x1*tan(alfa)-y1+(x2-x1)/cos(alfa)+x2*tan(alfa)-y2\n')
       alfa=pi/4;
       r00=x1*tan(alfa)-y1+(x2-x1)/cos(alfa)+x2*tan(alfa)-y2;
       % Terza formula
       printf('\nFormula 3: 2-y1-y2+(x2-x1)\n')
       r000=2-y1-y2+(x2-x1);
       
    end
    % Modalità compatta
    % Prima formula
    tic
    printf('%s %.0f\n\n','Numero Coppie: ',n^4);
    printf('Formula 1: y1+x2-x1+y2\n')
    % y1
    tmp=repmat(base_val,n^2,n^(n_col-3));
    r1=tmp(:);
    % x2
    tmp=repmat(base_val,n^1,n^(n_col-2));
    r1=r1+tmp(:);
    % x1 
    tmp=repmat(base_val,n^3,n^(n_col-4));
    r1=r1-tmp(:);
    % y2
    tmp=repmat(base_val,n^0,n^(n_col-1))';
    r1=r1+tmp(:);
    toc
    [min_formula_1 idx_1]=min(r1)
    if(~chk_flg)
       clear r1
    end
    
    % Seconda formula
    printf('\nFormula 2: x1*tan(alfa)-y1+(x2-x1)/cos(alfa)+x2*tan(alfa)-y2\n')
    alfa=pi/4;
    tic
    % x1*tan(alfa)
    tmp=repmat(base_val,n^3,n^(n_col-4));
    r2=tmp(:)*tan(alfa);
    % x1*tan(alfa)-y1
    tmp=repmat(base_val,n^2,n^(n_col-3));
    r2=r2-tmp(:);
    % (x2-x1)/cos(alfa)
    tmp=repmat(base_val,n^1,n^(n_col-2));
    tmp1=repmat(base_val,n^3,n^(n_col-4));
    tmp=(tmp(:)-tmp1(:))/cos(alfa);
    r2=r2+tmp;
    % x2*tan(alfa)
    tmp=repmat(base_val,n^1,n^(n_col-2));
    r2=r2+tmp(:)*tan(alfa);
    % y2
    tmp=repmat(base_val,n^0,n^(n_col-1))';
    r2=r2-tmp(:);
    toc
    [min_formula_2 idx_2]=min(r2)
    if(~chk_flg)
       clear r2
    end
    clear tmp1
    
    % Terza formula
    printf('\nFormula 3: 2-y1-y2+(x2-x1)\n')
    tic
    % 2-y1
    tmp=repmat(base_val,n^2,n^(n_col-3));
    r3=2-tmp(:);
    % y2
    tmp=repmat(base_val,n^0,n^(n_col-1))';
    r3=r3-tmp(:);
    % x2
    tmp=repmat(base_val,n^1,n^(n_col-2));
    r3=r3+tmp(:);
    % x1
    tmp=repmat(base_val,n^3,n^(n_col-4));
    r3=r3-tmp(:);
    toc
    [min_formula_3 idx_3]=min(r3)
    if(~chk_flg)
       clear r3
    end
    clear tmp
    
    if(chk_flg)
       [min(min(r0-r1)) max(max(r0-r1))]
       [min(min(r00-r2)) max(max(r00-r2))]
       [min(min(r000-r3)) max(max(r000-r3))]
       clear x1 y1 x2 y2 r0 r00 r000
    end
    
Devi accedere o registrarti per scrivere nel forum
2 risposte