This repository has been archived on 2023-11-03. You can view files and clone it, but cannot push or open issues or pull requests.
GINPA/Modele/calcul.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);
}