-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.py
165 lines (114 loc) · 3.97 KB
/
util.py
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
# Util
# ==================================
from vector2d import Vector2D
import copy
class DictWrap(object):
""" Wrap an existing dict, or create a new one, and access with either dot
notation or key lookup.
The attribute _data is reserved and stores the underlying dictionary.
When using the += operator with create=True, the empty nested dict is
replaced with the operand, effectively creating a default dictionary
of mixed types.
args:
d({}): Existing dict to wrap, an empty dict is created by default
create(True): Create an empty, nested dict instead of raising a KeyError
example:
>>>dw = DictWrap({'pp':3})
>>>dw.a.b += 2
>>>dw.a.b += 2
>>>dw.a['c'] += 'Hello'
>>>dw.a['c'] += ' World'
>>>dw.a.d
>>>print dw._data
{'a': {'c': 'Hello World', 'b': 4, 'd': {}}, 'pp': 3}
"""
def __init__(self, d=None, create=True):
if d is None:
d = {}
supr = super(DictWrap, self)
supr.__setattr__('_data', d)
supr.__setattr__('__create', create)
def __getattr__(self, name):
try:
value = self._data[name]
except KeyError:
if not super(DictWrap, self).__getattribute__('__create'):
raise
value = {}
self._data[name] = value
if hasattr(value, 'items'):
create = super(DictWrap, self).__getattribute__('__create')
return DictWrap(value, create)
return value
def __setattr__(self, name, value):
self._data[name] = value
def __getitem__(self, key):
try:
value = self._data[key]
except KeyError:
if not super(DictWrap, self).__getattribute__('__create'):
raise
value = {}
self._data[key] = value
if hasattr(value, 'items'):
create = super(DictWrap, self).__getattribute__('__create')
return DictWrap(value, create)
return value
def __setitem__(self, key, value):
self._data[key] = value
def __iadd__(self, other):
if self._data:
raise TypeError("A Nested dict will only be replaced if it's empty")
else:
return other
class Util(object):
@staticmethod
def translatePoints(points, x=0, y=0):
for point in points:
point.x += x
point.y += y
return points
@staticmethod
def scalePoints(points, x = 1.0, y = 1.0):
for point in points:
point.x *= x
point.y *= y
return points
@staticmethod
def scaledPoints(points, x = 1.0, y = 1.0):
pointsCopy = copy.deepcopy(points)
for point in pointsCopy:
point.x *= x
point.y *= y
return pointsCopy
@staticmethod
def clamp(minimum, x, maximum):
return max(minimum, min(x, maximum))
# Returns a scaling function based on tuples for domain and range
@staticmethod
def linearScale(domain, range):
rise = range[1] - range[0]
run = domain[1] - domain[0]
m = rise / run
c = range[1] - m * domain[1]
def f(x):
return m * x + c
return f
# Returns a new array of points copied
@staticmethod
def copyPoints(points):
return [pt.copy() for pt in points]
@staticmethod
def strPoints(points):
return [str(pt) for pt in points]
@staticmethod
def sign(num):
if(num >= 0.0): return 1
return -1
@staticmethod
def shapeFromString(string, pointDelimiter=',', coordDelimiter=' '):
# Grab the points
points = [p.strip().split(coordDelimiter) for p in string.split(pointDelimiter)]
# Convert coordinates to vectors
points = [Vector2D(float(c[0]), float(c[1])) for c in points]
return points