Programmation en C: Série 3

Exercice 1: Machine de tri

Pour trier des granulats par taille, on utilise des cribles. Ces cribles ne font pas un tri parfait, et on aimerait modéliser cela.

A. Crible simple

Nous modélisons notre granulat avec 3 tailles (petit, moyen, grand), et le crible comme suit:

Crible A

Complétez le code suivant:

			#include <stdio.h>

			struct Granulat {
				double petit;
				double moyen;
				double grand;
			};

			void cribleA(struct Granulat * entree, struct Granulat * sortie, struct Granulat * reste) {
				...
			}

			void afficher(char * nomSortie, struct Granulat * granulat) {
				...
			}

			int main(int argc, char * argv[]) {
				struct Granulat entree = {80, 50, 10};
				struct Granulat sortieA;
				struct Granulat sortieB;

				cribleA(&entree, &sortieA, &sortieB);

				afficher("Sortie A", &sortieA);
				afficher("Sortie B", &sortieB);
				return 0;
			}
		

Système à deux cribles

Ajoutez un crible B qui traite ce qui reste du crible A. Le crible B sépare

			#load solutions/crible.c
		
               petit       moyen       grand
Sortie A       4.0 t       4.0 t      10.0 t
Sortie B      11.4 t      46.0 t       0.0 t
Sortie C      64.6 t       0.0 t       0.0 t

Exercice 2: Trajectoire GPS

Dans cet exercice, on traite des trajectoires GPS. Une telle trajectoire est une liste de coordonnées GPS, dont chaque coordonnée a

A. La structure GpsPoint

Déclarez une struct GpsPoint {...}; pour une coordonnée GPS.

B. Afficher une coordonnée GPS

Ecrivez une fonction void afficher(struct GpsPoint * point) {...} qui affiche une coordonnée GPS. Vous pouvez tester votre fonction en l'appelant comme suit:

			struct GpsPoint point = {45.97639, 7.65833, 4478};
			afficher(&point);
		

C. Lire une ligne

Ecrivez une fonction int lireLigne(char * ligne, struct GpsPoint * point) {...} qui extrait une coordonnée d'une chaine de caractères comme la suivante:

46.94396000,6.718970000,1117.0

Les valeurs (latitude en degrés, longitude en degrés, altitude en m) sont séparées par des virgules.

Si la ligne est valide, votre fonction doit remplir la structure point et retourner 1. Sinon, la fonction doit retourner 0 pour indiquer que le ligne n'est pas valide.

			#load solutions/track-ABC.c
		
 45.97639   7.65833   4478
 46.94396   6.71897   1117

D. Lire un fichier entier

Ajoutez la fonction suivante à votre code:

			int lireFichier(char * nomFichier, struct GpsPoint * tableauARemplir, int longueur) {
				// Ouvrir le fichier
				FILE * file = fopen(nomFichier, "r");
				if (file == NULL) return -1;

				// Lire ligne par ligne
				int ligne = 0;
				char buffer[100];
				while (fgets(buffer, 100, file) != NULL) {
					if (ligne >= longueur) return ligne;
					int ok = lireLigne(buffer, tableauARemplir + ligne);
					if (ok) ligne = ligne + 1;
				}

				// Fermer le fichier et retourner le nombre de lignes lues
				fclose(file);
				return ligne;
			}
		

Cette fonction appelle votre fonction lireLigne, et s'utilise comme suit:

			struct GpsPoint points[1000];
			int nbPoints = lireFichier("nom-du-fichier.csv", points, 1000);

			// nbPoints contient le nombre de points,
			// ou -1 si le fichier n'existe pas
		

Vous pouvez tester votre programme avec une de ces trois trajectoires:

E. Afficher quelques points

Affichez les 10 premiers points de la trajectoire.

F. Différence d'altitude

Calculez et affichez la différence entre l'altitude de départ et celle de l'arrivée.

G. Montée

Calculez la montée totale. Pour cela, on ne considère que les segments de la trajectoire qui montent.

#load solutions/track-DEFG.c
Les 10 premiers points (de 755 points)
 46.02541   7.48111   2012
 46.02541   7.48113   2011
 46.02576   7.48123   2011
 46.02578   7.48117   2012
 46.02577   7.48102   2015
 46.02571   7.48095   2016
 46.02548   7.48085   2018
 46.02531   7.48088   2018
 46.02509   7.48100   2016
 46.02502   7.48100   2017
Différence d'altitude: 451 m
Montée: 1304 m

H. Convertir en XYZ

Transformez chaque coordonnée GPS en coordonnées cartésiennes. Si on admet que la terre est une sphère de rayon rterre = 6378100 m, on peut utiliser les equations suivantes:

Transformée GPS -> XYZ

Notez que sin et cos de math.h prennent des valeurs en radians.

I. Distance totale

A l'aide des coordonnées cartésiennes, calculez la distance totale de la trajectoire.

J. Pente maximale

Calculez la pente (Δ altitude / distance) de chaque segment de la trajectoire, et affichez la pente maximale.

#load solutions/track-HIJ.c
Distance totale: 14383 m
Pente maximale: 56 %
#load solutions/track-HIJ-struct.c
Distance totale: 14383 m
Pente maximale: 56 %