normline_pt.curvature_pt should really return its result -- and changed some docstrings
[PyX/mjg.git] / pyx / unit.py
blob98b7aed71b6d5532b185ec90e0a1a04877f137f8
1 #!/usr/bin/env python
2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002-2004 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002-2004 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 import types
25 import helper
27 scale = { 't':1, 'u':1, 'v':1, 'w':1, 'x':1 }
29 _default_unit = "cm"
31 _m = {
32 'm' : 1,
33 'cm': 0.01,
34 'mm': 0.001,
35 'inch': 0.01*2.54,
36 'pt': 0.01*2.54/72,
39 def set(uscale=None, vscale=None, wscale=None, xscale=None, defaultunit=None):
40 if uscale is not None:
41 scale['u'] = uscale
42 if vscale is not None:
43 scale['v'] = vscale
44 if wscale is not None:
45 scale['w'] = wscale
46 if xscale is not None:
47 scale['x'] = xscale
48 if defaultunit is not None:
49 global _default_unit
50 _default_unit = defaultunit
53 def _convert_to(l, dest_unit="m"):
54 if type(l) in (types.IntType, types.LongType, types.FloatType):
55 return l * _m[_default_unit] * scale['u'] / _m[dest_unit]
56 elif not isinstance(l, length):
57 l = length(l) # convert to length instance if necessary
59 return (l.t + l.u*scale['u'] + l.v*scale['v'] + l.w*scale['w'] + l.x*scale['x']) / _m[dest_unit]
61 def tom(l):
62 return _convert_to(l, "m")
64 def tocm(l):
65 return _convert_to(l, "cm")
67 def tomm(l):
68 return _convert_to(l, "mm")
70 def toinch(l):
71 return _convert_to(l, "inch")
73 def topt(l):
74 return _convert_to(l, "pt")
76 ################################################################################
77 # class for generic length
78 ################################################################################
80 class length:
81 """ PyX lengths
83 PyX lengths are composed of five components (t=true, u=user, v=visual,
84 w=width, and x=TeX) which can be scaled separately (except for the true
85 component, which is always unscaled). Lengths can be constructed in units
86 of "pt", "mm", "cm", "m" and "inch". When no unit is given, a module
87 default is used, which can be changed with the help of the module level function
88 set().
89 """
91 def __init__(self, f=0, type="u", unit=None):
92 """ create a length instance of the given type with a length f
93 in the given unit. If unit is not set, the currently set default unit is used.
94 """
95 self.t = self.u = self.v = self.w = self.x = 0
96 l = float(f) * _m[unit or _default_unit]
97 if type == "t":
98 self.t = l
99 elif type == "u":
100 self.u = l
101 elif type == "v":
102 self.v = l
103 elif type == "w":
104 self.w = l
105 elif type == "x":
106 self.x = l
108 def __cmp__(self, other):
109 # we try to convert self and other into meters and
110 # if this fails, we give other a chance to do the comparison
111 try:
112 return cmp(tom(self), tom(other))
113 except:
114 # why does -cmp(other, self) not work?
115 return -other.__cmp__(self)
117 def __mul__(self, factor):
118 result = length()
119 result.t = factor * self.t
120 result.u = factor * self.u
121 result.v = factor * self.v
122 result.w = factor * self.w
123 result.x = factor * self.x
124 return result
126 __rmul__=__mul__
128 def __div__(self, divisor):
129 if isinstance(divisor, length):
130 return tom(self) / tom(divisor)
131 result = length()
132 result.t = self.t / divisor
133 result.u = self.u / divisor
134 result.v = self.v / divisor
135 result.w = self.w / divisor
136 result.x = self.x / divisor
137 return result
139 def __add__(self, other):
140 # convert to length if necessary
141 if not isinstance(other, length):
142 # if other is not a length, we try to convert it into a length and
143 # if this fails, we give other a chance to do the addition
144 try:
145 other = length(other)
146 except:
147 return other + self
148 result = length()
149 result.t = self.t + other.t
150 result.u = self.u + other.u
151 result.v = self.v + other.v
152 result.w = self.w + other.w
153 result.x = self.x + other.x
154 return result
156 __radd__ = __add__
158 def __sub__(self, other):
159 # convert to length if necessary
160 if not isinstance(other, length):
161 # if other is not a length, we try to convert it into a length and
162 # if this fails, we give other a chance to do the subtraction
163 try:
164 other = length(other)
165 except:
166 return -other + self
167 result = length()
168 result.t = self.t - other.t
169 result.u = self.u - other.u
170 result.v = self.v - other.v
171 result.w = self.w - other.w
172 result.x = self.x - other.x
173 return result
175 def __rsub__(self, other):
176 # convert to length if necessary
177 if not isinstance(other, length):
178 other = length(other)
179 result = length()
180 result.t = other.t - self.t
181 result.u = other.u - self.u
182 result.v = other.v - self.v
183 result.w = other.w - self.w
184 result.x = other.x - self.x
185 return result
187 def __neg__(self):
188 result = length()
189 result.t = -self.t
190 result.u = -self.u
191 result.v = -self.v
192 result.w = -self.w
193 result.x = -self.x
194 return result
196 def __str__(self):
197 return "(%(t)f t + %(u)f u + %(v)f v + %(w)f w + %(x)f x) m" % self.__dict__
200 ################################################################################
201 # predefined instances which can be used as length units
202 ################################################################################
204 # user lengths and unqualified length which are also user length
205 u_pt = pt = length(1, type="u", unit="pt")
206 u_m = m = length(1, type="u", unit="m")
207 u_mm = mm = length(1, type="u", unit="mm")
208 u_cm = cm = length(1, type="u", unit="cm")
209 u_inch = inch = length(1, type="u", unit="inch")
211 # true lengths
212 t_pt = length(1, type="t", unit="pt")
213 t_m = length(1, type="t", unit="m")
214 t_mm = length(1, type="t", unit="mm")
215 t_cm = length(1, type="t", unit="cm")
216 t_inch = length(1, type="t", unit="inch")
218 # visual lengths
219 v_pt = length(1, type="v", unit="pt")
220 v_m = length(1, type="v", unit="m")
221 v_mm = length(1, type="v", unit="mm")
222 v_cm = length(1, type="v", unit="cm")
223 v_inch = length(1, type="v", unit="inch")
225 # width lengths
226 w_pt = length(1, type="w", unit="pt")
227 w_m = length(1, type="w", unit="m")
228 w_mm = length(1, type="w", unit="mm")
229 w_cm = length(1, type="w", unit="cm")
230 w_inch = length(1, type="w", unit="inch")
232 # TeX lengths
233 x_pt = length(1, type="x", unit="pt")
234 x_m = length(1, type="x", unit="m")
235 x_mm = length(1, type="x", unit="mm")
236 x_cm = length(1, type="x", unit="cm")
237 x_inch = length(1, type="x", unit="inch")