208 lines
4.8 KiB
C
208 lines
4.8 KiB
C
#include "calcul.h"
|
|
|
|
|
|
double distance(Coordonnees const* const a, Coordonnees const* const b)
|
|
{
|
|
const double ratio = PI / 180.0;
|
|
|
|
/* Conversion des latitudes & longitudes en radians */
|
|
const double latA = a->lat * ratio;
|
|
const double latB = b->lat * ratio;
|
|
const double lonA = a->lon * ratio;
|
|
const double lonB = b->lon * ratio;
|
|
|
|
const double arg = sqrt(pow(sin((latA - latB) / 2), 2) + cos(latA) * cos(latB) * pow(sin((lonA - lonB) / 2), 2));
|
|
|
|
return 2 * RAYON * asin(arg);
|
|
|
|
}
|
|
|
|
|
|
void redresserRectangle(sfVector2f *const positionHG, sfVector2f *const positionBD, const bool carre)
|
|
{
|
|
const sfVector2f point1 = *positionHG;
|
|
const sfVector2f point2 = *positionBD;
|
|
|
|
if((point2.x > point1.x) && (point2.y < point1.y))
|
|
{
|
|
positionHG->y = point2.y;
|
|
positionBD->y = point1.y;
|
|
}
|
|
|
|
else if(point2.x < point1.x)
|
|
{
|
|
if(point2.y < point1.y)
|
|
{
|
|
*positionHG = point2;
|
|
*positionBD = point1;
|
|
}
|
|
|
|
else
|
|
{
|
|
positionHG->x = point2.x;
|
|
positionBD->x = point1.x;
|
|
}
|
|
}
|
|
|
|
// Si l'on souhaite avoir un carré à la place d'un rectangle, on récupère la dimension du côté qui est maximale, et on la fixe sur les deux dimensions
|
|
if(carre)
|
|
{
|
|
int32_t moitLongestSide = 0;
|
|
int32_t lAbscisse = positionBD->x - positionHG->x;
|
|
int32_t lOrdonnee = positionBD->y - positionHG->y;
|
|
|
|
if(lAbscisse > lOrdonnee)
|
|
{
|
|
moitLongestSide = lAbscisse/2;
|
|
|
|
positionHG->y = positionHG->y + lOrdonnee/2 - moitLongestSide;
|
|
positionBD->y = positionHG->y + moitLongestSide*2;
|
|
positionBD->x = positionHG->x + moitLongestSide*2;
|
|
|
|
if(positionHG->y < 0)
|
|
{
|
|
positionBD->y = moitLongestSide*2+1;
|
|
positionHG->y = 1;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
moitLongestSide = lOrdonnee/2;
|
|
|
|
positionHG->x = positionHG->x + lAbscisse/2 - moitLongestSide;
|
|
positionBD->x = positionHG->x + moitLongestSide*2;
|
|
positionBD->y = positionHG->y + moitLongestSide*2;
|
|
|
|
if(positionHG->x < 0)
|
|
{
|
|
positionBD->x = moitLongestSide*2+1;
|
|
positionHG->x = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
time_t temps(const Point a, const Point b)
|
|
{
|
|
if(a.date <= b.date)
|
|
return b.date - a.date;
|
|
return a.date - b.date;
|
|
}
|
|
|
|
|
|
double percentPointsInCercle(Point const * const points, const uint32_t taille, Coordonnees const * const centre, const double rayon)
|
|
{
|
|
uint32_t in = 0;
|
|
for(uint32_t i=0;i < taille;i++)
|
|
{
|
|
if(distance(&points[i].pos, centre) <= rayon)
|
|
in++;
|
|
}
|
|
|
|
return 1.0 * in / taille;
|
|
}
|
|
|
|
|
|
void getExtrema(Point const* const pts, uint32_t const taille, Coordonnees *const hautGauche, Coordonnees *const basDroit)
|
|
{
|
|
double lonOuestDroite=-181;
|
|
double lonOuestGauche=1;
|
|
double lonEstDroite=-1;
|
|
double lonEstGauche=181;
|
|
basDroit->lat = 90;
|
|
hautGauche->lat = -90;
|
|
|
|
for(uint32_t i = 0; i < taille; i++)
|
|
{
|
|
if (pts[i].pos.lon < 0)
|
|
{
|
|
if(lonOuestDroite < pts[i].pos.lon)
|
|
{
|
|
lonOuestDroite = pts[i].pos.lon;
|
|
}
|
|
|
|
if(lonOuestGauche > pts[i].pos.lon)
|
|
{
|
|
lonOuestGauche = pts[i].pos.lon;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(lonEstDroite < pts[i].pos.lon)
|
|
{
|
|
lonEstDroite=pts[i].pos.lon;
|
|
}
|
|
|
|
if(lonEstGauche > pts[i].pos.lon)
|
|
{
|
|
lonEstGauche=pts[i].pos.lon;
|
|
}
|
|
}
|
|
|
|
if(basDroit->lat > pts[i].pos.lat)
|
|
{
|
|
basDroit->lat = pts[i].pos.lat;
|
|
}
|
|
|
|
if(hautGauche->lat < pts[i].pos.lat)
|
|
{
|
|
hautGauche->lat = pts[i].pos.lat;
|
|
}
|
|
}
|
|
|
|
if(lonOuestDroite == -181)
|
|
{
|
|
hautGauche->lon = lonEstGauche;
|
|
basDroit->lon = lonEstDroite;
|
|
}
|
|
else if(lonEstGauche == 181)
|
|
{
|
|
hautGauche->lon = lonOuestGauche;
|
|
basDroit->lon = lonOuestDroite;
|
|
}
|
|
else if(360 - lonEstGauche + lonOuestDroite < lonEstDroite - lonOuestGauche)
|
|
{
|
|
hautGauche->lon = lonEstGauche;
|
|
basDroit->lon = lonOuestDroite;
|
|
}
|
|
else
|
|
{
|
|
hautGauche->lon = lonOuestGauche;
|
|
basDroit->lon = lonEstDroite;
|
|
}
|
|
}
|
|
|
|
|
|
inline uint8_t getZoomFromMaxRatio(const double maxRatio)
|
|
{
|
|
int8_t zoom = floor(log2(CONSTANTE / maxRatio) - 1);
|
|
|
|
return (zoom > ZOOMAX ? ZOOMAX : (zoom < ZOOMIN ? ZOOMIN : zoom));
|
|
}
|
|
|
|
|
|
inline double getEchelleFromZoom(const uint8_t zoom)
|
|
{
|
|
return (CONSTANTE / pow(2.0, zoom + 1));
|
|
}
|
|
|
|
|
|
void getZoomEchelle(Carte *const carte)
|
|
{
|
|
/*
|
|
Explications:
|
|
|
|
`carte` pointe sur une structure dont les champs correspondant aux points HG et BD sont remplis et corrects.
|
|
Il "suffit" maintenant de déterminer l'échelle et le zoom les plus adaptés pour cette vue.
|
|
Pour cela on calcule un rapport qui représente la distance maximale qui est à afficher sur notre carte (dont les dimensions sont connues au préalable).
|
|
Ce rapport est directement donné à une des deux fonctions ci-dessus qui détermine le meilleur zoom.
|
|
De ce zoom on en déduit ensuite l'échelle RÉELLE de la carte qui sera téléchargée et affichée.
|
|
*/
|
|
|
|
// Voir calculs (dans le corps des fonctions ci-dessus) pour les deux appels suivants:
|
|
carte->zoom = getZoomFromMaxRatio(distance(&carte->pointHautGauche, &carte->pointBasDroite) * (1 + EXTRADISTANCEPERCENTAGE / 100.0) / (1.0e-2 * MAPSIZE * MAPSCALE / PPCM));
|
|
carte->echelle = getEchelleFromZoom(carte->zoom);
|
|
}
|