class M3: z = M(((0, 0, 0), (0, 0, 0), (0, 0, 0))) z._det = 0 e = M(((1, 0, 0), (0, 1, 0), (0, 0, 1))) e._det = 1 @staticmethod def x_rot(a): # right hand rule rotation! m = M(( (1, 0, 0), (0, cos(a), -sin(a)), (0, sin(a), cos(a)), )) m._det = 1 return m @staticmethod def y_rot(a): if a == 1: return M3.e m = M(( (cos(a), 0, -sin(a)), (0, 1, 0), (sin(a), 0, cos(a)), )) m._det = 1 return m @staticmethod def z_rot(a): if a == 1: return M3.e m = M(( (cos(a), -sin(a), 0), (sin(a), cos(a), 0), (0, 0, 1), )) m._det = 1 return m @staticmethod def grow(s): if s == 0: return M3.z if s == 1: return M3.e m = M(( (s, 0, 0), (0, s, 0), (0, 0, s), )) m._det = s**3 return m
def x_rot(a): # right hand rule rotation! m = M(( (1, 0, 0), (0, cos(a), -sin(a)), (0, sin(a), cos(a)), )) m._det = 1 return m
def z_rot(a): if a == 1: return M3.e m = M(( (cos(a), -sin(a), 0), (sin(a), cos(a), 0), (0, 0, 1), )) m._det = 1 return m
def y_rot(a): if a == 1: return M3.e m = M(( (cos(a), 0, -sin(a)), (0, 1, 0), (sin(a), 0, cos(a)), )) m._det = 1 return m
class M2: z = M(((0, 0), (0, 0))) z._det = 0 e = M(((1, 0), (0, 1))) e._det = 1 @staticmethod def grower2(s): if s == 0: return M2.z if s == 1: return M2.e m = M(( (s, 0), (0, s), )) m._det = s**2 return m
def grower2(s): if s == 0: return M2.z if s == 1: return M2.e m = M(( (s, 0), (0, s), )) m._det = s**2 return m
def grow(s): if s == 0: return M3.z if s == 1: return M3.e m = M(( (s, 0, 0), (0, s, 0), (0, 0, s), )) m._det = s**3 return m
def projection(v, camera, centre): """ Project 3D vector onto 2D screen. :param v: 3D Vector :param camera: Camera object :param centre: 2D Vector, centre of screen :return: 2D Vector, position on screen """ v -= camera.pos # camera is basically the origin after this v = M3.z_rot(-camera.z_angle) @ v # rotate points on z-axis around camera v = M3.x_rot(-camera.x_angle) @ v # in the opposite direction sx = 1 / v._value[1] # more distance => point closer to middle (?) sy = 1 / v._value[1] sx *= 800 # zoom way in (original pyramid is tiny) sy *= -800 # tk has y pointing down res = M(((sx, 0, 0), (0, 0, sy))) @ v # Apply transform from Q3 to Q2 res += centre # move to the middle return res