211 lines
4.9 KiB
C
211 lines
4.9 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 getZoomFromEchelle(const double echelle)
|
|
{
|
|
int8_t zoom = floor(log2(CONSTANTE / (echelle)) - 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)
|
|
{
|
|
const double distLat = distance(&(Coordonnees){carte->pointHautGauche.lat,0},&(Coordonnees){carte->pointBasDroite.lat,0});
|
|
const double distLon = distance(&(Coordonnees){0,carte->pointHautGauche.lon},&(Coordonnees){0,carte->pointCentral.lon}) + distance(&(Coordonnees){0,carte->pointCentral.lon},&(Coordonnees){0,carte->pointBasDroite.lon});
|
|
|
|
|
|
// Calcul de la distance maximum entre les points les plus éloignés, que l'on devra
|
|
// pouvoir être en mesure d'afficher
|
|
const double distanceMaximale = distLat > distLon ? distLat : distLon;
|
|
|
|
// L'échelle faisant correspondre la taille de la carte à la réalité voulue
|
|
carte->echelle = (distanceMaximale + 1.0e-2 * BORDERSIZE / PPCM) / (1.0e-2 * MAPSIZE * MAPSCALE / PPCM);
|
|
|
|
// Partie entière du zoom à cause de l'API google maps.
|
|
carte->zoom = getZoomFromEchelle(carte->echelle);
|
|
|
|
// L'échelle de la carte avec le zoom arrondi.
|
|
carte->echelle = getEchelleFromZoom(carte->zoom);
|
|
}
|