1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
| //
//* main.c
//* test4
//
//* Created by Benoit Castagnetto on 10/02/2016.
//* Copyright © 2016 Benoit Castagnetto. All rights reserved.
//
// Inclusion des bibliothèques
#include <stdlib.h>
#include <stdio.h>
#include <SDL2_image/SDL_image.h>
#include <SDL2/SDL.h>
#include <SDL2_ttf/SDL_ttf.h>
//bibliothèque créée pour contenir les fonctions utiles
#include "fonctions.h"
// on ouvre le main
int main (int argc, char** argv)
{
// Création des tableaux de valeur pour x et y
double tableauAbscisses[10] = {0}, tableauOrdonnees[10] = {0}, tableauDerivees[10] = {0};
// initialisation des valeurs. Dans la version finale elles seront données par l'utilisateur.
double Ca = 0.1, Cb=0.11, Va=5, taille = 10, pas = 1, Ve = 0, pHe = 0;
// on crée les abscisses et les ordonnées à l'aide des fonctions créées
remplirAbscisses(tableauAbscisses, taille, pas);
remplirOrdonnees(tableauAbscisses, tableauOrdonnees, Ca, Cb, Va, taille);
remplirDerivees(tableauDerivees, tableauAbscisses, tableauOrdonnees, taille);
// on détermine et on affiche la valeur du volume et du pH équivalent à l'aide des fonctions créées
Ve = determinationVe(tableauDerivees, tableauAbscisses, taille);
printf("Le volume équivalent est de %lf mL\n",Ve);
pHe = determinationpHe(tableauDerivees, tableauOrdonnees, taille);
printf("Le pH à l'équivalence est de %lf\n",pHe);
/* Création des variables utiles pour le grapHique
largeur et hauteur sont la taille de la fenêtre
echelleX va de 0 à 11 pour le moment et le test, à fixer par l'utilisateur ou à 25 mL ?
echelleY va de 0 à 15 vu que c'est du pH
pixelX-Y sont les mises à l'échelle de la fenêtre des abscisses et ordonnées
posX-Y sont les positions de la fenêtre à l'écran
origine est la position de l'origine des axes
*/
int largeur = 640, hauteur = 480, pixelX = 0, pixelY = 0, pixelDerY = 0, pixelVe = 0, pixelpHe = 0, posX = 400, posY = 100, origine = 30;
double echelleXMin = 0, echelleXMax = 11, echelleYMin = 0, echelleYMax = 15;
// On initialise la SDL et TTF
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
// Création d'un pointeur window pour la fenêtre du graphique
SDL_Window *window = NULL;
window = SDL_CreateWindow("Dosage", posX, posY, largeur, hauteur, SDL_WINDOW_SHOWN);
//Création d'un pointeur renderer pour le graphique
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
// Création de pointeurs pour les surfaces qui vont contenir les annotations
SDL_Surface *textepH = NULL, *texteV = NULL, *textedpHSurdV = NULL, *textepHe = NULL, *texteVe = NULL;
// Création d'un pointeur pour la police, on utilise Times New Roman, lisible et passe partout
TTF_Font *police = NULL;
police = TTF_OpenFont("/Library/Fonts/Times New Roman.ttf", 12);
// On crée les couleurs utiles pour les polices, bleue pour le pH, noire pour V et rouge pour la dpH/dV
SDL_Color couleurNoire = {0, 0, 0};
SDL_Color couleurBleue = {0, 0, 255};
SDL_Color couleurVerte = {0, 255, 0};
SDL_Color couleurRouge = {255, 0, 0};
// On affecte les annotations au pointeur correspondant
textepH = TTF_RenderText_Blended(police, "pH", couleurBleue);
texteV = TTF_RenderText_Blended(police, "V (en mL)", couleurNoire);
textedpHSurdV = TTF_RenderText_Blended(police, "dpH / dV", couleurRouge);
// On prépare l'affichage de la valeur de pHe et Ve sur le graph
// On convertit la valeur de pHe en chaîne de caractère et on garde un chiffre derrière la virgule
char convpHe[1];
sprintf(convpHe, "%.1lf", pHe);
// On crée une chaîne de caractère qui va afficher "pHe = valeur_avec_un_chiffre_derrière_la_virgule" à l'écran
char affichepHe[7];
strcpy(affichepHe, "pHe = ");
strncat( affichepHe, convpHe, 4 );
// On affiche à l'écran la valeur de pHe
textepHe = TTF_RenderText_Blended(police, affichepHe, couleurVerte);
// On convertit la valeur de Ve en chaîne de caractère et on garde un chiffre derrière la virgule
char convVe[1];
sprintf(convVe, "%.1lf", Ve);
// On crée une chaîne de caractère qui va afficher "Ve = valeur_avec_un_chiffre_derrière_la_virgule" à l'écran
char afficheVe[7];
strcpy(afficheVe, "Ve = ");
printf("%s\n", strncat( afficheVe, convVe, 6 ));
// Et on recommence pour ajouter mL : "Ve = valeur_avec_un_chiffre_derrière_la_virgule mL"
char afficheVeFin[4];
strcpy(afficheVeFin, " mL");
printf("%s\n", strncat( afficheVe, afficheVeFin, 3 ));
// On affiche à l'écran la valeur de Ve
texteVe = TTF_RenderText_Blended(police, afficheVe, couleurVerte);
// Instructions à garder sous le coude pour la transparence au cas où
// SDL_SetColorKey(textepH, SDL_TRUE, SDL_MapRGB(textepH->format, 0, 0, 0));
// On crée une texture à partir de textepH
SDL_Texture *texturepH = SDL_CreateTextureFromSurface(renderer, textepH);
SDL_Texture *textureV = SDL_CreateTextureFromSurface(renderer, texteV);
SDL_Texture *texturepHe = SDL_CreateTextureFromSurface(renderer, textepHe);
SDL_Texture *textureVe = SDL_CreateTextureFromSurface(renderer, texteVe);
SDL_Texture *texturedpHSurdV = SDL_CreateTextureFromSurface(renderer, textedpHSurdV);
// On passe en couleur blanche
SDL_SetRenderDrawColor( renderer, 255, 255, 255, 255 );
// Et on passe le renderer avec cette couleur
SDL_RenderClear(renderer);
/* On va maintenant calculer les coordonnées des points à placer sur le grapH
Pour se faire on fait un calcul de proportionnalité
Pour Y, attention car la numérotation commence en haut à gauche de la fenêtre et non en bas à gauche
le -0.5 dans la formule se décompose en fait en -1 + 0.5
Comme le point fait 3x3, ajouter -1 permet de mettre le centre du point sur la valeur voulue et non le coin du point
Comme les nombres sont ici tous positifs et qu'on passe de double à int le +0,5 assure un arrondi correct (car cela se fait systématiquement par défaut)
*/
for(int i=0; i<taille; i++)
{
pixelX = -0.5 + origine + (tableauAbscisses[i] - echelleXMin) / (echelleXMax - echelleXMin) * largeur;
pixelY = -0.5 - origine + hauteur - ((tableauOrdonnees[i] - echelleYMin) / (echelleYMax - echelleYMin) * hauteur);
pixelDerY = -0.5 - origine + hauteur - ((tableauDerivees[i] - echelleYMin) / (echelleYMax - echelleYMin) * hauteur);
// à décommenter en cas de doute pour vérifier que le calcul des pixelX-Y se passe bien
// printf("%d\n",pixelX);
// printf("%d\n",pixelY);
// printf("%d\n",pixelDerY);
//Creation d'un rectangle de 3par3 pour faire le point de coordonnées (pixelX,pixelY) et (pixelX,pixelDerY) sur le grapH
SDL_Rect point = {pixelX, pixelY, 3, 3};
SDL_Rect Derpoint = {pixelX, pixelDerY, 3, 3};;
// On affiche le point de coordonnées(V,pH) en rouge
SDL_SetRenderDrawColor( renderer, 0, 0, 255, 255 );
SDL_RenderFillRect( renderer, &point );
// On affiche le point de coordonnées(V,dpH/dV) en vert
SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );
SDL_RenderFillRect( renderer, &Derpoint );
}
// On crée ici les coordonnées de Ve et pHe à l'échelle du graph. le +0,5 sert à arrondir correctement lors de la conversion de double vers int
pixelVe = 0.5 + origine + (Ve - echelleXMin) / (echelleXMax - echelleXMin) * largeur;
pixelpHe = 0.5 - origine + hauteur - ((pHe - echelleYMin) / (echelleYMax - echelleYMin) * hauteur);
// tracé des axes, on utilise une couleur différente pour chacun
// Noir pour les abscisses V
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255 );
SDL_RenderDrawLine(renderer, 0, hauteur - origine, largeur, hauteur - origine );
// Bleu pour le pH
SDL_SetRenderDrawColor( renderer, 0, 0, 255, 255 );
SDL_RenderDrawLine(renderer, origine, 0, origine, hauteur );
// Rouge pour la dérivée dpH/dV, affiché à droite pour ne pas se superposer avec l'autre axe
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255 );
SDL_RenderDrawLine(renderer, largeur - origine, 0, largeur - origine, hauteur );
// Vert et en pointillé pour le point équivalent.
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255 );
for( int i = 0; i < hauteur; i = i + 4 )
{
SDL_RenderDrawPoint(renderer, pixelVe, i );
};
for( int i = 0; i < largeur; i = i + 4 )
{
SDL_RenderDrawPoint(renderer, i, pixelpHe );
};
// On place le texte à 10 pixel de la droite et 2 du haut avec une largeur de 15 et une hauteur de 15 et aini de suite
SDL_Rect textepH_position = {10, 2, 15, 15};
SDL_Rect texteV_position = {largeur - 85, hauteur - 29, 50, 15};
SDL_Rect textepHe_position = {origine + 5, pixelpHe - 15, 50, 15};
SDL_Rect texteVe_position = {pixelVe, hauteur - 29, 60, 15};
SDL_Rect textedpHSurdV_position = {largeur - 85, 2, 45, 15};
// On copie la texture vers le renderer
SDL_RenderCopy(renderer, texturepH, NULL, &textepH_position);
SDL_RenderCopy(renderer, textureV, NULL, &texteV_position);
SDL_RenderCopy(renderer, texturepHe, NULL, &textepHe_position);
SDL_RenderCopy(renderer, textureVe, NULL, &texteVe_position);
SDL_RenderCopy(renderer, texturedpHSurdV, NULL, &textedpHSurdV_position);
// On met à jour l'affichage
SDL_RenderPresent(renderer);
// On bloque la fenêtre à l'aide d'un event
while (1) {
SDL_Event e;
if (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
break;
}
}
}
// On ferme tout proprement
SDL_FreeSurface(textepH);
SDL_FreeSurface(texteV);
SDL_FreeSurface(textepHe);
SDL_FreeSurface(texteVe);
SDL_FreeSurface(textedpHSurdV);
TTF_CloseFont(police);
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
} |
Partager