achei isso ae.....e tirando uns errinhos de metragem (que nao eh importante para q eu to fazendo) ficou premera....
Bom eu comecei por aqui e achei que tava no papo (mas não era bem assim)
http://mathforum.org/library/drmath/view/51711.html
e aqui
http://jan.ucc.nau.edu/~cvm/latlon_formula.html
O negocio esbarrou no calculo de acos(x), para x = 0.9999999661
nao vira sem Float 64 bits (pelo menos no keil/arm nao virou)....e como nao tenho o real view fui atras de outros caminhos menos perversos....
Bom, passou natal.....e tals....
Depois fui por aqui (e de quebra achei o projetinho dos caras legal)
http://www.ce.rit.edu/research/projects ... /algos.htm
Depois só pra ver o porque das constantes (que ainda nao entendi...ehehehe)
http://www.meridianworlddata.com/Distan ... lation.asp
E finalmente aqui foi o que mais me agradou
http://www.math.montana.edu/frankw/ccp/ ... /learn.htm
Dai fiz uns testes iniciais e tals ....
Só pra exemplificar eu fiz uma doideira aqui que acho que por hora ta no grau.....depois se for o caso eu otimizo (nao eh objetivo do lance agora)
As declarações
- Código: Selecionar todos
typedef struct _cgps {
byte g;
byte m;
word s;
byte d;
} T_CGPS;
/* Para calculo de distancia */
typedef struct _tdistancia {
byte ativo;
byte valido;
dword dmin;
dword datual;
T_CGPS lat_g;
T_CGPS lon_g;
T_CGPS lat_p;
T_CGPS lon_p;
} T_DISTANCIA;
as constantes
- Código: Selecionar todos
#define GPS_ANTENA_LAT 0
#define GPS_ANTENA_LON 1
#define GPS_PONTO_LAT 2
#define GPS_PONTO_LON 3
- Código: Selecionar todos
/*************************************************************************
* Função
rota_distancia_inicializa
* Parâmetros
distancia - distancia minima de atuação
* Retorno
nenhum
* Descrição
inicializa o calculador de distancia
**************************************************************************/
void rota_distancia_inicializa (dword distancia)
{
app_distancia.ativo = FALSE;
app_distancia.valido = FALSE;
app_distancia.dmin = distancia;
app_distancia.datual = 0;
/* Antena GPS - Latitude */
app_distancia.lat_g.g = 0;
app_distancia.lat_g.m = 0;
app_distancia.lat_g.s = 0;
app_distancia.lat_g.d = 'S';
/* Antena GPS - Longitude */
app_distancia.lon_g.g = 0;
app_distancia.lon_g.m = 0;
app_distancia.lon_g.s = 0;
app_distancia.lon_g.d = 'W';
/* Ponto - Latitude */
app_distancia.lat_p.g = 0;
app_distancia.lat_p.m = 0;
app_distancia.lat_p.s = 0;
app_distancia.lat_p.d = 'S';
/* Ponto - Longitude */
app_distancia.lon_p.g = 0;
app_distancia.lon_p.m = 0;
app_distancia.lon_p.s = 0;
app_distancia.lon_p.d = 'W';
}
/*************************************************************************
* Função
rota_distancia_calcula
* Parâmetros
nenhum
* Retorno
1 - distancia calculada ok, 0 - nao pode calcular
* Descrição
calcula distancia
**************************************************************************/
byte rota_distancia_calcula(void)
{
static double a,b,c,d,x1,x2,y1,y2,z1,z2,pi,dist;
if (!app_distancia.ativo)
return FALSE;
pi = (double) 3.1415926;
/* Processamento do ponto */
// Latitude
a = (double)app_distancia.lat_p.g + ((double)app_distancia.lat_p.m)/60.0 +
((double)app_distancia.lat_p.s)/600000.0;
if (app_distancia.lat_p.d == 'N')
a = 90.0 - a;
else
a = 90.0 + a;
// Longitude
b = (double)app_distancia.lon_p.g + ((double)app_distancia.lon_p.m)/60.0 +
((double)app_distancia.lon_p.s)/600000.0;
if (app_distancia.lon_p.d == 'W')
b = -b;
/* Processamento do gps */
// Latitude
c = (double)app_distancia.lat_g.g + ((double)app_distancia.lat_g.m)/60.0 +
((double)app_distancia.lat_g.s)/600000.0;
if (app_distancia.lat_g.d == 'N')
c = 90.0 - c;
else
c = 90.0 + c;
// Longitude
d = (double)app_distancia.lon_g.g + ((double)app_distancia.lon_g.m)/60.0 +
((double)app_distancia.lon_g.s)/600000.0;
if (app_distancia.lon_g.d == 'W')
d = -d;
x1 = 6367.0*cos(b*pi/180.0)*sin(a*pi/180.0);
y1 = 6367.0*sin(b*pi/180.0)*sin(a*pi/180.0);
z1 = 6367.0*cos(a*pi/180.0);
x2 = 6367.0*cos(d*pi/180.0)*sin(c*pi/180.0);
y2 = 6367.0*sin(d*pi/180.0)*sin(c*pi/180.0);
z2 = 6367.0*cos(c*pi/180.0);
// para medida em mmmmm.cc
app_distancia.datual = floor(100000.0*sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2)));
if (app_distancia.datual < 20000000) {
app_distancia.valido = TRUE;
}
else {
app_distancia.valido = FALSE;
}
return app_distancia.valido;
}
/*************************************************************************
* Função
rota_distancia_ref
* Parâmetros
tipo - tipo da referencia
grau
min
seg
direcao
* Retorno
nenhum
* Descrição
altera parametros de referencia
**************************************************************************/
void rota_distancia_ref(byte tipo, byte g, byte m, word s, byte d)
{
switch (tipo) {
case GPS_ANTENA_LAT:
app_distancia.lat_g.g = g;
app_distancia.lat_g.m = m;
app_distancia.lat_g.s = s;
app_distancia.lat_g.d = d;
break;
case GPS_ANTENA_LON:
app_distancia.lon_g.g = g;
app_distancia.lon_g.m = m;
app_distancia.lon_g.s = s;
app_distancia.lon_g.d = d;
break;
case GPS_PONTO_LAT:
app_distancia.lat_p.g = g;
app_distancia.lat_p.m = m;
app_distancia.lat_p.s = s;
app_distancia.lat_p.d = d;
break;
case GPS_PONTO_LON:
app_distancia.lon_p.g = g;
app_distancia.lon_p.m = m;
app_distancia.lon_p.s = s;
app_distancia.lon_p.d = d;
break;
}
}
Bom vou ver se virou depois ...ainda to escrevendo o mizera do codigo eheheheheh
Thank you for all.