113 lines
2.4 KiB
Cython
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)
|