Disabled actor rotation for speed
[flail.git] / geom.py
blob0d5668ef09b6cb2f22e9758e6cefdd0fcd24307b
1 from __future__ import division
5 class vector (object):
7 __slots__ = 'x', 'y', 'z'
9 def __init__ (self, x = 0, y = 0, z = 0):
10 self.x, self.y, self.z = x, y, z
12 def __str__ (self):
13 return '(%f, %f, %f)' % (self.x, self.y, self.z)
15 __repr__ = __str__
17 def __add__ (self, other):
18 return vector (self.x + other.x,
19 self.y + other.y,
20 self.z + other.z)
22 def __sub__ (self, other):
23 return vector (self.x - other.x,
24 self.y - other.y,
25 self.z - other.z)
27 def __mul__ (self, other):
28 return vector (self.x * other,
29 self.y * other,
30 self.z * other)
32 def __truediv__ (self, other):
33 return vector (self.x / other,
34 self.y / other,
35 self.z / other)
37 __div__ = __truediv__
39 def __rmul__ (self, other):
40 return vector (self.x * other,
41 self.y * other,
42 self.z * other)
44 def __iadd__ (self, other):
45 self.x += other.x
46 self.y += other.y
47 self.z += other.z
48 return self
50 def __isub__ (self, other):
51 self.x -= other.x
52 self.y -= other.y
53 self.z -= other.z
54 return self
56 def __imul__ (self, other):
57 self.x *= other
58 self.y *= other
59 self.z *= other
60 return self
62 def __itruediv__ (self, other):
63 self.x /= other
64 self.y /= other
65 self.z /= other
66 return self
68 __idiv__ = __itruediv__
70 def __neg__ (self):
71 return vector (-self.x, -self.y, -self.z)
73 def __pos__ (self):
74 return self
76 def __abs__ (self):
77 return self.norm ()
79 def norm (self):
80 from math import sqrt
81 return sqrt (self.normsq ())
83 def normsq (self):
84 return self.dot (self)
86 def normed (self, norm):
87 return self * (norm / abs (self))
89 def dot (self, other):
90 return (self.x * other.x +
91 self.y * other.y +
92 self.z * other.z)
94 def cross (self, other):
95 return vector (self.y * other.z - self.z * other.y,
96 self.z * other.x - self.x * other.z,
97 self.x * other.y - self.y * other.x)
99 def proj (self, other):
100 return other * self.dot (other) / other.dot (other)
102 def xrot (self, angle):
103 from math import cos, sin
104 cosx, sinx = cos (angle), sin (angle)
105 return vector (self.x,
106 cosx * self.y - sinx * self.z,
107 sinx * self.y + cosx * self.z)
109 def yrot (self, angle):
110 from math import cos, sin
111 cosy, siny = cos (angle), sin (angle)
112 return vector (siny * self.z + cosy * self.x,
113 self.y,
114 cosy * self.z - siny * self.x)
116 def zrot (self, angle):
117 from math import cos, sin
118 cosz, sinz = cos (angle), sin (angle)
119 return vector (cosz * self.x - sinz * self.y,
120 sinz * self.x + cosz * self.y,
121 self.z)
123 def transform (self, oval):
124 # pos = (self - oval.pos).zrot (-oval.angle)
125 pos = self - oval.pos
126 pos.x /= oval.size.x
127 pos.y /= oval.size.y
128 return pos
130 def invert (self, oval):
131 x = self.x * oval.size.x
132 y = self.y * oval.size.y
133 pos = vector (x, y, self.z)
134 return oval.pos + pos
135 # return oval.pos + pos.zrot (oval.angle)
139 class line (object):
141 __slots__ = 'p1', 'p2'
143 def __init__ (self, p1 = None, p2 = None):
144 self.p1 = p1 or vector ()
145 self.p2 = p2 or vector ()
147 def __call__ (self, t):
148 return self.p1 + t * self.dir ()
150 def dir (self):
151 return self.p2 - self.p1
153 def perp (self):
154 dir = self.dir ()
155 return vector (-dir.y, dir.x)
157 def length (self):
158 return abs (self.dir ())
160 def dist (self):
161 cross = self.p1.cross (self.p2)
162 return cross.z / self.length ()
164 def distsq (self):
165 cross = self.p1.cross (self.p2)
166 return cross.z * cross.z / self.dir ().normsq ()
168 def units (self):
169 '''Get parameters yielding points on the unit circle.
171 In some sense, finds the intersection(s) of this line
172 with the unit circle. It really only gives the
173 solutions to the equation |p1 + t (p2 - p1)| = 1.'''
175 from math import sqrt
177 dir = self.dir ()
178 a = dir.normsq ()
179 b = 2 * self.p1.dot (dir)
180 c = self.p1.normsq () - 1
181 dis = b * b - 4 * a * c
183 if dis < 0:
184 return ()
185 elif dis == 0:
186 return (-b / (2 * a),)
187 else:
188 return ((-b - sqrt (dis)) / (2 * a),
189 (-b + sqrt (dis)) / (2 * a))
191 def transform (self, oval):
192 return line (self.p1.transform (oval),
193 self.p2.transform (oval))
195 def invert (self, oval):
196 return line (self.p1.invert (oval),
197 self.p2.invert (oval))
201 class rect (object):
203 __slots__ = 'pos', 'size'
205 def __init__ (self, pos = None, size = None):
206 self.pos = pos or vector ()
207 self.size = size or vector ()
209 def left (self):
210 return self.pos.x - self.size.x
212 def right (self):
213 return self.pos.x + self.size.x
215 def top (self):
216 return self.pos.y + self.size.y
218 def bottom (self):
219 return self.pos.y - self.size.y
221 def width (self):
222 return 2 * self.size.x
224 def height (self):
225 return 2 * self.size.y
227 def set_left (self, l):
228 self.pos.x = l + self.size.x
230 def set_right (self, r):
231 self.pos.x = r - self.size.x
233 def set_top (self, t):
234 self.pos.y = t - self.size.y
236 def set_bottom (self, b):
237 self.pos.y = b + self.size.y
239 def set_width (self, w):
240 self.size.x = w / 2
242 def set_height (self, h):
243 self.size.y = h / 2
247 class ellipse (object):
249 __slots__ = 'pos', 'size', 'angle'
251 def __init__ (self, pos = None, size = None, angle = 0):
252 self.pos = pos or vector ()
253 self.size = size or vector ()
254 self.angle = angle