over/m/m.vec3.pyx

113 lines
2.4 KiB
Cython

cdef class vec3:
"""
A float 3D vector.
>>> v = vec3(1, 1, 0)
>>> w = vec3(0, 1, 1)
>>> v.length
1.4142135623730951
>>> v.dot(w)
1.0
>>> v.cross(w)
vec4(1.00, 1.00, 1.00)
>>> v + w
vec4(1.00, 2.00, 1.00)
>>> w - v
vec4(-1.00, 0.00, 1.00)
"""
def __init__(vec3 self, *args):
"""
Create a vec3.
Accepts any number of parameters between 0 and 3 to fill the vector from the left.
"""
length = len(args)
if length == 1 and isinstance(args[0], (list, tuple)):
args = args[0]
length = len(args)
if length > 3:
raise MathError("Attempt to initialize a vec3 with %d arguments." %(length))
for i in range(3):
if i < length:
self.v[i] = args[i]
else:
self.v[i] = 0.0
def __getitem__(vec3 self, int i):
if i >= 3 or i < 0:
raise IndexError("element index out of range(3)")
return self.v[i]
def __setitem__(vec3 self, int i, float value):
if i >= 3 or i < 0:
raise IndexError("element index out of range(3)")
self.v[i] = value
def __repr__(vec3 self):
return "vec3(%.2f, %.2f, %.2f)" %(self.v[0], self.v[1], self.v[2])
def __getstate__(vec3 self):
return (self.v[0], self.v[1], self.v[2])
def __setstate__(vec3 self, state):
self.v[0] = state[0]
self.v[1] = state[1]
self.v[2] = state[2]
@property
def length(vec3 self):
"""Contains the geometric length of the vector."""
return sqrt(self.v[0]**2 + self.v[1]**2 + self.v[2]**2)
def normalized(vec3 self):
"""Returns this vector, normalized."""
length = self.length
return vec3(self.v[0] / length, self.v[1] / length, self.v[2] / length)
def __add__(vec3 L, vec3 R):
return vec3(L.v[0] + R.v[0], L.v[1] + R.v[1], L.v[2] + R.v[2])
def __sub__(vec3 L, vec3 R):
return vec3(L.v[0] - R.v[0], L.v[1] - R.v[1], L.v[2] - R.v[2])
def __neg__(vec3 self):
return vec3(-self.v[0], -self.v[1], -self.v[2])
def dot(vec3 L, vec3 R):
"""
Returns the dot product of the two vectors.
E.g. u.dot(v) -> u . v
"""
return L.v[0] * R.v[0] + L.v[1] * R.v[1] + L.v[2] * R.v[2]
def cross(vec3 L, vec3 R):
"""
Returns the cross product of the two vectors.
E.g. u.cross(v) -> u x v
"""
return vec3(L.v[1]*R.v[2] - L.v[2]*R.v[1], L.v[0]*R.v[2] - L.v[2]*R.v[0], L.v[0]*R.v[1] - L.v[1]*R.v[0])
def __mul__(vec3 L, R):
"""
Multiplication of a vec3 by a float.
The float has to be on the right.
"""
return vec3(L.v[0] * R, L.v[1] * R, L.v[2] * R)