def test_find_intersection_2(self): spheres = [data.Sphere(data.Point(1, 1, 1), 1), data.Sphere(data.Point(2, 2, 2), 1), data.Sphere(data.Point(3, 3, 3), 1)] ray = data.Ray(data.Point(0, 0, 0), data.Vector(1, 0, 0)) result = [] self.assertEqual(collisions.find_intersection_points(spheres, ray) == result, True) pass
def cast_ray(ray, sphere_list, color, light, point): intersections = collisions.find_intersection_points(sphere_list, ray) if intersections != []: colors = getcolor(ray, intersections) sphereR = colors[0] sphereG = colors[1] sphereB = colors[2] diffuse = getDiffuse(ray, intersections, sphere_list, light) sphereDR = diffuse[0] sphereDG = diffuse[1] sphereDB = diffuse[2] specular = getSpecular(ray, intersections, light, point) sphereSR = specular[0] sphereSG = specular[1] sphereSB = specular[2] closest = findClosestSphere(ray, intersections) closestSphere = closest[0] closestPoint = closest[1] finalcolorR = color.r * sphereR * closestSphere.finish.ambient + sphereDR + sphereSR finalcolorG = color.g * sphereG * closestSphere.finish.ambient + sphereDG + sphereSG finalcolorB = color.b * sphereB * closestSphere.finish.ambient + sphereDB + sphereSB finalcolorRGB = data.Color(finalcolorR, finalcolorG, finalcolorB) return finalcolorRGB else: return data.Color(1.0, 1.0, 1.0)
def test_find_intersection(self): sphere_1 = data.Sphere(data.Point(1, 1, 0), 1) sphere_2 = data.Sphere(data.Point(200, 200, 200), 1) s_list = [sphere_1, sphere_2] new_list = [(data.Sphere(data.Point(1, 1, 0), 1), data.Point(0, 1, 0))] r = data.Ray(data.Point(-1, 1, 0), data.Vector(20, 0, 0)) self.assertEqual(collisions.find_intersection_points(s_list, r), new_list)
def test_find_intersection_2(self): sphere_1 = data.Sphere(data.Point(20, 20, 20), 2) sphere_2 = data.Sphere(data.Point(60, 60, 60), 1) s_list = [sphere_1, sphere_2] new_list = [] r = data.Ray(data.Point(0, 0, 0), data.Vector(0, 0, 1)) self.assertEqual(collisions.find_intersection_points(s_list, r), new_list)
def test_find_intersection_points2(self): sphere1 = data.Sphere(data.Point(0,0,0), 3, data.Color(1.0, 1.0, 1.0)) sphere2 = data.Sphere(data.Point(40, 50, 60), 2, data.Color(1.0, 1.0, 1.0)) sphere3 = data.Sphere(data.Point(104, 150, 200), 8, data.Color(1.0, 1.0, 1.0)) sphere_list = [sphere1, sphere2, sphere3] ray2 = data.Ray(data.Point(0,-4, 0), data.Vector(0,15,0)) expected2 = [(data.Point(0,-3,0), sphere1)] self.assertEqual(collisions.find_intersection_points(sphere_list, ray2), expected2)
def test_find_intersection_points1(self): sphere1 = data.Sphere(data.Point(0, -1, -2), 3, data.Color(1.0, 1.0, 1.0)) sphere2 = data.Sphere(data.Point(-4, -5, -6), 7, data.Color(1.0, 1.0, 1.0)) sphere3 = data.Sphere(data.Point(-10, -15, -20), 2, data.Color(1.0, 1.0, 1.0)) sphere_list = [sphere1, sphere2, sphere3] ray1 = data.Ray(data.Point(12, 14, 18), data.Vector(4,6,8)) expected = [] self.assertEqual(collisions.find_intersection_points(sphere_list, ray1), expected)
def test_find_sphere_intersections_0(self): point_ray = data.Point(-10.0, 0.0, 0.0) direction = data.Vector(1.0, 0.0, 0.0) ray = data.Ray(point_ray, direction) point0_sphere = data.Point(0.0, 2.0, 0.0) sphere0 = data.Sphere(point0_sphere, 1.0) collision_points = collisions.find_intersection_points([sphere0], ray) self.assertListAlmostEqual(collision_points, [])
def cast_ray(ray,sphere_list,ambient_color,light,eye_position): inter_list = collisions.find_intersection_points(sphere_list, ray) if inter_list != []: mindex = 0 for i in range(1,len(inter_list)): if (distance(ray.pt,inter_list[i][1]) < distance(ray.pt,inter_list[mindex][1])): mindex = i result_sphere = inter_list[mindex][0] inter_point = inter_list[mindex][1] sphere_color = result_sphere.color sphere_finish = result_sphere.finish sphere_normal = collisions.sphere_normal_at_point(result_sphere, inter_point) pt_off_sphere = find_pt_off_sphere(inter_point,sphere_normal) l_dir = vector_math.normalize_vector( vector_math.vector_from_to(pt_off_sphere, light.pt)) l_dot_n = vector_math.dot_vector(sphere_normal,l_dir) ray_off_to_l = data.Ray(pt_off_sphere,l_dir) inter_list = collisions.find_intersection_points(sphere_list,ray_off_to_l) diffuse_list = determine_diffuse_contribution(result_sphere, pt_off_sphere, light,sphere_normal, sphere_list,l_dir, l_dot_n,ray_off_to_l, inter_list) spec_intensity = determine_specular_contribution(l_dir,l_dot_n, sphere_normal, eye_position, pt_off_sphere, light, result_sphere.finish, ray_off_to_l,inter_list) result_r = ((sphere_color.r * sphere_finish.ambient * ambient_color.r) + diffuse_list[0] + spec_intensity[0]) result_g = ((sphere_color.g * sphere_finish.ambient * ambient_color.g) + diffuse_list[1] + spec_intensity[1]) result_b = ((sphere_color.b * sphere_finish.ambient * ambient_color.b) + diffuse_list[2] + spec_intensity[2]) return data.Color(result_r,result_g,result_b) else: return ambient_color
def test_find_intersection_points_3(self): sphere_list = [ data.Sphere(data.Point(-5, 2, 9), 2, data.Color(0.23, 0.12, 0.2), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0, 0, -9), 1, data.Color(0.24, 0.14, 0.68), data.Finish(0.5, 0.4, 0.5, 0.05)), ] ray = data.Ray(data.Point(0, -7, 0), data.Vector(0, 5, 0)) fip = collisions.find_intersection_points(sphere_list, ray) result_list = [] self.assertEqual(fip, result_list)
def collides_with_spheres(ray, list, pE, light): l = collisions.find_intersection_points(list, ray) d = vector_math.distance(pE, light.pt) s = False if len(l) > 0: for x in l: if vector_math.distance(x[1], pE) < d: s = True return s
def test_find_intersection_1(self): t = math.sqrt(2) spheres = [data.Sphere(data.Point(1, 1, 0), t), data.Sphere(data.Point(2, 2, 0), t), data.Sphere(data.Point(3, 3, 0), t)] ray = data.Ray(data.Point(0, 0, 0), data.Vector(1, 1, 0)) result = [(spheres[0], data.Point(0, 0, 0)), (spheres[1], data.Point(1, 1, 0)), (spheres[2], data.Point(2, 2, 0))] self.assertEqual(collisions.find_intersection_points(spheres, ray) == result, True) pass
def test_find_intersection_points_2(self): sphere_list = [ data.Sphere(data.Point(0, 0, 0), 2, data.Color(0.23, 0.23, 0.23), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(20.3, 20, -100), 1, data.Color(0.45, 0.45, 0.67), data.Finish(0.5, 0.4, 0.5, 0.05)), ] ray = data.Ray(data.Point(0, -7, 0), data.Vector(0, 5, 0)) fip = collisions.find_intersection_points(sphere_list, ray) result_list = [(sphere_list[0], collisions.sphere_intersection_point(ray, sphere_list[0]))] self.assertEqual(fip, result_list)
def point_unobstructed(point, light, sphere_list): light_dir = vector_math.normalize_vector(vector_math.difference_point( light.pt, point)) ray_to_light = data.Ray(point, light_dir) spheres_intersected = collisions.find_intersection_points(sphere_list, ray_to_light) if spheres_intersected == []: return True else: return False
def cast_ray(ray, sphere_list, am_color, light, point): l = collisions.find_intersection_points(sphere_list, ray) if len(l) > 0: tu = smallest_point_distance(ray, l) s = tu[0] p = tu[1] c = s.color return get_color(c, am_color, tu, light, sphere_list) else: return data.Color(1.0, 1.0, 1.0)
def cast_ray(ray, sphere_list, am_color, light, point): l = collisions.find_intersection_points(sphere_list, ray) if len(l) > 0: tu = smallest_point_distance(ray,l) s = tu[0] p = tu[1] c = s.color return get_color(c, am_color, tu, light, sphere_list) else: return data.Color(1.0,1.0,1.0)
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 find_closest_collision(ray, sphere_list): collision_list = collisions.find_intersection_points(sphere_list, ray) if collision_list: closest_sphere_index = 0 for i in range(1, len(collision_list)): if distance(ray.pt, collision_list[i][1]) < distance(ray.pt, collision_list[closest_sphere_index][1]): closest_sphere_index = i return collision_list[closest_sphere_index] else: return None
def test_intersection_points_3(self): s1 = data.Sphere(data.Point(2, 2, 2), math.sqrt(3), data.Color(0, 1, 0), data.Finish(.2, 1, 0, 0)) s2 = data.Sphere(data.Point(-2, -2, 3), 1, data.Color(0, 1, 0), data.Finish(0.2, 1, 0, 0)) s3 = data.Sphere(data.Point(0, 3, 0), 3 * math.sqrt(2), data.Color(0, 1, 0), data.Finish(.2, 1, 0, 0)) ray = data.Ray(data.Point(0, 0, 0), data.Vector(1, 1, 1)) s_list = [s1, s2, s3] result_list = [(s1, data.Point(1, 1, 1)), (s3, data.Point(3, 3, 3))] self.assertEqual(collisions.find_intersection_points(s_list, ray), result_list)
def test_intersection_points_2(self): s1 = data.Sphere(data.Point(2, 0, 2), 2, data.Color(0, 1, 0), data.Finish(.2, 1, 0, 0)) s2 = data.Sphere(data.Point(0, 2, 4), 2, data.Color(0, 1, 0), data.Finish(.2, 1, 0, 0)) s3 = data.Sphere(data.Point(2, 2, 0), 2, data.Color(0, 1, 0), data.Finish(.2, 1, 0, 0)) ray = data.Ray(data.Point(0, 0, -6), data.Vector(0, 0, 1)) s_list = [s1, s2, s3] result_list = [(s1, data.Point(0, 0, 2)), (s2, data.Point(0, 0, 4))] self.assertEqual(collisions.find_intersection_points(s_list, ray), result_list)
def test_find_intersection_points(self): sphere_list = [ data.Sphere(data.Point(0, 0, 0), 2, data.Color(1, 0.5, 0.3), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0, 20, 0), 1, data.Color(1.0, 0.0, 0.4), data.Finish(0.5, 0.4, 0.5, 0.05)), ] ray = data.Ray(data.Point(0, -20, 0), data.Vector(0, 1.3, 0)) fip = collisions.find_intersection_points(sphere_list, ray) result_list = [ (sphere_list[0], collisions.sphere_intersection_point(ray, sphere_list[0])), (sphere_list[1], collisions.sphere_intersection_point(ray, sphere_list[1])), ] self.assertEqual(fip, result_list)
def cast_ray(ray, sphere_list, ambient_color, light, eye_position): inter_list = collisions.find_intersection_points(sphere_list, ray) if inter_list != []: mindex = 0 for i in range(1, len(inter_list)): if (distance(ray.pt, inter_list[i][1]) < distance( ray.pt, inter_list[mindex][1])): mindex = i result_sphere = inter_list[mindex][0] inter_point = inter_list[mindex][1] sphere_color = result_sphere.color sphere_finish = result_sphere.finish sphere_normal = collisions.sphere_normal_at_point( result_sphere, inter_point) pt_off_sphere = find_pt_off_sphere(inter_point, sphere_normal) l_dir = vector_math.normalize_vector( vector_math.vector_from_to(pt_off_sphere, light.pt)) l_dot_n = vector_math.dot_vector(sphere_normal, l_dir) ray_off_to_l = data.Ray(pt_off_sphere, l_dir) inter_list = collisions.find_intersection_points( sphere_list, ray_off_to_l) diffuse_list = determine_diffuse_contribution( result_sphere, pt_off_sphere, light, sphere_normal, sphere_list, l_dir, l_dot_n, ray_off_to_l, inter_list) spec_intensity = determine_specular_contribution( l_dir, l_dot_n, sphere_normal, eye_position, pt_off_sphere, light, result_sphere.finish, ray_off_to_l, inter_list) result_r = ( (sphere_color.r * sphere_finish.ambient * ambient_color.r) + diffuse_list[0] + spec_intensity[0]) result_g = ( (sphere_color.g * sphere_finish.ambient * ambient_color.g) + diffuse_list[1] + spec_intensity[1]) result_b = ( (sphere_color.b * sphere_finish.ambient * ambient_color.b) + diffuse_list[2] + spec_intensity[2]) return data.Color(result_r, result_g, result_b) else: return ambient_color
def cast_ray(ray, sphere_list, ambient, light, eye_point): points= collisions.find_intersection_points(sphere_list, ray) if len(points) == 0: return Color(1.0, 1.0, 1.0) else: #using helper functions below closest= closest_sphere(ray, points) pe=translated_point(closest[0], closest[1]) n=normalize_vector(difference_point(closest[1], closest[0].center)) ldir=normalized_ldir(light.pt, pe) visable=light_visable(n, ldir) spheres_finish_color=finish_sphere(closest[0], ambient) reflection=reflection_vector(ldir, n) vdir=normalized_vdir(eye_point, pe) specular=specular_intensity(vdir, reflection) if not visable: return spheres_finish_color newpoints=collisions.find_intersection_points(sphere_list, Ray(pe, ldir)) if newpoints != []: return spheres_finish_color #no shine else: red=spheres_finish_color.r + (dot_vector(n, ldir) * light.color.r * closest[0].color.r * closest[0].finish.diffuse) green=spheres_finish_color.g + (dot_vector(n, ldir) * light.color.g * closest[0].color.g * closest[0].finish.diffuse) blue=spheres_finish_color.b + (dot_vector(n, ldir) * light.color.b * closest[0].color.b * closest[0].finish.diffuse) if specular<=0: return Color(red, green, blue) #white shine else: red1= red + (light.color.r * closest[0].finish.specular * specular**(1.0/closest[0].finish.roughness)) green1= green + (light.color.g * closest[0].finish.specular * specular**(1.0/closest[0].finish.roughness)) blue1= blue + (light.color.b * closest[0].finish.specular * specular**(1.0/closest[0].finish.roughness)) return Color(red1, green1, blue1)
def test_find_sphere_intersections_1(self): point_ray = data.Point(-10.0, 0.0, 0.0) direction = data.Vector(1.0, 0.0, 0.0) ray = data.Ray(point_ray, direction) point0_sphere = data.Point(0.0, 2.0, 0.0) sphere0 = data.Sphere(point0_sphere, 1.0) point1_sphere = data.Point(0.0, 1.0, 0.0) sphere1 = data.Sphere(point1_sphere, 1.0) point2_sphere = data.Point(0.0, 0.0, 0.0) sphere2 = data.Sphere(point2_sphere, 1.0) collision_points = collisions.find_intersection_points( [sphere0, sphere1, sphere2], ray) self.assertEqual(collision_points[0][1], data.Point(0.0, 0.0, 0.0)) self.assertEqual(collision_points[1][1], data.Point(-1.0, 0.0, 0.0))
def cast_ray(ray,sphere_list,amb,light,eye_point): white = data.Color(1.0,1.0,1.0) inter = collisions.find_intersection_points(sphere_list,ray) if (inter != []): closest_sphere, closest_int = find_closest(inter,ray) diffuse,spec = comp(sphere_list,inter,light,closest_sphere,closest_int,eye_point) val = closest_sphere.finish.ambient final_red = (closest_sphere.color.r*val*amb.r)+diffuse.r+spec.r final_green = (closest_sphere.color.g*val*amb.g)+diffuse.g+spec.g final_blue = (closest_sphere.color.b*val*amb.b)+diffuse.b+spec.b new_color = data.Color(final_red,final_green,final_blue) return new_color else : return white
def cast_ray(ray: data.Ray, sphere_list: typing.List[data.Sphere], am_light_color: data.Color, light: data.Light, eye_point: data.Point) -> data.Color: color = data.Color(1, 1, 1) intersected_spheres = collisions.find_intersection_points(sphere_list, ray) if not intersected_spheres: return color else: sphere_point = auxiliary.closest_sphere(intersected_spheres, ray) light_components = auxiliary.calculate_light_components( sphere_point, sphere_list, eye_point, light) color = auxiliary.calculate_color(sphere_point[0], am_light_color, light_components[0], light_components[1], light) return color
def closest_intersect(ray, sphere_list): """Find the nearest intersection point and sphere""" intersections = find_intersection_points(ray, sphere_list) if len(intersections) < 1: # We don't intersect anything return None # Find the nearest intersection point and its sphere nearest = intersections[0] nearest_dist_sq = length_vector_sq(vector_from_to(ray.pt, nearest[0])) for tup in intersections[1:]: dist_sq = length_vector_sq(vector_from_to(ray.pt, tup[0])) if dist_sq < nearest_dist_sq: nearest = tup nearest_dist_sq = dist_sq return nearest
def test_closestSphere1(self): spheres = [ data.Sphere(data.Point(0.0, 2.0, 0.0), 1.0, data.Color(1, 0, 0), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0.0, 5.0, 0.0), 1.0, data.Color(0, 0, 1), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0.0, 4.0, 0.0), 1.0, data.Color(0, 1, 0), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0.0, 8.0, 0.0), 1.0, data.Color(0, 0, 0), data.Finish(0.5, 0.4, 0.5, 0.05)) ] ray = data.Ray(data.Point(0.0, 0.0, 0.0), data.Vector(0.0, 1.0, 0.0)) intersected_spheres = collisions.find_intersection_points(spheres, ray) result = auxiliary.closest_sphere(intersected_spheres, ray) check = (data.Sphere(data.Point(0.0, 2.0, 0.0), 1.0, data.Color(1, 0, 0), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Point(0, 1, 0)) self.assertEqual(result, check)
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 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 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
def test_find_intersection_points(self): sphere_list = [data.Sphere(data.Point(1, 1, 1), 1), data.Sphere(data.Point(3, 3, 3), 1)] ray = data.Ray(data.Point(1, 1, 1), data.Vector(1, 0, 0)) list_of_intersection_pairs = collisions.find_intersection_points(sphere_list, ray) self.assertTrue(id(list_of_intersection_pairs), (4300121440, 4300122088))
def cast_ray(ray, sphere_list, ambient_color, light, eye_point): reslist = collisions.find_intersection_points(sphere_list, ray) if reslist == []: return data.Color(1, 1, 1) closest_sphere_pair = find_closest_sphere(ray.pt, reslist) sphere_color = closest_sphere_pair[0].color l_dot_n = vector_math.dot_vector( collisions.sphere_normal_at_point(closest_sphere_pair[0], closest_sphere_pair[1]), vector_math.normalize_vector(vector_math.difference_point(light.pt, closest_sphere_pair[1]))) specular_intensity = find_specular_intensity(closest_sphere_pair, light, eye_point, l_dot_n) ambient_component = find_ambient_component(closest_sphere_pair[0], ambient_color) if specular_intensity > 0 and light_hits_point(closest_sphere_pair, sphere_list, light): diffuse_component = find_diffuse_component(l_dot_n, light, closest_sphere_pair[0]) specular_component = find_specular_component(light, closest_sphere_pair[0], specular_intensity) newr = specular_component.r + diffuse_component.r + ambient_component.r newg = specular_component.g + diffuse_component.g + ambient_component.g newb = specular_component.b + diffuse_component.b + ambient_component.b pixelcolor = data.Color(newr, newg, newb) pixelcolor = fix_specular_color(pixelcolor, ambient_component, diffuse_component) elif light_hits_point(closest_sphere_pair, sphere_list, light): diffuse_component = find_diffuse_component(l_dot_n, light, closest_sphere_pair[0]) newr = diffuse_component.r + ambient_component.r newg = diffuse_component.g + ambient_component.g newb = diffuse_component.b + ambient_component.b pixelcolor = data.Color(newr, newg, newb) pixelcolor = fix_color_issues(pixelcolor, ambient_component) # if color is past max/min, sets it to the max/min else: # light doesn't hit ray newr = ambient_component.r newg = ambient_component.g newb = ambient_component.b pixelcolor = data.Color(newr, newg, newb) pixelcolor = fix_color_issues(pixelcolor, ambient_component) return pixelcolor
def test_find_intersection_points1(self): sphere_list = [data.Sphere(data.Point(1, 6, 4), 8), data.Sphere(data.Point(3, 2, 1), 1)] ray = data.Ray(data.Point(2, 1, 4), data.Vector(1, 3, 0)) list_of_intersection_pairs = collisions.find_intersection_points(sphere_list, ray) self.assertTrue(id(list_of_intersection_pairs), (4379206576, 4379236616))