posts:node: Add a post on Node and npm
[blog.git] / posts / clickloc / scale_click.py
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2010-2012 W. Trevor King <wking@drexel.edu>
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this program.  If not, see
17 # <http://www.gnu.org/licenses/>.
18
19
20 """Convert `clickloc.tk` pixel coordinates to physical coordinates
21 """
22
23 from math import exp, log
24
25
26 __version__ = '0.2'
27
28
29 if __name__ == '__main__':
30     from argparse import ArgumentParser
31
32     parser = ArgumentParser(description=__doc__, version=__version__)
33     parser.add_argument(
34         '-x', '--logx', default=False, action='store_const', const=True,
35         help='Use a log scale for the physical abscissa')
36     parser.add_argument(
37         '-y', '--logy', default=False, action='store_const', const=True,
38         help='Use a log scale for the physical ordinate')
39     parser.add_argument(
40         dest='xmin', type=float,
41         help='Physical coordinate for the xmin-pixel pair')
42     parser.add_argument(
43         dest='xmax', type=float,
44         help='Physical coordinate for the xmax-pixel pair')
45     parser.add_argument(
46         dest='ymin', type=float,
47         help='Physical coordinate for the ymin-pixel pair')
48     parser.add_argument(
49         dest='ymax', type=float,
50         help='Physical coordinate for the ymax-pixel pair')
51     parser.add_argument(
52         dest='input',
53         help='File containing pixel coordinates')
54     args = parser.parse_args()
55
56     with open(args.input, 'r') as f:
57         # reference points in pixels from the first 4 clicks
58         xmin_p = float(f.readline().split()[0])
59         xmax_p = float(f.readline().split()[0])
60         ymin_p = float(f.readline().split()[1])
61         ymax_p = float(f.readline().split()[1])
62         loc = locals()
63         for key in ['xmin', 'xmax', 'ymin', 'ymax']:
64             loc[key] = getattr(args, key)
65         if args.logx:
66             print(('# Xp -> exp((Xp-{xmin_p})/({xmax_p}-{xmin_p})'
67                    '*log({xmax}/{xmin}) + log({xmin}))').format(**loc))
68         else:
69             print(('# Xp -> ({xmax}-{xmin})/({xmax_p}-{xmin_p})'
70                    '*(Xp-{xmin_p}) + {xmin}').format(**loc))
71         if args.logy:
72             print(('# Yp -> exp((Yp-{ymin_p})/({ymax_p}-{ymin_p})'
73                    '*log({ymax}/{ymin}) + log({ymin}))').format(**loc))
74         else:
75             print(('# Yp -> ({ymax}-{ymin})/({ymax_p}-{ymin_p}'
76                    '*(Yp-{ymin_p}) + {ymin}').format(**loc))
77
78         for line in f:
79             x_p,y_p = [float(x) for x in line.split()]
80             if args.logx:
81                 x = exp(
82                     (x_p - xmin_p)/(xmax_p - xmin_p)*log(xmax/xmin)
83                     + log(xmin))
84             else:
85                 x = (xmax - xmin)/(xmax_p - xmin_p) * (x_p - xmin_p) + xmin
86             if args.logy:
87                 y = exp(
88                     (y_p - ymin_p)/(ymax_p - ymin_p)*log(ymax/ymin)
89                     + log(ymin))
90             else:
91                 y = (ymax - ymin)/(ymax_p - ymin_p) * (y_p - ymin_p) + ymin
92             print('{}\t{}'.format(x, y))