def _rotate(vertex, point=None, x=None, y=None, z=None): """rotates a vertex around a point around any or all axes""" alpha, beta, gamma = x, y, z if point == None: point = (0, 0, 0) #translate vertex to revolve around origo: rotated_vertex = vector_subtract(vertex, point) #convert vertex into a 1-row matrix: (x, y, z) --> ((x, y, z)) rotated_vertex = (rotated_vertex,) if alpha != None: rotation_matrix_x = ((1, 0, 0), (0, cos(alpha), sin(alpha)), (0, -sin(alpha), cos(alpha))) rotated_vertex = matrix_multiply(rotated_vertex, rotation_matrix_x) if beta != None: rotation_matrix_y = ((cos(beta), 0, -sin(beta)), (0, 1, 0), (sin(beta), 0, cos(beta))) rotated_vertex = matrix_multiply(rotated_vertex, rotation_matrix_y) if gamma != None: rotation_matrix_z = ((cos(gamma), sin(gamma), 0), (-sin(gamma), cos(gamma), 0), (0, 0, 1)) rotated_vertex = matrix_multiply(rotated_vertex, rotation_matrix_z) #return vertex translated to revolve around point: return vector_add(rotated_vertex[0], point)
def _calculate_ray_collision(self, solid, triangle, S, V): """calculates at what point, if any, a ray hits a triangle P(t) = S + tV P is a point on the line / ray S is the starting point of the ray V is the direction vector for the line / ray The value t represents where on the line point P is located. t = 0 <-> point is in starting point t < 0 <-> point is behind starting point t > 0 <-> point is in front of starting point """ T = triangle['vertices'] #vertices for triangle N = triangle['normal'] #normal for triangle's plane try: # D = -N*T[0] | signed distance from origin # L = <N, D> | 4d plane vector # t = - ( L*S ) / ( L*V ) = - ( N*S - N*T[0] ) / ( N*V ) t = -(dot_product(N, S)-dot_product(N, T[0])) / dot_product(N, V) except ZeroDivisionError: print('Triangle\'s plane is parallel to ray, collision impossible') return None #point where ray hits triangle's plane: P = vector_add(S, inner_product(t, V)) R = vector_subtract(P, T[0]) Q = triangle['Q'] M1 = triangle['M'] M2 = ((dot_product(R, Q[0]),), (dot_product(R, Q[1]),)) w = matrix_multiply(M1, M2) w = (1-w[0][0]-w[1][0], w[0][0], w[1][0]) if all([i > 0 for i in w]) and t > 0: #point P is inside triangle / ray goes through triangle #triangle is in front camera if t > 0 return P else: return None