def lies_behind(p, poly): #draw a line from the viewer's position to p, and see if it intersects the plane formed by poly. #formula courtesy of https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection a,b,c = poly n = cross_product(b-a, c-a) p0 = a l = Point(0,0,1) l0 = p if dot_product(l,n) == 0: #I think this only happens when the poly is viewed edge-on. return False d = dot_product(p0 - l0, n) / dot_product(l,n) return d < 0
def reflect_speeds(normal_vector, v1_vector, v2_vector, m_1, m_2): """ TODO """ v1_eff = geometry.dot_product(normal_vector, v1_vector) v2_eff = geometry.dot_product(normal_vector, v2_vector) new_v1_eff, new_v2_eff = elastic_collision(v1_eff, -v2_eff, m_1, m_2) new_v1_eff = geometry.vector_product(normal_vector, new_v1_eff) new_v2_eff = geometry.vector_product(normal_vector, new_v2_eff) v1_perpendicular = geometry.components(normal_vector, v1_vector)[1] v2_perpendicular = geometry.components(normal_vector, v2_vector)[1] new_v1_vector = geometry.vector_diff(v1_perpendicular, new_v1_eff) new_v2_vector = geometry.vector_sum(v2_perpendicular, new_v2_eff) return (new_v1_vector[0], new_v1_vector[1], new_v2_vector[0], new_v2_vector[1])
def line_segment_intersection(a,b,c,d): #a line can be expressed as the set of points p for which #(p - p0) dot n = 0 #where p0 is a point on the line and n is a normal vector to the line. #the vector equation for a line segment is #p = f*c + (1-f)*d = f*c - f*d + d = f*(c-d) + d #where f is a number between 0 and 1 inclusive. # #(f*(c-d) + d - p0) dot n = 0 #((f*(c-d)) dot n) - ((p0 - d) dot n) = 0 #((f*(c-d)) dot n) = ((p0 - d) dot n) #f*((c-d) dot n) = ((p0 - d) dot n) #f = ((p0 - d) dot n) / ((c-d) dot n) p0 = a n = exp(1, (a-b).angle() + math.radians(90)) f = dot_product(p0-d, n) / dot_product(c-d, n) if 0 <= f <= 1: return (c+d)*f - d return None
def test_dot_product(self): self.assertEqual(geometry.dot_product([1, 2, 1], [1, 1, 2]), 5)
def angle_3d(a,b): return math.acos(dot_product(a,b) / (a.magnitude() * b.magnitude()))