def main(): args = sys.argv sphere_list = get_sphere_list(args[1]) eye_point = data.Point(0.0, 0.0, -14.0) view = [-10.0, 10.0, -7.5, 7.5, 1024, 768] ambient_light = data.Color(1.0, 1.0, 1.0) light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)) if len(args) > 2: try: for i in range(2, len(args)): if args[i] == "-eye": l = args[i:i + 4] eye_point = commandline.get_eye_point(l, [0.0, 0.0, -14.0]) elif args[i] == "-view": l = args[i:i + 7] view = commandline.get_view(l, view) elif args[i] == "-light": l = args[i:i + 7] light = commandline.get_light( l, [-100.0, 100.0, -100.0, 1.5, 1.5, 1.5]) elif args[i] == "-ambient": l = args[i:i + 4] ambient_light = commandline.get_ambient_light( l, [1.0, 1.0, 1.0]) except: print "Something went horribly wrong" cast.cast_all_rays(view[0], view[1], view[2], view[3], view[4], view[5], eye_point, sphere_list, ambient_light, light)
def test_cast_ray_4(self): ray = data.Ray(data.Point(0.0, -3.0, -3.0), data.Vector(2.0, 1.0, 1.0)) sphere1 = data.Sphere(data.Point(0.0, 2.0, 2.0), 6.0, data.Color(1.0, 0.0, 0.0)) sphere2 = data.Sphere(data.Point(-10.0, -15.0, -20.0), 2.0, data.Color(0.0, 0.0, 1.0)) sphere_list = [sphere1, sphere2] casted = cast.cast_ray(ray, sphere_list) self.assertEqual(casted, data.Color(1.0, 0.0, 0.0))
def test_cast_ray_5(self): ray = data.Ray(data.Point(0.0, 0.0, 0.0), data.Vector(5.0, 0.0, 0.0)) sphere1 = data.Sphere(data.Point(5.0, 0.0, -5.0), 5.0, data.Color(1.0, 0.0, 0.0)) sphere2 = data.Sphere(data.Point(17.0, 0.0, 5.0), 5.0, data.Color(0.0, 0.0, 1.0)) sphere_list = [sphere1, sphere2] casted = cast.cast_ray(ray, sphere_list) self.assertEqual(casted, data.Color(1.0, 0.0, 0.0))
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_cast_ray(self): r = data.Ray(data.Point(0, 0, 0), data.Vector(0, 50, 0)) sphere_list = [ data.Sphere(data.Point(0, 50, 0), 10, data.Color(0.0, 1.0, 1.0)), data.Sphere(data.Point(0, 100, 0), 10, data.Color(1.0, 1.0, 0.0)) ] self.assertEqual(cast.cast_ray(r, sphere_list), data.Color(0.0, 1.0, 1.0))
def compute_specular_color(light, sphere, specular_intensity): if sphere.finish.roughness == 0: return data.Color(0.0, 0.0, 0.0) else: specular_r = light.color.r * sphere.finish.specular * (specular_intensity ** (1 / sphere.finish.roughness)) specular_g = light.color.g * sphere.finish.specular * (specular_intensity ** (1 / sphere.finish.roughness)) specular_b = light.color.b * sphere.finish.specular * (specular_intensity ** (1 / sphere.finish.roughness)) return data.Color(specular_r, specular_g, specular_b)
def cmd_line(command_arguments): eye = data.Point(0, 0, -14) min_x = -10.0 max_x = 10.0 min_y = -7.5 max_y = 7.5 width = 1024.0 height = 768.0 light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)) ambient = data.Color(1.0, 1.0, 1.0) for idx, arg in enumerate(command_arguments[2:]): if arg == "-eye": try: eye = data.Point(float(command_arguments[idx + 3]), float(command_arguments[idx + 4]), float(command_arguments[idx + 5])) except: print "argument error in eye" sys.exit() elif arg == "-view": try: min_x = float(command_arguments[idx + 3]) max_x = float(command_arguments[idx + 4]) min_y = float(command_arguments[idx + 5]) max_y = float(command_arguments[idx + 6]) width = float(command_arguments[idx + 7]) height = float(command_arguments[idx + 8]) except: print "argument error in view" sys.exit() elif arg == "-light": try: light_point = data.Point(float(command_arguments[idx + 3]), float(command_arguments[idx + 4]), float(command_arguments[idx + 5])) light_color = data.Color(float(command_arguments[idx + 6]), float(command_arguments[idx + 7]), float(command_arguments[idx + 8])) light = data.Light(light_point, light_color) except: print "argument error in light" sys.exit() elif arg == "-ambient": try: ambient = data.Color(float(command_arguments[idx + 3]), float(command_arguments[idx + 4]), float(command_arguments[idx + 5])) except: print "argument error in ambient" else: try: test_float = float(arg) except: print "usage: python ray_caster.py <filename> [-eye x y z] [-view min_x max_x min_y max_y width height] [-light x y z r g b] [-ambient r g b]" arg_list = [eye, min_x, max_x, min_y, max_y, width, height, light, ambient] return arg_list
def test_calculateColor2(self): result = auxiliary.calculate_color( data.Sphere(data.Point(0.0, 2.0, 0.0), 1.0, data.Color(1, 1, 1), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Color(1, 1, 1), 1, 1, data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5))) check = data.Color(1.85, 1.85, 1.85) self.assertEqual(result, check)
def test_get_diffuse_2(self): lDir = 2 light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)) s = data.Sphere(data.Point(1.0, 1.0, 0.0), 2.0, data.Color(0.0, 0.0, 1.0), data.Finish(.2, .4, .5, .05)) diffuse = .4 expected = data.Color(0, 0, 1.2) self.assertEqual(cast.get_diffuse(lDir, light, s, diffuse), expected)
def get_color(c1, c2, tu, light, s_list): s = tu[0] p = tu[1] f = s.finish ambientColor = data.Color(c1.r * c2.r * f.ambient, c1.g * c2.g * f.ambient, c1.b * c2.b * f.ambient) diffuseColor = get_diffuse_color(tu, light, s_list) color = data.Color(ambientColor.r + diffuseColor.r, ambientColor.g + diffuseColor.g, ambientColor.b + diffuseColor.b) return color
def test1(self): result = commandline.process_cmdArguments( ['', 'test_file', '-ambient', '0.9', '0.9', '0.9']) sphere1 = data.Sphere(data.Point(1, 1, 0), 2, data.Color(1, 0, 1), data.Finish(0.2, 0.4, 0.5, 0.05)) sphere2 = data.Sphere(data.Point(8, -10, 110), 100, data.Color(0.2, 0.2, 0.6), data.Finish(0.4, 0.8, 0, 0.05)) check = (data.Light(data.Point(-100, 100, -100), data.Color(1.5, 1.5, 1.5)), data.Color(0.9, 0.9, 0.9), [sphere1, sphere2]) self.assertEqual(result, check)
def true_color(list, eye_point, color, light, sphere_list, point): mindex = 0 for i in range(1, len(list)): n = dist_from_eye(list[mindex][1], eye_point) m = dist_from_eye(list[i][1], eye_point) if m < n: mindex = i r1 = list[mindex][0].color.r * list[mindex][0].finish.ambient * color g1 = list[mindex][0].color.g * list[mindex][0].finish.ambient * color b1 = list[mindex][0].color.b * list[mindex][0].finish.ambient * color color_with_finish = data.Color(r1, g1, b1) M = scale_vector(sphere_normal_at_point(list[mindex][0], list[mindex][1])\ , 0.01) pe = translate_point(list[mindex][1], M) N = scale_vector(M, 100) ldir = normalize_vector(vector_from_to(pe, light.pt)) dot = dot_vector(N, ldir) if dot > 0: #light is visible lray = data.Ray(pe, ldir) if is_closer_sphere(sphere_list, lray) == True: dr = dot * light.color.r * list[mindex][0].color.r * \ list[mindex][0].finish.diffuse dg = dot * light.color.g * list[mindex][0].color.g * \ list[mindex][0].finish.diffuse db = dot * light.color.b * list[mindex][0].color.b * \ list[mindex][0].finish.diffuse rvec = difference_vector(ldir, scale_vector(N, 2 * dot)) vdir = normalize_vector(vector_from_to(point, pe)) spec = dot_vector(rvec, vdir) if spec > 0: #specular intensity contributes sr = light.color.r * list[mindex][0].finish.specular * \ (spec ** (1 / float(list[mindex][0].finish.roughness))) sg = light.color.g * list[mindex][0].finish.specular * \ (spec ** (1 / float(list[mindex][0].finish.roughness))) sb = light.color.b * list[mindex][0].finish.specular * \ (spec ** (1 / float(list[mindex][0].finish.roughness))) return data.Color((r1 + dr + sr), (g1 + dg + sg), (b1 + db + sb)) else: #specular intensity does not contribute return data.Color((r1 + dr), (g1 + dg), (b1 + db)) else: #another sphere in way return color_with_finish else: #light is behind return color_with_finish
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_collides_with_spheres_1(self): s = data.Sphere(data.Point(0.0, 0.0, 0.0), 2.0, data.Color(1.0, 0.0, 0.0), data.Finish(.2, .4, .5, .05)) s1 = data.Sphere(data.Point(5.0, 5.0, 5.0), 2.0, data.Color(1.0, 0.0, 0.0), data.Finish(.2, .4, .5, .05)) ray = data.Ray(data.Point(-5, 0, 0), data.Vector(1, 0, 0)) light = data.Light(data.Point(0, 0, -14), data.Color(1, 1, 1)) expected = False self.assertEqual( cast.collides_with_spheres(ray, [s, s1], data.Point(-3, -3, -3), light), expected)
def test_cast_ray_1(self): sphere_list = [ data.Sphere(data.Point(0, 0, 0), 1, data.Color(0, 0, 0), data.Finish(.2, 1, 0, 0)) ] ray = data.Ray(data.Point(0, 0, -15), data.Vector(0, 0, 1)) light = data.Light(data.Point(0, 0, 3), data.Color(1, 1, 1)) ambient_color = data.Color(1, 1, 1) eye_point = data.Point(0, 0, -14) calc_color = cast.cast_ray(ray, sphere_list, ambient_color, light, eye_point) exp_color = data.Color(0, 0, 0) self.assertEqual(calc_color, exp_color)
def get_diffuse_color(tu, light, s_list): pE = get_pe(tu) N = collisions.sphere_normal_at_point(tu[0], tu[1]) lDir = vector_math.vector_from_to(pE, light.pt) lDir = vector_math.normalize_vector(lDir) lDirection = vector_math.dot_vector(N, lDir) sI = get_specular_intensity(lDir, lDirection, N, pE, light, tu[0]) ray = data.Ray(pE, lDir) if lDirection <= 0 or collides_with_spheres(ray, s_list, pE, light): return data.Color(0, 0, 0) dif = get_diffuse(lDirection, light, tu[0], tu[0].finish.diffuse) finalColor = data.Color(sI.r + dif.r, sI.g + dif.g, sI.b + dif.b) return finalColor
def get_ambient(argv): amb_values = [1.0,1.0,1.0] amb_i = get_flag_index(argv,'-ambient') if amb_i != None: try: for x in range(1,4): amb_values[x - 1] = float(argv[amb_i + x]) except: print 'Ambient arguments cannot be converted into numeric values.' amb_values = [1.0,1.0,1.0] return data.Color(amb_values[0],amb_values[1],amb_values[2]) else: return data.Color(amb_values[0],amb_values[1],amb_values[2])
def test_get_specular_intensity_2(self): lDir = data.Vector(.5, 10, 3) lDirection = 3 N = data.Vector(2, 2, 3) pE = data.Point(2, 3, -3) light = data.Light(data.Point(0, 0, -14), data.Color(1.5, 1.5, 1.5)) sphere = data.Sphere(data.Point(0.0, 0.0, 0.0), 1.0, data.Color(1.0, .5, 1.0), data.Finish(.2, .4, .5, .05)) result = cast.get_specular_intensity(lDir, lDirection, N, pE, light, sphere) expected = data.Color(0, 0, 0) self.assertEqual(result, expected)
def test_get_difuse_color_2(self): light = data.Light(data.Point(-5.0, 10.0, -10.0), data.Color(1.5, 1.5, 1.5)) a = data.Sphere(data.Point(0, 0, 0), 4.0, data.Color(.5, 0.3, .8), data.Finish(.2, .4, .5, .05)) b = data.Sphere(data.Point(.5, 1.5, -3.0), .5, data.Color(1.0, 0.0, 0.0), data.Finish(.4, .4, .5, .05)) list = [a, b] t = (a, data.Point(2.0, 0, 0)) result = cast.get_diffuse_color(t, light, list) expected = data.Color(0, 0, 0) self.assertEqual(result, expected)
def test_get_color_2(self): ambient = data.Color(.2, .2, .2) light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)) a = data.Sphere(data.Point(0, 0, 0), 2.0, data.Color(.5, 0.3, .8), data.Finish(.2, .4, .5, .05)) b = data.Sphere(data.Point(.5, 1.5, -3.0), .5, data.Color(1.0, 0.0, 0.0), data.Finish(.4, .4, .5, .05)) list = [a, b] t = (a, data.Point(2.0, 0, 0)) result = cast.get_color(a.color, ambient, t, light, list) expected = data.Color(0.02, 0.012, 0.032) self.assertEqual(result, expected)
def test_sphere(self): point = data.Point(1, 2, 3) color = data.Color(0, 0, 0) finish = data.Finish(0.2, 1, 0, 0) sphere = data.Sphere(point, 1.0, color, finish) self.assertAlmostEqual(sphere.center.x, 1) self.assertAlmostEqual(sphere.center.y, 2) self.assertAlmostEqual(sphere.center.z, 3) self.assertEqual(sphere.center, point) self.assertAlmostEqual(sphere.radius, 1.0) self.assertEqual(sphere.center, data.Point(1, 2, 3)) self.assertEqual( sphere, data.Sphere(data.Point(1, 2, 3), 1, data.Color(0, 0, 0), data.Finish(.2, 1, 0, 0)))
def test_sphere_2(self): point2 = data.Point(0, -1, -2.0) color2 = data.Color(0, 1, 0) finish2 = data.Finish(0.2, 1, 0, 0) sphere2 = data.Sphere(point2, 2.5, color2, finish2) self.assertAlmostEqual(sphere2.center.x, 0) self.assertAlmostEqual(sphere2.center.y, -1) self.assertAlmostEqual(sphere2.center.z, -2.0) self.assertEqual(sphere2.center, point2) self.assertAlmostEqual(sphere2.radius, 2.5) self.assertEqual(point2, data.Point(0, -1, -2)) self.assertEqual( sphere2, data.Sphere(data.Point(0, -1, -2), 2.5, data.Color(0, 1, 0), data.Finish(0.2, 1, 0, 0)))
def test_cast_ray_1(self): pt = data.Point(0,0,0) dir = data.Vector(0,0,1) ray = data.Ray(pt,dir) center_1 = data.Point(12,0,0) center_2 = data.Point(0,5,0) center_3 = data.Point(5,0,0) center_4 = data.Point(50,0,0) radius = 2 color = data.Color(1,0,.1) finish = data.Finish(1,.2,1,1) light = data.Light(data.Color(1.5,1.5,1.5),data.Point(0,0,0)) eye_point = data.Point(1,1,1) sphere_list = [data.Sphere(center_1,radius,color,finish),data.Sphere(center_2,radius,color,finish),data.Sphere(center_3,radius,color,finish),data.Sphere(center_4,radius,color,finish)] test_cast_ray_1 = cast.cast_ray(ray,sphere_list,finish,light,eye_point) self.assertTrue(test_cast_ray_1 == data.Color(1,1,1))
def validate_light(argv, i): try: return data.Light(data.Point(float(argv[i+1]), float(argv[i+2]), \ float(argv[i+3])), data.Color(float(argv[i+4]), float(argv[i+5]), \ float(argv[i+6]))) except: return DEFAULT_LIGHT
def fix_color_issues(init_color, ambient_component): maxn = 1 minr = min(ambient_component.r, 1) ming = min(ambient_component.g, 1) minb = min(ambient_component.b, 1) r = init_color.r g = init_color.g b = init_color.b if r > maxn: r = maxn elif r < minr: r = minr if g > maxn: g = maxn elif g < ming: g = ming if b > maxn: b = maxn elif b < minb: b = minb return data.Color(r, g, b)
def fix_specular_color(color, ambient_component, diffuse_component): r = color.r g = color.g b = color.b maxn = 1 minr = min(ambient_component.r + diffuse_component.r, 1) ming = min(ambient_component.g + diffuse_component.g, 1) minb = min(ambient_component.b + diffuse_component.b, 1) if r > maxn: r = maxn elif r < minr: r = minr if g > maxn: g = maxn elif g < ming: g = ming if b > maxn: b = maxn elif b < minb: b = minb return data.Color(r, g, b)
def test_computePe2(self): result = auxiliary.compute_Pe( (data.Sphere(data.Point(0.0, 2.0, 0.0), 1.0, data.Color(1, 1, 1), data.Finish(0.5, 0.4, 0.5, 0.05)), data.Point(0, 1, 0))) check = data.Point(0, 0.99, 0) self.assertEqual(result, check)
def test_cast_ray_2(self): pt = data.Point(0,0,0) dir = data.Vector(0,1,0) ray = data.Ray(pt,dir) center_1 = data.Point(0,0,5) center_2 = data.Point(0,5,0) center_3 = data.Point(5,0,0) radius = 2 color = data.Color(0,1,0) color_1 = data.Color(0,0,0) finish = data.Finish(1,1,1,1) light = data.Light(data.Point(1,1,1),data.Color(1,1,1)) eye_point = data.Point(1,1,1) ambient = data.Color(1,1,1) sphere_list = [data.Sphere(center_1,radius,color_1,finish),data.Sphere(center_2,radius,color,finish),data.Sphere(center_3,radius,color_1,finish)] test_cast_ray_2 = cast.cast_ray(ray,sphere_list,ambient,light,eye_point) self.assertTrue(test_cast_ray_2 == data.Color(0.328870320968,2.14399924358,0.328870320968))
def test_get_pE_2(self): sphere = data.Sphere(data.Point(0.0, 0.0, 0.0), 2.0, data.Color(0.0, 0.0, 1.0), data.Finish(.2, .4, .5, .05)) tuple = (sphere, data.Point(0, 2, 0)) pe = cast.get_pe(tuple) expected = data.Point(0, 2.01, 0) self.assertEqual(pe, expected)