def _create_triangles(self): triangles = [] for face in self.faces: T = self.get_vertices(face) #vertices t0, t1, t2 Q = (vector_subtract(T[1], T[0]), vector_subtract(T[2], T[0])) normal = cross_product(Q[0], Q[1]) M = inverse(((dot_product(Q[0], Q[0]), dot_product(Q[0], Q[1])), (dot_product(Q[0], Q[1]), dot_product(Q[1], Q[1])))) triangles.append({'normal': normal, 'vertices': T, 'Q': Q, 'M': M}) return triangles
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