def sphere_intersection_point(theRay, theSphere): dotvector_of_raydir_sqr = vector_math.dot_vector(theRay.dir, theRay.dir) diffpoint_of_raypt_sphcen = vector_math.difference_point( theRay.pt, theSphere.center) dotvector_of_raydir_diffpoint = vector_math.dot_vector( diffpoint_of_raypt_sphcen, theRay.dir) dotvector_of_diffpoint_sqr = vector_math.dot_vector( diffpoint_of_raypt_sphcen, diffpoint_of_raypt_sphcen) A = dotvector_of_raydir_sqr #(theRay.dir * theRay.dir) B = dotvector_of_raydir_diffpoint * 2 #(2 * (theRay.pt - theSphere.center) * theRay.dir) C = dotvector_of_diffpoint_sqr - theSphere.radius**2 #(((theRay.pt - theSphere.center) * (theRay.pt - theSphere.center)) - theSphere.radius ** 2) D = B**2 - 4 * A * C #discriminant if D < 0: #D < 0 means no real roots, thus sphere does not intersect with ray return 'None' elif D == 0: t = (-B + math.sqrt(D)) / (2 * A) if t < 0: return 'None' else: pointt = vector_math.translate_point( theRay.pt, vector_math.scale_vector(theRay.dir, t)) return pointt else: t1 = (-B + math.sqrt(D)) / (2 * A) t2 = (-B - math.sqrt(D)) / (2 * A) if t1 >= 0 and t2 >= 0: pointt = vector_math.translate_point( theRay.pt, vector_math.scale_vector(theRay.dir, min(t1, t2))) return pointt elif t1 < 0 and t2 < 0: return 'None' elif t1 < 0 or t2 < 0: pointt = vector_math.translate_point( theRay.pt, vector_math.scale_vector(theRay.dir, max(t1, t2))) return pointt
def getSpecular(ray, intersection_list, light, point): closest = findClosestSphere(ray, intersection_list) csphere = closest[0] cpoint = closest[1] n_vector = collisions.sphere_normal_at_point(csphere, cpoint) scaled_vector = vector_math.scale_vector(n_vector, 0.01) p_e = vector_math.translate_point(cpoint, scaled_vector) light_vector = vector_math.vector_from_to(p_e, light.pt) L_dir = vector_math.normalize_vector(light_vector) light_dot_product = vector_math.dot_vector(n_vector, L_dir) #gets spec values n_scale = vector_math.scale_vector(n_vector, (2 * light_dot_product)) reflection = vector_math.difference_vector(L_dir, n_scale) pe_eyevec = vector_math.normalize_vector( vector_math.difference_point(p_e, point)) specularIntensity = vector_math.dot_vector(pe_eyevec, reflection) if specularIntensity > 0: sphere_spec = csphere.finish.specular sphere_rough = csphere.finish.roughness specCont_r = (light.color.r * sphere_spec) * (specularIntensity**( 1 / float(sphere_rough))) specCont_g = (light.color.g * sphere_spec) * (specularIntensity**( 1 / float(sphere_rough))) specCont_b = (light.color.b * sphere_spec) * (specularIntensity**( 1 / float(sphere_rough))) else: specCont_r = 0 specCont_g = 0 specCont_b = 0 return (specCont_r, specCont_g, specCont_b)
def cast_ray(ray, sphere_list, color, light): """Find the rendered color at the nearest intersection point along ray""" nearest = closest_intersect(ray, sphere_list) if not nearest: # No intersection, return white return Color(1.0, 1.0, 1.0) point, sphere = nearest # Compute initial ambient colors r = sphere.color.r * sphere.finish.ambient * color.r g = sphere.color.g * sphere.finish.ambient * color.g b = sphere.color.b * sphere.finish.ambient * color.b # Calculate diffuse value normal = sphere_normal_at_point(sphere, point) to_light = normalize_vector(vector_from_to(point, light.pt)) l_dot = dot_vector(normal, to_light) diffuse = sphere.finish.diffuse * l_dot if diffuse < 0: diffuse = 0 else: # Check for shadows new_point = translate_point(point, scale_vector(normal, 0.01)) light_ray = Ray(new_point, to_light) shadow_intersect = closest_intersect(light_ray, sphere_list) if (shadow_intersect and length_vector_sq(vector_from_to(new_point, shadow_intersect[0])) < length_vector_sq(vector_from_to(new_point, light.pt))): diffuse = 0 # Add diffuse to existing colors r += sphere.color.r * diffuse * light.color.r g += sphere.color.g * diffuse * light.color.g b += sphere.color.b * diffuse * light.color.b # Compute specular intensity if diffuse > 0: reflection = difference_vector(to_light, scale_vector(normal, 2 * l_dot)) intensity = dot_vector(reflection, normalize_vector(ray.dir)) power = 1. / sphere.finish.roughness if intensity > 0: r += light.color.r * sphere.finish.specular * intensity ** power g += light.color.g * sphere.finish.specular * intensity ** power b += light.color.b * sphere.finish.specular * intensity ** power # Max out colors at 1.0 if r > 1: r = 1 if g > 1: g = 1 if b > 1: b = 1 return Color(r, g, b)
def cast_ray(ray, sphere_list, amb, light, eye_point): result_color = data.Color(1.0, 1.0, 1.0) # test for closest sphere to the eye collision_tuple = find_closest_collision(ray, sphere_list) if collision_tuple: # some useful variables sphere_hit = collision_tuple[0] sphere_hit_point = collision_tuple[1] # basic color before manipulation result_r = sphere_hit.color.r * sphere_hit.finish.amb * amb.r result_g = sphere_hit.color.g * sphere_hit.finish.amb * amb.g result_b = sphere_hit.color.b * sphere_hit.finish.amb * amb.b # computing light intensity sphere_vector = vector_math.vector_from_to(sphere_hit.center, sphere_hit_point) sphere_normal = vector_math.normalize_vector(sphere_vector) scaled_normal = vector_math.scale_vector(sphere_normal, 0.01) hit_point = vector_math.translate_point(sphere_hit_point, scaled_normal) light_vector = vector_math.vector_from_to(hit_point, light.pt) light_normal = vector_math.normalize_vector(light_vector) light_scale = vector_math.dot_vector(sphere_normal, light_normal) if light_scale > 0: sphere_normal_ray = data.Ray(hit_point, light_normal) possible_obstruction = find_closest_collision(sphere_normal_ray, sphere_list) if possible_obstruction == None or distance(hit_point, possible_obstruction[1]) > distance( hit_point, light.pt ): result_r += sphere_hit.color.r * light_scale * light.color.r * sphere_hit.finish.diff result_g += sphere_hit.color.g * light_scale * light.color.g * sphere_hit.finish.diff result_b += sphere_hit.color.b * light_scale * light.color.b * sphere_hit.finish.diff # computing specular intensity tmp_vector = vector_math.scale_vector(sphere_normal, 2 * light_scale) reflection_vector = vector_math.difference_vector(light_normal, tmp_vector) eye_vector = vector_math.vector_from_to(eye_point, hit_point) eye_normal = vector_math.normalize_vector(eye_vector) spec_scale = vector_math.dot_vector(reflection_vector, eye_normal) if spec_scale > 0: result_r += light.color.r * sphere_hit.finish.spec * spec_scale ** (1 / float(sphere_hit.finish.rough)) result_g += light.color.g * sphere_hit.finish.spec * spec_scale ** (1 / float(sphere_hit.finish.rough)) result_b += light.color.b * sphere_hit.finish.spec * spec_scale ** (1 / float(sphere_hit.finish.rough)) result_color = data.Color(result_r, result_g, result_b) return result_color
def test_scale_2(self): v = data.Vector(0, .5, .75) v = vector_math.scale_vector(v, 100) self.assertAlmostEqual(v.x, 0) self.assertAlmostEqual(v.y, 50) self.assertAlmostEqual(v.z, 75) pass
def test_scale_2(self): v = data.Vector(1.0, 2.0, 3.0) scale_factor = 1.5 v_scaled = vector_math.scale_vector(v, scale_factor) self.assertAlmostEqual(v_scaled.x, 1.5) self.assertAlmostEqual(v_scaled.y, 3.0) self.assertAlmostEqual(v_scaled.z, 4.5)
def sphere_intersection_point(ray,sphere): def point_t(t): return vector_math.translate_point(ray.pt, vector_math.scale_vector(ray.dir,t)) diff_pt = vector_math.difference_point(ray.pt,sphere.center) a = vector_math.dot_vector(ray.dir, ray.dir) b = vector_math.dot_vector(vector_math.scale_vector(diff_pt,2), ray.dir) c = vector_math.dot_vector(diff_pt,diff_pt) - sphere.radius ** 2 disc = b ** 2 - 4 * a * c if disc < 0: return None elif disc == 0: t3 = (-b / (2 * a)) if t3 >= 0: return point_t(t3) else: return None else: disc_root = math.sqrt(disc) t1 = (-b + disc_root) / (2 * a) t2 = (-b - disc_root) / (2 * a) if t1 >= 0 and t2 >= 0: return point_t(min(t1,t2)) elif t1 < 0 and t2 < 0: return None else: if t1 >= 0: return point_t(t1) elif t2 >= 0: return point_t(t2)
def determine_specular_contribution(l_dir, l_dot_n, normal, eye_position, off_pt, light, sphere_finish, ray, inter_list): reflection_vect = vector_math.difference_vector( l_dir, vector_math.scale_vector(normal, 2 * l_dot_n)) v_dir = vector_math.normalize_vector( vector_math.vector_from_to(eye_position, off_pt)) spec_intensity = vector_math.dot_vector(reflection_vect, v_dir) def compute_spec(color_comp): return (color_comp * sphere_finish.specular * (spec_intensity**(1 / sphere_finish.roughness))) if spec_intensity > 0: r_comp = compute_spec(light.color.r) g_comp = compute_spec(light.color.g) b_comp = compute_spec(light.color.b) if inter_list == []: return [r_comp, g_comp, b_comp] else: dist_pt_to_light = distance(off_pt, light.pt) nearest_point = find_nearest(inter_list, ray) if distance(off_pt, nearest_point) < dist_pt_to_light: return [0, 0, 0] else: return [r_comp, g_comp, b_comp] else: return [0, 0, 0]
def sphere_intersection_point(ray, sphere): def point_t(t): return vector_math.translate_point( ray.pt, vector_math.scale_vector(ray.dir, t)) diff_pt = vector_math.difference_point(ray.pt, sphere.center) a = vector_math.dot_vector(ray.dir, ray.dir) b = vector_math.dot_vector(vector_math.scale_vector(diff_pt, 2), ray.dir) c = vector_math.dot_vector(diff_pt, diff_pt) - sphere.radius**2 disc = b**2 - 4 * a * c if disc < 0: return None elif disc == 0: t3 = (-b / (2 * a)) if t3 >= 0: return point_t(t3) else: return None else: disc_root = math.sqrt(disc) t1 = (-b + disc_root) / (2 * a) t2 = (-b - disc_root) / (2 * a) if t1 >= 0 and t2 >= 0: return point_t(min(t1, t2)) elif t1 < 0 and t2 < 0: return None else: if t1 >= 0: return point_t(t1) elif t2 >= 0: return point_t(t2)
def determine_specular_contribution(l_dir,l_dot_n,normal,eye_position, off_pt,light,sphere_finish,ray, inter_list): reflection_vect = vector_math.difference_vector(l_dir, vector_math.scale_vector(normal, 2 * l_dot_n)) v_dir = vector_math.normalize_vector( vector_math.vector_from_to(eye_position,off_pt)) spec_intensity = vector_math.dot_vector(reflection_vect,v_dir) def compute_spec(color_comp): return (color_comp * sphere_finish.specular * (spec_intensity ** (1 / sphere_finish.roughness))) if spec_intensity > 0: r_comp = compute_spec(light.color.r) g_comp = compute_spec(light.color.g) b_comp = compute_spec(light.color.b) if inter_list == []: return [r_comp,g_comp,b_comp] else: dist_pt_to_light = distance(off_pt,light.pt) nearest_point = find_nearest(inter_list,ray) if distance(off_pt,nearest_point) < dist_pt_to_light: return [0,0,0] else: return [r_comp,g_comp,b_comp] else: return [0,0,0]
def test_scale_1(self): v = data.Vector(1,2,3) v = vector_math.scale_vector(v, 2) self.assertAlmostEqual(v.x, 2) self.assertAlmostEqual(v.y, 4) self.assertAlmostEqual(v.z, 6) pass
def test_scale_1(self): v = data.Vector(0.0, 0.1, 0.2) scale_factor = 1.5 v_scaled = vector_math.scale_vector(v, scale_factor) self.assertEqual(v_scaled, data.Vector(0.0, 0.15, 0.3)) self.assertAlmostEqual(v_scaled.x, 0.0) self.assertAlmostEqual(v_scaled.y, 0.15) self.assertAlmostEqual(v_scaled.z, 0.3)
def test_vectorToFrom_1(self): p1 = data.Point(1,2,3) p2 = data.Point(0,0,0) v1 = vector_math.vector_from_to(p1, p2) v2 = vector_math.vector_from_to(p2, p1) equals1 = data.Vector(-1, -2, -3) equals2 = vector_math.scale_vector(v1, -1) self.assertEqual(v1 == equals1, True) self.assertEqual(v2 == equals2, True) pass
def cast_ray(ray, sphere_list, ambient, light, point): a = collisions.find_intersection_points(sphere_list, ray) if a == []: return data.Color(1.0, 1.0, 1.0) sphere_look = a[0] for x in a: if distance(ray.pt, x[1]) < distance(ray.pt, sphere_look[1]): sphere_look = x red = sphere_look[0].color.r * sphere_look[0].finish.ambient * ambient.r green = sphere_look[0].color.g * sphere_look[0].finish.ambient * ambient.g blue = sphere_look[0].color.b * sphere_look[0].finish.ambient * ambient.b n = collisions.sphere_normal_at_point(sphere_look[0], sphere_look[1]) pe = vector_math.translate_point(sphere_look[1], vector_math.scale_vector(n, .01)) visible_ray = data.Ray(pe, vector_math.vector_from_to(pe, light.point)) ldir = vector_math.normalize_vector(visible_ray.dir) visible = vector_math.dot_vector(ldir, n) n = collisions.sphere_normal_at_point(sphere_look[0], sphere_look[1]) ldir_dot_n = vector_math.dot_vector(ldir, n) reflection_vector = vector_math.difference_vector( vector_math.scale_vector(n, ldir_dot_n * 2), ldir) vdir = vector_math.normalize_vector(vector_math.vector_from_to(point, pe)) specular_intensity = vector_math.dot_vector(reflection_vector, vdir) if visible > 0: if collisions.find_intersection_points(sphere_list, visible_ray) == []: red += (visible * light.color.r * sphere_look[0].color.r * sphere_look[0].finish.diffuse) green += (visible * light.color.g * sphere_look[0].color.g * sphere_look[0].finish.diffuse) blue += (visible * light.color.b * sphere_look[0].color.b * sphere_look[0].finish.diffuse) if specular_intensity > 0: spec_intensity_calc = specular_intensity**( 1 / sphere_look[0].finish.roughness) red += light.color.r * sphere_look[ 0].finish.specular * spec_intensity_calc green += light.color.g * sphere_look[ 0].finish.specular * spec_intensity_calc blue += light.color.b * sphere_look[ 0].finish.specular * spec_intensity_calc return data.Color(red, green, blue)
def sphere_intersection_point(ray, sphere): #define variables A = vector_math.dot_vector(ray.dir, ray.dir) B = vector_math.dot_vector( vector_math.scale_vector( (vector_math.difference_point(ray.pt, sphere.center)), 2), ray.dir) C = vector_math.dot_vector( vector_math.difference_point(ray.pt, sphere.center), vector_math.difference_point(ray.pt, sphere.center)) - sphere.radius**2 discriminant = B**2 - 4 * A * C if discriminant < 0: return None #define t t = (-B + math.sqrt(discriminant)) / (2.0 * A) t_2 = (-B - math.sqrt(discriminant)) / (2.0 * A) point_t = vector_math.translate_point(ray.pt, vector_math.scale_vector(ray.dir, t)) point_t2 = vector_math.translate_point( ray.pt, vector_math.scale_vector(ray.dir, t_2)) #Cases if t >= 0 and t_2 >= 0: if t_2 > t: return point_t else: return point_t2 elif t < 0 and t_2 < 0: return None elif (t < 0 and t_2 >= 0) or (t >= 0 and t_2 < 0): if t >= 0: return point_t else: return point_t2 else: return None
def comp(sphere_list,inter,light,sphere,int,eye_point): n = collisions.sphere_normal_at_point(sphere,int) scaled_normal = vector_math.scale_vector(n,.01) Pe = vector_math.translate_point(inter[0][1],scaled_normal) vr_light = vector_math.vector_from_to(Pe,light.pt) L_dir = vector_math.normalize_vector(vr_light) dot_product = vector_math.dot_vector(n,L_dir) reflection_vr = vector_math.difference_vector(L_dir,vector_math.scale_vector(n,(2 * dot_product))) V_dir = vector_math.normalize_vector(vector_math.vector_from_to(eye_point,Pe)) intensity = vector_math.dot_vector(reflection_vr,V_dir) ray = data.Ray(Pe,L_dir) inter2 = collisions.find_intersection_points(sphere_list,ray) if dot_product>0 and inter2 == []: diff_r = sphere.color.r*sphere.finish.diffuse*dot_product*light.color.r diff_g = sphere.color.g*sphere.finish.diffuse*dot_product*light.color.g diff_b = sphere.color.b*sphere.finish.diffuse*dot_product*light.color.b spec_r = light.color.r*sphere.finish.specular*math.pow(intensity,(1/sphere.finish.roughness)) spec_g = light.color.g*sphere.finish.specular*math.pow(intensity,(1/sphere.finish.roughness)) spec_b = light.color.b*sphere.finish.specular*math.pow(intensity,(1/sphere.finish.roughness)) return data.Color(diff_r,diff_g,diff_b),data.Color(spec_r,spec_g,spec_b) else : return data.Color(0,0,0), data.Color(0,0,0)
def find_specular_intensity(spherepair, light, eye_point, l_dot_n): light_dir = vector_math.normalize_vector(vector_math.difference_point( light.pt, spherepair[1])) sphere_normal = collisions.sphere_normal_at_point(spherepair[0], spherepair[1]) reflection_vector = vector_math.difference_vector(light_dir, vector_math.scale_vector(sphere_normal, 2 * l_dot_n)) view_dir = vector_math.normalize_vector(vector_math.difference_point( spherepair[1], eye_point)) specular_intensity = vector_math.dot_vector(view_dir, reflection_vector) return specular_intensity
def get_specular_intensity(lDir, lDirection, N, pE, light, sphere): reflection_vector = vector_math.difference_vector(lDir, vector_math.scale_vector(N, lDirection * 2)) vDir = vector_math.vector_from_to(data.Point(0.0,0.0,-14.0), pE) vDir = vector_math.normalize_vector(vDir) intensity = vector_math.dot_vector(reflection_vector, vDir) if intensity > 0: r = light.color.r * sphere.finish.specular * intensity**(1 / sphere.finish.roughness) g = light.color.g * sphere.finish.specular * intensity**(1 / sphere.finish.roughness) b = light.color.b * sphere.finish.specular * intensity**(1 / sphere.finish.roughness) color = data.Color(r,g,b) else: color = data.Color(0,0,0) return color
def get_specular_intensity(lDir, lDirection, N, pE, light, sphere): reflection_vector = vector_math.difference_vector( lDir, vector_math.scale_vector(N, lDirection * 2)) vDir = vector_math.vector_from_to(data.Point(0.0, 0.0, -14.0), pE) vDir = vector_math.normalize_vector(vDir) intensity = vector_math.dot_vector(reflection_vector, vDir) if intensity > 0: r = light.color.r * sphere.finish.specular * intensity**( 1 / sphere.finish.roughness) g = light.color.g * sphere.finish.specular * intensity**( 1 / sphere.finish.roughness) b = light.color.b * sphere.finish.specular * intensity**( 1 / sphere.finish.roughness) color = data.Color(r, g, b) else: color = data.Color(0, 0, 0) return color
def sphere_intersection_point(ray, sphere): a = vm.dot_vector(ray.dir, ray.dir) b = vm.dot_vector(vm.scale_vector(vm.vector_from_to(sphere.center, ray.pt), 2), ray.dir) c = vm.dot_vector(vm.vector_from_to(sphere.center, ray.pt), vm.vector_from_to(sphere.center, ray.pt)) - sphere.radius ** 2 x = vm.quadForm(a, b, c) def point_along_ray(ray, t): if t >= 0: x = ray.pt.x + ray.dir.x * t y = ray.pt.y + ray.dir.y * t z = ray.pt.z + ray.dir.z * t return data.Point(x, y, z) else: return None if x is None: return None if isinstance(x, list): intersections = [] for i in x: intersections.append(point_along_ray(ray, i)) distances = [] for i in intersections: if i is not None: distances.append(vm.distForm(i, ray.pt)) else: distances.append(None) if distances[0] is None: return intersections[1] if distances[1] is None: return intersections[0] if distances[0] < distances[1]: return intersections[0] else: return intersections[1] else: intersection = point_along_ray(ray, x) return intersection
def getDiffuse(ray, intersection_list, sphere_list, light): closest = findClosestSphere(ray, intersection_list) csphere = closest[0] cpoint = closest[1] normalVec = collisions.sphere_normal_at_point(csphere, cpoint) scaled_vector = vector_math.scale_vector(normalVec, 0.01) p_e = vector_math.translate_point(cpoint, scaled_vector) light_vector = vector_math.vector_from_to(p_e, light.pt) L_dir = vector_math.normalize_vector(light_vector) ldotProduct = vector_math.dot_vector(normalVec, L_dir) light_ray = data.Ray(p_e, L_dir) light_intersections = collisions.find_intersection_points( sphere_list, light_ray) light_distance = vector_math.length_vector(light_vector) if_diffuse = True if ldotProduct > 0: if light_intersections != []: for spheres_and_points in light_intersections: point = spheres_and_points[1] difference_lengths = vector_math.length_vector( vector_math.difference_point(point, p_e)) if difference_lengths < light_distance: if_diffuse = False else: if_diffuse = False if if_diffuse: lClr_r = light.color.r lClr_g = light.color.g lClr_b = light.color.b sp_r = csphere.color.r sp_g = csphere.color.g sp_b = csphere.color.b diff_r = ldotProduct * lClr_r * sp_r * csphere.finish.diffuse diff_g = ldotProduct * lClr_g * sp_g * csphere.finish.diffuse diff_b = ldotProduct * lClr_b * sp_b * csphere.finish.diffuse else: diff_r = 0 diff_g = 0 diff_b = 0 return (diff_r, diff_g, diff_b)
def find_pt_off_sphere(inter_point,normal): vect = vector_math.scale_vector(normal, 0.01) return vector_math.translate_point(inter_point,vect)
def test_scale_vector_2(self): vector3 = data.Vector(-1, 0, 5) scalar = (-2.0) vector4 = data.Vector(2.0, 0.0, -10.0) self.assertEqual(vector_math.scale_vector(vector3, -2.0), vector4)
def test_scale_vector_2(self): vector_one = data.Vector(1, 2, 3) scale = 1.5 v = data.Vector(1.5, 3, 4.5) self.assertEqual(vector_math.scale_vector(vector_one, scale), v)
def find_pt_off_sphere(inter_point, normal): vect = vector_math.scale_vector(normal, 0.01) return vector_math.translate_point(inter_point, vect)
def test_scale_vector_1(self): vector1 = data.Vector(5,10,20) scalar = (3.0) vector2 = data.Vector(15.0,30.0,60.0) self.assertEqual(vector_math.scale_vector(vector1, scalar), vector2)
def find_point_near_sphere(sphere, point): normal_vector = collisions.sphere_normal_at_point(sphere, point) translate_vec = vector_math.scale_vector(normal_vector, 0.01) return vector_math.translate_point(point, translate_vec)
def test_scale_vector_again(self): sv = vector_math.scale_vector(data.Vector(-3.5, 5, 7.5), 2) self.assertEqual(sv, data.Vector(-7, 10, 15))
def test_scale_vector(self): sv = vector_math.scale_vector(data.Vector(1, 2, 3), 1.5) self.assertEqual(sv, data.Vector(1.5, 3, 4.5))
def test_scale_vector_1(self): self.assertEqual(vector_math.scale_vector(data.Vector(1, 2, 3), 1.5), data.Vector(1.5, 3, 4.5))
def get_pe(tu): vector = collisions.sphere_normal_at_point(tu[0], tu[1]) sVector = vector_math.scale_vector(vector, .01) scaledPoint = vector_math.translate_point(tu[1], sVector) return scaledPoint
def point_t(t): return vector_math.translate_point(ray.pt, vector_math.scale_vector(ray.dir,t))
def point_t(t): return vector_math.translate_point( ray.pt, vector_math.scale_vector(ray.dir, t))
def test_scale_vector_1(self): vector_one = data.Vector(1, 1, 1) scale = 2 v = data.Vector(2, 2, 2) self.assertTrue( data.Vector.__eq__(vector_math.scale_vector(vector_one, scale), v))
def test_scale_vector_2(self): self.assertEqual(vector_math.scale_vector(data.Vector(5, 10, 15), .2), data.Vector(1, 2, 3))
def cast_ray(ray, sphere_list, light = light_obj, ambient = data.Color(), eye_point = data.Point(0, 0, -14)): # intersections contains a list of tuples of spheres and points, ex: [(Sphere_1, Point_1), (Sphere_2, Point_2), ...] intersections = collisions.find_intersection_points(sphere_list, ray) if len(intersections) == 0: return data.Color(1.0, 1.0, 1.0) else: # initializing variable that stores the index and the distance of the tuple with the smallest distance index_of_nearest_sphere = 0 distance_of_nearest_sphere = vector_math.distance_between(intersections[0][1], ray.pt) # loop through all_intersection_point and find the index of the tuple that contains the sphere & intersection with the smallest distance from ray's point for index in range(0, len(intersections)): distance_between_points = vector_math.distance_between(intersections[index][1], ray.pt) if distance_between_points < distance_of_nearest_sphere: index_of_nearest_sphere = index distance_of_nearest_sphere = distance_between_points # storing the sphere and intersection point in to variables for later usage nearest_sphere = intersections[index_of_nearest_sphere][0] nearest_intersection = intersections[index_of_nearest_sphere][1] # ==== color calculation based on ambient light, diffusion, light color and location ==== # Impricision of floats can create collision issues with the sphere where the point lies when using the computed intersection # A point "pe" that is 0.01 above te intersection point will be used instead sphere_normal_vector = collisions.sphere_normal_at_point(nearest_sphere, nearest_intersection) pe_translate_direction_vector = vector_math.scale_vector(sphere_normal_vector, 0.01) # new point PE is now found pe = vector_math.translate_point(nearest_intersection, pe_translate_direction_vector) # === determine whether diffusivity is applicable -- determine if there are any obstruction of light vectors === # comput vector from pe to light point then compute normalized vector from pe to to light point l_dir = vector_math.normalize_vector(vector_math.vector_from_to(pe, light.pt)) n_dot_l_dir = vector_math.dot_vector(sphere_normal_vector, l_dir) # === computing the specular_intensity === reflection_vector = vector_math.difference_vector(l_dir ,vector_math.scale_vector(sphere_normal_vector, 2 * n_dot_l_dir)) #creating the direction vector that points from eye_point to pe v_dir = vector_math.normalize_vector(vector_math.vector_from_to(eye_point, pe)) #Vdir # specular_intensity is defined to be the dot product of reflection_vector and the direction vector from eye_point to pe specular_intensity = vector_math.dot_vector(v_dir, reflection_vector) ambient_color = compute_ambient_color(nearest_sphere, ambient) if n_dot_l_dir > 0: ray_to_point = data.Ray(pe,l_dir) inter = collisions.find_intersection_points(sphere_list, ray_to_point) if len(inter) == 0: diffuse_color = compute_diffuse_color(n_dot_l_dir, light, intersections[index_of_nearest_sphere][0]) if specular_intensity > 0: specular_color = compute_specular_color(light, nearest_sphere, specular_intensity) return add_color(add_color(specular_color, diffuse_color), ambient_color) else: return add_color(diffuse_color, ambient_color) else: return ambient_color elif specular_intensity > 0: specular_color = compute_specular_color(light, nearest_sphere, specular_intensity) return add_color(specular_color, ambient_color) else: return ambient_color