Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 24

Discussione: calcolo distanza

  1. #1

    calcolo distanza

    Salve a tutti, è un po' di tempo che sto cercando di capire come fare a calcolare la distanza tra 2 punti presi con il gps.
    Fino ad adesso ho usato la formula di harvesine e funziona:
    Codice PHP:
    function getDistanceBetweenPointsNew($latitude1$longitude1$latitude2$longitude2) {
      
    $earth_radius  3960.00;
      
    $delta_lat $latitude2 $latitude1 ;
      
    $delta_lon $longitude2 $longitude1 ;
      
    $alpha     $delta_lat/;
      
    $beta      $delta_lon/;
     
      
    $a        sin(deg2rad($alpha)) * sin(deg2rad($alpha)) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin(deg2rad($beta)) * sin(deg2rad($beta)) ;
      
    $c        asin(min(1sqrt($a)));
      
    $distance 2*$earth_radius $c;
      
    $distance round($distance4);
      
    $distance $distance*1.609344;
      return 
    $distance;


    Mi chiedevo però se tale formula tiene in considerazione l'altezza dei punti visto che io le passo solo lat e long, mi spiego meglio:

    Prendo il gps e registro un punto al livello del mare, poi prendo una cabinovia ed arrivo a 2000 metri e registro l'altro punto.
    Se la formula che uso non tiene conto dell'altezza tra i 2 punti ci sarà una distanza pari al cateto minore del triangolo (300) sotto e questa non è la reale distanza, quella reale sarebbe l'ipotenusa del triangolo.

    codice:
    2|\
    0| \
    0|  \
    0|   \
     |____\    
       300 metri
    Tutte le formule che trovo in rete per il calcolo della distanza considerano solo latitudine e longitudine, esiste una formula che tiene conto anche dell'altezza? Ho trovato un abbozzo ma manca il raggio medio terrestre e non saprei come applicarla con latitudine longitudine ed altezza:
    Codice PHP:

    = (longlatalt)

    we calculate the equivalent Cartesian coordinates

    = (xyz)

    as 
    followswhere the asterisk denotes multiplication.

     
    alt cos(lat) * sin(long)
     
    alt sin(lat)
     
    alt cos(lat) * cos(long)

    Nowgiven a pair of points

     p0 
    = (x0y0z0)
     
    p1 = (x1y1z1)

    dist sqrt( (x1-x0)^+ (y1-y0)^+ (z1-z0)^
    mi dareste una mano?

  2. #2
    Ho trovato su internet il modo per convertire latitudine longitudine ed altitudine in x,y e z in modo da applicare la formula: dist = sqrt( (x1-x0)^2 + (y1-y0)^2 + (z1-z0)^2 )

    Qualcuno mi può tradurre in php la formula per convertire la y?:

    codice:
    x (in m) = Latitude  * 60 * 1852 
        
    y (in m) =  (PI/180) * cos(Longitude) * ( 637813.7^2 / sqrt( (637813.7 * cos(Longitude))^2 + (635675.23 * sin(Longitude))^2 ) ) 
      
    z (in m) = Altitude (in m)

  3. #3
    Utente di HTML.it L'avatar di bubi1
    Registrato dal
    Dec 2009
    Messaggi
    1,230
    1. Quello che hai trovato, e' un sistema per mappare le coordinate geografiche su un sistema catesiano ECEF. Non ti conviene, se cominci a guardare ecef e poi devi tornare al wgs84 non ne esci piu' vivo
    2. Il metodo basato sull'emisenoverso (harvesine) e' poco preciso.
    3. E' sbagliato calcolare in miglia e poi convertire in km - diventa ancora meno preciso per via degli arrotondamenti.
    4. In alternativa a harvesine, l'ideale e' di usare la formula di Vincenty. Ma e' abbastanza difficile per principianti, potresti incorrere in problemi che non saresti in grado di risovere. Quindi ti posto una mia vecchia funzione basata sulla legge sferica dei coseni - e' abbastanza precisa per la maggiorparte dei compiti normali (margine di errore intorno a 0.01%) - e restituisce il risultato in km.
    Codice PHP:
    function geo_dist($lat1,$long1,$lat2,$long2){
            list(
    $lat1,$long1,$lat2,$long2) = array_map("deg2rad",func_get_args());
            return 
    acos(sin($lat1)*sin($lat2) + cos($lat1)*cos($lat2)*cos($long2-$long1))*6378.137;

    6378.137 e' il raggio nel sistema wgs84, che e' considerato il modello piu' esatto applicabile globalmente.
    5. Se vuoi un valore ancora piu' preciso (ma sempre senza usare Vicenty) - devi tenere in considerazione che la terra non e' perfettamente sferica, quindi a latitudini diverse, il raggio sara' diverso. Quindi al posto del valore fisso 6378.137 puoi usare il risultato di questa funzione che restituisce il raggio medio tra due latitudini:
    Codice PHP:
    function get_radius($lat1,$lat2){
            list(
    $lat1,$lat2) = array_map("deg2rad",func_get_args());
            
    $r_eq 6378.137;//raggio equatoriale
            
    $r_pl 6356.7523;//raggio polare
            
    return $r_eq + ($r_pl $r_eq) * ($lat1 $lat2)/M_PI;

    6. Nota: mai confondere l'altezza al livello del mare con l'altezza al livello dell'elisse di riferimento (controllare a che altezza si riferisce il dispositivo gps).
    7. Per calcolare la distanza, tenendo conto dell'altezza, se la distanza tra i 2 punti e' abbastanza piccola in modo da ignorare la curvatura terrestre (come nel caso della funivia) basta semplicemente immaginare un triangolo retto con il primo cateto = distanza, il secondo = differenza tra le elevazioni, e l'angolo = 90.
    Applicando semplicemente il teorema di pitagora risali alla distanza dell'ipotenusa (che e' quella che serve a te, ed e' questa):
    Codice PHP:
     $distanza hypot($distanza_geo,abs($altezza_p1-$altezza_p2)); 
    8. Per calcolare la distanza, tenendo conto sia dell'altezza che della curvatura terrestre, devi mmaginare un triangolo isoscele, con la punta il centro del cerchio (terra), e le altre 2 sono i nostri punti geografici ad altezza 0. Conoscendo la lunghezza dell'arco, puoi calcolare l'angolo tra i due lati (angolo centrale), e con quest'ultimo calcolare il terzo lato, che e' la distanza che ci interessa, che e' la corda che prenderemo come valore per l'ipotenusa del triangolo di cui ho parlato al punto sopra. E poi basta fare la stessa cosa come sopra.
    La mia funzione e' questa:
    Codice PHP:
    function geo_dist_alt($dist,$alt1,$alt2){
            
    $central_angle deg2rad((180*$dist)/(M_PI*6378.137)); //dedotto dalla formula arco= (angolo / 180 gradi) * pi * r
            //e' una formula per calcolare l'arco in una circonferenza, ma il margine di errore viene abbassato se si usa il raggio calcolato in base alla latitudine
            
    $chord 2*6378.137*sin($central_angle/2);//teorema dei coseni
            
    return hypot($chord,abs($alt1-$alt2));

    - ma ha veramente senso di usarla solo se si tratta di centinaia di km, tanto dislivello, e serve tanta precisione.

  4. #4
    Non potevo chieder euna risposta migliore, grazie!!
    Diciamo che mi potrebbe bastare la penultima formula ma per curiosità vorrei provare anche l'ultima, da dove estrapolo il $dist di function geo_dist_alt($dist,$alt1,$alt2){ ?
    dal risultato della prima funzione?

  5. #5
    Utente di HTML.it L'avatar di bubi1
    Registrato dal
    Dec 2009
    Messaggi
    1,230
    dalla prima

    $dist e' la distanza dal punto a al punto b sul'ellisse terrestre, che e' una curva. L'ultima funzione non fa altro che calcolare la linea retta dal a al b, in base alla lunghezza della curva ed il raggio equatoriale, e poi usando questa linea come catete, applica il pitagora.
    Ma non ti consiglierei di usarla, ci sono molti casi quando e' imprecisa. Quella funzione va benissimo solo se si tratta di misurazioni geodesiche su aree dove dal punto a al punto b si puo' tracciare una retta senza toccare l'elisse di riferimento. Per intenderci: Ponte di Legno - Milano si, Lhasa - New York assolutamente no. Quindi quando la distanza e' ne troppo corta ne troppo lunga e serve precisione metrica.

    Cmq, tutti i calcoli dipendono da cosa stiamo misurando. Se un volo d'aereo, bisogna tener conto dell'altitudine del volo, se e' costante o no, delle curva per prendere quota e per atterrare, dalla distanza, etc.
    Se e' per calcolare una distanza di volo indicativa tra 2 citta', normalmente si applica una delle formule tipo harvesine, coseni, vincenty etc senza contare il dislivello.
    Se e' per un ponte radio, data la copertura relativemente piccola e l'importanza della distanza reale, allora si usano le altitudini e pitagora.
    Se e' per un percorso a piedi/in macchina, si prende il gps e si fa il percorso

  6. #6
    beh quello che dovrei fare è proprio misurare la distanza di un percorso a piedi ottenuto col gps...

    mi restituisce un errore la prima formula: Fatal error: func_get_args(): Can't be used as a function parameter perchè?

  7. #7
    Utente di HTML.it L'avatar di bubi1
    Registrato dal
    Dec 2009
    Messaggi
    1,230
    argh, e' perche' ho usato una sintassi 5.3.0, dimenticando che prima non era possibile usare func_get_args come parametro

    sostituisci
    list($lat1,$long1,$lat2,$long2) = array_map("deg2rad",func_get_args());
    con
    $params = func_get_args();
    list($lat1,$long1,$lat2,$long2) = array_map("deg2rad",$params);

    e fai lo stesso adeguamento anche nella funzione per il raggio medio se la usi.


    Per quanto riguarda il percorso a piedi, spero che hai gia' preso in considerazione il fatto che ci possono essere ostacoli di vario genere e che il percorso non e' sempre retto

    Ps: e per percorsi a piedi puoi ignorare completamente i discorsi sulla curvatura terrestre. Ricordati anche che tutte le dimensioni (distanze, altezze) sono in km, quindi se devi passare l'altezza di 350metri saranno 0.35 km

  8. #8
    consiglio anche la lettura di questo, magari aiuta: http://www.movable-type.co.uk/script...-vincenty.html (in fondo alla pagina c'è un po di codice)
    Administrator of NAMDesign.Net

  9. #9
    grazie ancora, ho provato tutte le formule che mi hai dato + quelle che avevo io, ottengo con tutte + o meno lo stesso risultato.

    l'unica che non mi va è l'ultima ed ho provato così:
    Codice PHP:

    $latitude1 
    '41.756192';
    $longitude1 '87.967360';
    $altitude1'192';

    $latitude2 '41.758701';
    $longitude2 '87.973307';
    $altitude2'198';


    function 
    geo_dist($latitude1,$longitude1,$latitude2,$longitude2){ 

    $params func_get_args();
    list(
    $latitude1,$longitude1,$latitude2,$longitude2) = array_map("deg2rad",$params);
    return 
    acos(sin($latitude1)*sin($latitude2) + cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6378.137
    }
    $distanzageo_dist($latitude1,$longitude1,$latitude2,$longitude2);

    //passo distanza alla funzione che mi considera anche le altezze:

    function geo_dist_alt($distanza,$altitude1,$altitude2){ 
            
    $central_angle deg2rad((180*$distanza)/(M_PI*6378.137)); //dedotto dalla formula arco= (angolo / 180 gradi) * pi * r 
            //e' una formula per calcolare l'arco in una circonferenza, ma il margine di errore viene abbassato se si usa il raggio calcolato in base alla latitudine 
            
    $chord 2*6378.137*sin($central_angle/2);//teorema dei coseni 
            
    return hypot($chord,abs($altitude1-$altitude2)); 
    }
    $distanza2geo_dist_alt($distanza,$altitude1,$altitude2);
    echo 
    $distanza2
    Le altre tornano tutte intorno ai 266 metri.
    Le differenze grandi le ho solo usando quelle che mi calcolano anche le altezze (se le modifico) ed è giusto!

    adesso mi chiedo però perchè se uplodo il mio tracciato su trailguru.com mi dice che il mio tracciato è lungo 3,49 km quando con le formule mie ottengo da 3,7 a 3,8 a seconda se calcolo anche l'altezza o meno, e la cosa che + mi fa rabbia è che il mio gps è d'accordo con trailguru!

  10. #10
    Utente di HTML.it L'avatar di bubi1
    Registrato dal
    Dec 2009
    Messaggi
    1,230
    $latitude1 = '41.756192';
    $longitude1 = '87.967360';
    $altitude1= '192';

    $latitude2 = '41.758701';
    $longitude2 = '87.973307';
    $altitude2= '198';
    Ma ti avevo detto sopra che dovevi passare tutte le misure in km.. quindi 0.192 e 0.198.
    Cmq, la distanza tra questi 2 punti, calcolata con harvesine ti deve dare 566mt, con i coseni o vincenty 567.

    E poi, su un dislivello di 6 metri, la differenza tra la distanza geo e la distanza che tiene conto dell'altitudine sara' di 50cm, quindi trascurabile
    E su queste distanze, applicare anche quella che tiene conto della curvatura terrestre ti dara' una differenza nell'ordine dei centesimi di millimetri.

    Posta anche le coordinate del tuo percorso, vedremo se hai fatto bene i calcoli

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.