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 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 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 test_cast_ray(self): sph1 = data.Sphere(data.Point(0, 3, 3), 5, data.Color(1.0, 1.0, 0.0), \ data.Finish(0.5, 0.4, 0.5, 0.05)) sph2 = data.Sphere(data.Point(5, 1, 2), 2, data.Color(0.0, 1.0, 1.0), \ data.Finish(0.9, 0.4, 0.5, 0.05)) sph3 = data.Sphere(data.Point(2, 2, 2), 4, data.Color(1.0, 0.0, 1.0), \ data.Finish(0.8, 0.4, 0.5, 0.05)) N = [sph1, sph2, sph3] ray1 = data.Ray(data.Point(4, 4, 4), data.Vector(-2, -2, -2)) self.assertTrue(cast.cast_ray(ray1, N, 0.8, data.Light(data.Point(-100.0, \ 100.0, -100.0), data.Color(1.5, 1.5, 1.5)), data.Point(0.0, 0.0, -14.0)), \ data.Color(0.8, 0.8, 0.8)) ray2 = data.Ray(data.Point(3, 5, 1), data.Vector(-3, 1, 4)) self.assertTrue(cast.cast_ray(ray2, N, 0.5, data.Light(data.Point(-100.0, \ 100.0, -100.0), data.Color(1.5, 1.5, 1.5)), data.Point(0.0, 0.0, -14.0)), \ data.Color(1.0, 1.0, 1.0))
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 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 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_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_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 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 get_light(l, light): result = [] for i in range(1, len(l)): try: result.append(float(l[i])) except: print "ERROR-- parsing light" result.append(light[i]) position = data.Point(result[0], result[1], result[2]) color = data.Color(result[3], result[4], result[5]) return data.Light(position, color)
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 get_light(argv): light_values = [-100.0,100.0,-100.0,1.5,1.5,1.5] light_i = get_flag_index(argv,'-light') if light_i != None: try: for x in range(1,7): light_values[x - 1] = float(argv[light_i + x]) except: print 'Light arguments cannot be converted into numeric values.' light_values = [-100.0,100.0,-100.0,1.5,1.5,1.5] return data.Light(data.Point(light_values[0], light_values[1], light_values[2]), data.Color(light_values[3], light_values[4], light_values[5])) else: return data.Light(data.Point(light_values[0], light_values[1], light_values[2]), data.Color(light_values[3], light_values[4], light_values[5]))
def process_cmdArguments( args: typing.List[str] ) -> typing.Optional[typing.Tuple[data.Light, data.Color, typing.List[data.Sphere]]]: light = data.Light(data.Point(-100, 100, -100), data.Color(1.5, 1.5, 1.5)) ambient = data.Color(1, 1, 1) if len(args) >= 3: for idx in range(len(args)): try: if args[idx] == '-light': light = data.Light( data.Point(float(args[idx + 1]), float(args[idx + 2]), float(args[idx + 3])), data.Color(float(args[idx + 4]), float(args[idx + 5]), float(args[idx + 6]))) except: print( 'Incorrect format: Default Values for light will be used') try: if args[idx] == '-ambient': ambient = data.Color(float(args[idx + 1]), float(args[idx + 2]), float(args[idx + 3])) except: print( 'Incorrect format: Default Values for ambient light color will be used' ) if len(args) >= 2: file_name = args[1] sphere_list = file_funcs.read_from_file(file_name) return (light, ambient, sphere_list) else: print( "python3 ray_caster.py <filename> [-light x y z r g b] [-ambient r g b]" ) exit(1)
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 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_cast_ray2(self): spheres = [ data.Sphere(data.Point(6.0, 0.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)) result = cast.cast_ray( ray, spheres, data.Color(1, 1, 1), data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)), data.Point(0, 0, -14)) self.assertEqual(result, data.Color(0, 0, 0.5))
def test_cast_ray_1(self): finish = data.Finish(.4, .4, .5, .05) one = data.Sphere(data.Point(2, 2, 0), 1.0, data.Color(.4, .2, .1), finish) two = data.Sphere(data.Point(6, 6, 0), 2.0, data.Color(.2, .3, .5), finish) three = data.Sphere(data.Point(-2, -2, 0), 1.0, data.Color(1, 1, 1), finish) four = data.Sphere(data.Point(-6, -6, 0), 15.0, data.Color(.5, .5, .5), finish) ray = data.Ray(data.Point(0, 0, -14), data.Vector(0, 0, 1)) l = [one, two, three, four] light = data.Light(data.Point(0, 0, -14), data.Color(1.5, 1.5, 1.5)) ambient_color = data.Color(.2, .2, .2) result = cast.cast_ray(ray, l, ambient_color, light, data.Point(0, 0, -14)) expected = data.Color(0.286793135633, 0.286793135633, 0.286793135633) self.assertEqual(result, expected)
def test_calculate_light_component2(self): spheres = [ data.Sphere(data.Point(1, 1, 0), 2, data.Color(0, 0, 1), data.Finish(0.2, 0.4, 0.5, 0.05)), data.Sphere(data.Point(0.5, 1.5, -3), 0.5, data.Color(1, 0, 0), data.Finish(0.2, 0.4, 0.5, 0.05)) ] intersection_pt = collisions.sphere_intersection_point( data.Ray(data.Point(0, 0, -14), data.Vector(0.5, 1.5, 11)), data.Sphere(data.Point(0.5, 1.5, -3), 0.5, data.Color(1, 0, 0), data.Finish(0.2, 0.4, 0.5, 0.05))) eye_pt = data.Point(0, 0, -14) light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, 1.5)) result = auxiliary.calculate_light_components( (data.Sphere(data.Point(0.5, 1.5, -3), 0.5, data.Color(1, 0, 0), data.Finish(0.2, 0.4, 0.5, 0.05)), intersection_pt), spheres, eye_pt, light) check = (0.5082198628016603, 0.5082198628016605) self.assertEqual(result, check)
def create_picture(): eyept = data.Point(0.0, 0.0, -14.0) sph1 = data.Sphere(data.Point(1.0, 1.0, 0.0), 2.0, data.Color(0.0, 0.0, \ 1.0), data.Finish(0.2, 0.4, 0.5, 0.05)) sph2 = data.Sphere(data.Point(0.5, 1.5, -3.0), 0.5, data.Color(1.0, 0.0, \ 0.0), data.Finish(0.4, 0.4, 0.5, 0.05)) S = [sph1, sph2] min_x = -10 max_x = 10 min_y = -7.5 max_y = 7.5 width = 1024 height = 768 ambient = 1.0 light = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, 1.5, \ 1.5)) cast.cast_all_rays(min_x, max_x, min_y, max_y, width, height, eyept, S, \ ambient, light)
def test_light_1(self): light = data.Light(data.Point(0, 0, 0), data.Color(1, 1, 1)) self.assertEqual(light.pt, data.Point(0, 0, 0)) self.assertEqual(light.color, data.Color(1, 1, 1))
import data import vector_math import collisions light_obj = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(0, 0, 0)) def compute_ambient_color(sphere, ambient): ambient_r = sphere.color.r * sphere.finish.ambient * ambient.r ambient_b = sphere.color.g * sphere.finish.ambient * ambient.g ambient_g = sphere.color.b * sphere.finish.ambient * ambient.b return data.Color(ambient_r, ambient_b, ambient_g) def compute_diffuse_color(n_dot_l_dir, light, sphere): diffuse_r = sphere.color.r * n_dot_l_dir * light.color.r * sphere.finish.diffuse diffuse_g = sphere.color.g * n_dot_l_dir * light.color.g * sphere.finish.diffuse diffuse_b = sphere.color.b * n_dot_l_dir * light.color.b * sphere.finish.diffuse return data.Color(diffuse_r, diffuse_g, diffuse_b) 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 add_color(color1,color2): r = color1.r + color2.r
import sys import data import cast DEFAULT_EYE = data.Point(0.0, 0.0, -14.0) DEFAULT_VIEW = (-10, 10, -7.5, 7.5, 1024, 768) DEFAULT_LIGHT = data.Light(data.Point(-100.0, 100.0, -100.0), data.Color(1.5, \ 1.5, 1.5)) DEFAULT_AMB = data.Color(1.0, 1.0, 1.0) def main(argv): validate_cmdline(argv) spheres = [] with open_file(argv[1], 'rb') as f: spheres = process_file(f) flags = command_flags(argv) return [spheres, flags] def validate_cmdline(argv): if len(argv) >= 2: pass else: 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]' exit(1) def open_file(name, mode):
import data import cast eyePoint = data.Point(0.0, 0.0, -14.0) 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)) a = 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)) 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)) cast.cast_all_rays(-10.0, 10.0, -7.5, 7.5, 1024, 768, eyePoint, [a, b], ambient_light, light)
def test_light1(self): result = data.Light(data.Point(0, 0, 0), data.Color(1, 1, 1)) self.assertEqual(result.pt, data.Point(0, 0, 0)) self.assertEqual(result.color, data.Color(1, 1, 1))
def test_light2(self): light1 = data.Light(data.Point(1, 2, 3), data.Color(0, 0, 0)) light2 = data.Light(data.Point(1, 2, 3), data.Color(0, 0, 0)) self.assertEqual(light1, light2)
def test_light_2(self): light = data.Light(data.Point(1, 5, 2), data.Color(.5, .25, .75)) self.assertEqual(light.pt, data.Point(1, 5, 2)) self.assertEqual(light.color, data.Color(.5, .25, .75))
import commandline import cast import collisions import vector_math import data defaults = { "min_x": -10, "max_x": 10, "min_y": -7.5, "max_y": 7.5, "width": 1024, "height": 768, "eye_point": data.Point(0, 0, -14), "ambient_color": data.Color(1, 1, 1), "light": data.Light(data.Point(-100, 100, -100), data.Color(1.5, 1.5, 1.5)), "outfile": "image.ppm" } def main(argv): argument_errors = commandline.argment_errors(defaults, argv) if not argument_errors[0]: print "Argument Error, a valid .in file is needed as the first argument." exit(1) sphere_list = commandline.get_sphere_list(argv[1]) arg_dict = commandline.find_cast_args(defaults, argv) cast.cast_all_rays(defaults["min_x"], defaults["max_x"], defaults["min_y"],