#!/usr/bin/env python # -*- coding: utf-8 -*- # *************************************************************************** # * Copyright (C) 2012, Paul Lutus * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU General Public License as published by * # * the Free Software Foundation; either version 2 of the License, or * # * (at your option) any later version. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU General Public License for more details. * # * * # * You should have received a copy of the GNU General Public License * # * along with this program; if not, write to the * # * Free Software Foundation, Inc., * # * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * # *************************************************************************** import sys from math import * # area of unit radius circle section at height y, 0 <= y <= 2 def fa(y): y -= 1 return sqrt(1-y*y) * y + acos(-y) # root finder for above function using binary search def fy(a): epsilon = 1e-7 y = 1 dy = 1 while(abs(dy) > epsilon): da = fa(y) dy *= 0.5 y += (dy,-dy)[da>a] return y # print formatter def format(y,tv,fvol): return '%.4f,%.4f,%.4f' % (y,tv,tv * 100.0/fvol) def help(): print('Usage: [-i(nverse mode)] (tank height) (tank width) (tank length) (table step size) [(conversion factor)]') print(' Conversion factors: cm³ -> liters: 1000, in³ -> gallons: 231') args = sys.argv args.pop(0) if(len(args) < 4): help() else: inverse_mode = args[0] == '-i' if(inverse_mode): args.pop(0) if(len(args) < 4): help() else: # th = tank height # tw = tank width # tl = tank length # ss = step size th,tw,tl,ss = [float(x) for x in args[:4]] args = args[4:] # default: no volume conversion vc = 1 # if a conversion factor is present if(len(args) > 0): # use it vc = float(args[0]) # r = tank radius r = th / 2.0 # wr = tank width/height ratio wr = tw/th # av = unit circle partial area to tank volume term av = r * r * wr * tl / vc # fv = full tank volume fv = pi * av if(inverse_mode): # volume to height mode print('Volume,Height,%') fs = format(fv,th,th) # v = tank partial volume v = 0 # while volume <= full volume while(v <= fv): # compute height for this volume y = fy(v/av) * r s = format(v,y,th) print(s) v += ss else: # height to volume mode print('Height,Volume,%') fs = format(th,fv,fv) # y = tank sensor height y = 0 # while height <= tank height while(y <= th): # compute volume for this height v = fa(y/r) * av s = format(y,v,fv) print(s) y += ss # print 100% value if not already printed if(s != fs): print fs