Un ami m'a un jour posé la question suivante:
“j'ai une cuve cylindrique horizontale pour le mazout de mon chauffage. Je ne crois plus à l'indication du volume restant, mais je peux facilement mesurer la hauteur du mazout dans la cuve: peux-tu me calculer le volume qui correspond à cette hauteur?”
Et voilà le résultat!
Prenons la section de cette cuve horizontale sur le schéma ci-dessous:
Désolé pour ce dessin à la main, mais je l'ai fait et scannée en 10mn, après avoir cherché pendant 3heures un programme de dessin capable de faire ça. J'ai essayé open-office/dessin, inkscape, photoshop, carbon14 et quelques autres sous Windows et sous Linux… Il manque toujours quelque chose d'élémentaire qui n'existe pas ou qui demande plus d'une 1/2 heure de recherche .
On connait au départ 3 valeurs:
On va supposer que les côtés de la cuve cylindrique sont plats ou peu bombés.
On calcule le rayon:
r = d/2
et la surface totale du cercle:
st = pi*r**2
On calcule l'angle alpha avec l'arc cosinus en connaissant a=r-h et l'hypothénuse r:
alpha = acos((r-h)/r)
On calcule aussi le côté b avec la relation de Pythagore:
b = sqrt(r**2-(r-h)**2)
Il faut ensuite calculer la surface hachurée. Pour cela, on calcule la surface correspondant à l'arc 2*alpha, en fonction de la surface totale st du cercle:
sa = st/(2*pi)*(2*alpha) = st/pi*alpha
Et il faut retrancher de cette surface sa la surface des 2 triangles:
sr = a*b = (r-h)*sqrt(r**2-(r-h)**2)
Ce qui donne pour la surface hachurée:
sh = sa-sr
C'est quasiment fini: le volume cherché correspond au volume totale au prorata des surfaces: surface hachurée / surface totale:
v = vt/st*sh
Maintenant, si la hauteur du liquide dépasse le rayon r de la cuve, le calcul sera différent. Pour éviter de le refaire, on va utiliser l'astuce suivante: si h>r, on va calculer pour h=d-h, ce qui nous ramène au cas précédent, et on va prendre à la fin le complément du volume trouvé: v=vt-v!
Tout cela nous donne le code Python suivant:
#!/usr/bin/python # -*- coding: utf-8 -*- # indispensable pour qu'une division entre 2 entiers donne un résultat décimal! from __future__ import division from math import pi,sqrt,acos def volcuve(h,d,vt): """volcuve(h,d,vt): Calcule le volume restant de liquide d'une cuve cylindique horizontale de diamètre d et de volume total vt""" if h==0: return 0 r=d/2 if h==r: return vt/2 if h==d: return vt if h>r: h=d-h nivhaut=True else: nivhaut=False st=pi*r*r alpha=acos((r-h)/r) sr=(r-h)*sqrt(r*r-(r-h)**2) sa=st/pi*alpha sh=sa-sr v=vt*sh/st if nivhaut: v=vt-v return v # exemples d'utilisation: print volcuve(0,120,3500) # affiche: 0 print volcuve(40,120,3500) # affiche: 1021.26992027 print volcuve(60,120,3500) # affiche: 1750.0 print volcuve(80,120,3500) # affiche: 2478.73007973 print volcuve(100,120,3500) # affiche: 3116.57143452 print volcuve(120,120,3500) # affiche: 3500
Si vous utilisez cette fonction dans une calculatrice, je vous conseille d'ajouter les vérifications des arguments:
Vous pouvez essayer cette fonction dans ma calculatrice en ligne: http://calculext.jpvweb.com