def testOctree(): bv = BoundingVolume(single=True) bv.BBv2 = np.array([-1, -1, -1]) bv.BBv8 = np.array([1, 1, 1]) bv.finalizeAABB() s1 = Sphere([0, 0, 0], 1, [0, 0, 0]) print("testing BoundingVolume.isPointInBoundingVolume") assertTrue(bv.isPointInBoundingVolume(s1, [0, 0, 0])) assertTrue(bv.isPointInBoundingVolume(s1, [1, 0, 0])) assertTrue(bv.isPointInBoundingVolume(s1, [0, 1, 0])) assertTrue(bv.isPointInBoundingVolume(s1, [0, 0, 1])) assertTrue(bv.isPointInBoundingVolume(s1, [0, 0.5, 0])) assertTrue(bv.isPointInBoundingVolume(s1, [0, 1, 1])) assertFalse(bv.isPointInBoundingVolume(s1, [0, 0, 1.1])) assertFalse(bv.isPointInBoundingVolume(s1, [0, 1, 1.1])) assertFalse(bv.isPointInBoundingVolume(s1, [0, 1, -1.1])) assertFalse(bv.isPointInBoundingVolume(s1, [9999, 0, -999])) assertFalse(bv.isPointInBoundingVolume(s1, [9999, 0, -999])) print("testing BoundingVolume.intersectsWithRay axis aligned") rFromLeftMid = Ray(np.array([0.0, -10.0, 0.0]), np.array([0.0, 0.9, 0.0])) rFromRightMid = Ray(np.array([0, 10, 0]), np.array([0, -0.8, 0])) fromTopMid = Ray(np.array([-10, 0, 0]), np.array([1, 0, 0])) fromBottomMid = Ray(np.array([10, 0, 0]), np.array([-0.9, 0, 0])) fromFrontMid = Ray(np.array([0, 0, -10]), np.array([0, 0, 1])) fromBackMid = Ray(np.array([0, 0, 10]), np.array([0, 0, -0.7])) assertTrue(bv.intersectsWithRay(rFromLeftMid)) assertTrue(bv.intersectsWithRay(rFromRightMid)) assertTrue(bv.intersectsWithRay(fromTopMid)) assertTrue(bv.intersectsWithRay(fromBottomMid)) assertTrue(bv.intersectsWithRay(fromFrontMid)) assertTrue(bv.intersectsWithRay(fromBackMid)) rFromLeftMid.o += np.array([10, 0, 0]) assertFalse(bv.intersectsWithRay(rFromLeftMid)) #todo add some more negative tests return
def render(self, scene): width = scene.width height = scene.height aspect_ratio = float(width) / height x0 = -1.0 x1 = +1.0 xstep = (x1 - x0) / (width - 1) y0 = -1.0 / aspect_ratio y1 = +1.0 / aspect_ratio ystep = (y1 - y0) / (height - 1) camera = scene.camera pixels = Image(width, height) # Create a bland image for j in range(height): y = y0 + j * ystep for i in range(width): x = x0 + i * xstep ray = Ray(camera, Point(x, y) - camera) pixels.set_pixel(i, j, self.ray_trace(ray, scene)) return pixels
def render(self, scene): width = scene.width height = scene.height aspect_ratio = float(width / height) x_0 = -1.0 x_1 = +1.0 x_step = (x_1 - x_0) / (width - 1) y_0 = -1.0 / aspect_ratio y_1 = +1.0 / aspect_ratio y_step = (y_1 - y_0) / (height - 1) camera = scene.camera pixels = Image(width, height) for j in range(height): y = y_0 + j * y_step for i in range(width): x = x_0 + i * x_step ray = Ray(camera, Point(x, y) - camera) pixels.set_pixel(i, j, self.ray_trace(ray, scene)) print("{:3.0f}%".format(float(j) / float(height) * 100), end="\r") return pixels
def ray_trace(self, ray, scene, x, y, depth=0): color = Color(0, 0, 0) dist_hit, obj_hit = self.find_nearest(ray, scene) # print(x) if obj_hit is None: return color if (obj_hit.id not in self.actual_objects_hit_pixel): # print(x) # print(self.actual_objects_hit_pixel[x-1]) self.actual_objects_hit_pixel[x][y].append(obj_hit.id) hit_pos = ray.origin + ray.direction * dist_hit hit_normal = obj_hit.normalf(hit_pos) color += self.color_at(obj_hit, hit_pos, hit_normal, scene) if depth < self.MAX_DEPTH: new_ray_pos = hit_pos + hit_normal * self.MIN_DISPLACE new_ray_dir=ray.direction - 2 * \ ray.direction.dot_product(hit_normal) * hit_normal new_ray = Ray(new_ray_pos, new_ray_dir) # new color with the reflected cofficient color += self.ray_trace(new_ray, scene, x, y, depth + 1) * obj_hit.material.reflection return color
def maxPixelRender(self,width,height,camera,pixels,scene,y0,ystep,x0,xstep): #Only raytraces a maximun ammount of #Gets a pixel pixels max= width*height*0.75 flag= True for j in range(height): y = y0 + j * ystep for i in range(width): x = x0 + i * xstep pixels.set_pixel(i, j, Color.from_hex("#000000"))#Creates a black pixel print("Terminado") while flag: #for j in range(height): j=random.randint(0,height-1) y = y0 + j * ystep i=random.randint(0,width-1) x = x0 + i * xstep #The raytrace of the pixel, otherwise creates a black pixel ray = Ray(camera, Point(x, y) - camera) #Creates a ray from the camera to the point pixels.set_pixel(i, j, self.ray_trace(ray, scene)) #Raytracing method max-=1 #Decreases the max pixels allowed if(max<=0): flag=False #print("{:3.0f}%".format(float(j) / float(height) * 100), end="\r") #Progress bar return pixels
def MonteCarlo(self, intersection, scene, sampleCount=64, sample=None): res = 0.0 minHitDist = np.infty for i in range(sampleCount): h2Vec = self.getCosineWeightedPointH2() d = self.transformH2toR3(h2Vec, intersection.n) r = Ray(intersection.pos + 0.001 * intersection.n, d) ni = Intersection() if (scene.intersect(r, ni)): if (r.t < minHitDist): minHitDist = r.t res += ni.ell * ni.color #if a sample is given, add the current hemisphere ray to average light direction #weight it by how much impact it has on the resulting radiance if ((sample != None) & (ni.ell > 0)): sample.avgLightDir += d * ni.ell v = self.transformH2toR3( np.array( [h2Vec[0], (h2Vec[1] - np.pi / 4) % (2 * np.pi)]), intersection.n) sample.rotGrad += -v * np.tan(h2Vec[0]) * ni.ell res *= np.pi / sampleCount if (sample != None): #normalize average light direction if (np.linalg.norm(sample.avgLightDir > 0)): sample.avgLightDir = sample.avgLightDir / np.linalg.norm( sample.avgLightDir) #min Hit distance is the closest intersection found while shooting rays in the hemisphere sample.minHitDist = minHitDist sample.irradiance = res #+ intersection.ell sample.rotGrad *= np.pi / sampleCount return res #+ intersection.ell
def test_refracted_color_with_refracted_ray(self): # this test failed! w = World() A = w.objs[0] A.material.ambient = 1 A.material.pattern = TestPattern() B = w.objs[1] B.material.transparency = 1.0 B.material.refractive_index = 1.5 r = Ray(Point(0, 0, 0.1), Vector(0, 1, 0)) ls = [ Intersection(-0.9899, A), Intersection(-0.4899, B), Intersection(0.4899, B), Intersection(0.9899, A) ] xs = Intersections(ls) comps = xs[2].prepare_computations(r, xs) c = w.refracted_color(comps, 5) # the expected answer is color(0, 0.99888, 0.04725) self.assertTrue(c == Color(0, 0.99888, 0.04721))
def render(self, scene): width = scene.width height = scene.height aspectRatio = float(width) / height x0 = -1.0 x1 = 1.0 xStep = (x1 - x0) / (width - 1) y0 = -1.0 / aspectRatio y1 = 1.0 / aspectRatio # y0 = -1.0 # y1 = 1.0 yStep = (y1 - y0) / (height - 1) camera = scene.camera pixels = Image(width, height) for j in range(height): y = y0 + j * yStep for i in range(width): x = x0 + i * xStep ray = Ray(camera, Point(x, y) - camera) pixels.setPixel(i, j, self.rayTrace(ray, scene)) print("{:3.0f}%".format(float(j) / float(height) * 100), end="\r") return pixels
def lerp(nx, ny): result = ["P3", f"{nx} {ny}", "255"] lower_left_corner = np.array([-2.0, -1.0, -1.0]) horizontal = np.array([4.0, 0.0, 0.0]) vertical = np.array([0.0, 2.0, 0.0]) origin = np.zeros(3) matrix = list() for j in range(ny - 1, -1, -1): for i in range(nx): u = i / nx v = j / ny r = Ray(origin, lower_left_corner + u * horizontal + v * vertical) c = color(r) ir = int(255.99 * c[0]) ig = int(255.99 * c[1]) ib = int(255.99 * c[2]) matrix.append([ir, ig, ib]) result.append(f"{ir} {ig} {ib}") p = np.array(matrix) print(p.shape) return result
def render(self, scene): width = scene.width height = scene.height aspect_ratio = float(width) / height x0 = -1.0 x1 = +1.0 xstep = (x1 - x0) / (width - 1) y0 = -1.0 / aspect_ratio y1 = +1.0 / aspect_ratio ystep = (y1 - y0) / (height - 1) camera = scene.camera pixels = Image(width, height) # calculating the pixels from the image for j in range(height): y = y0 + j * ystep for i in range(width): x = x0 + i * xstep ray = Ray(camera, Point(x, y) - camera) pixels.set_pixel(i, j, self.ray_trace(ray, scene)) print("{:3.0f}%".format(float(j) / float(height) * 100), end="\r") return pixels
def refracted_color(self, comps, remaining): if remaining == 0: return Color(0, 0, 0) if comps.obj.material.transparency == 0: return Color(0, 0, 0) n_ratio = comps.n1 / comps.n2 cos_i = comps.eyev.dot(comps.normalv) sin2_t = n_ratio * n_ratio * (1 - cos_i * cos_i) if sin2_t > 1: return Color(0, 0, 0) cos_t = sqrt(1.0 - sin2_t) direction = comps.normalv * (n_ratio * cos_i - cos_t) - \ comps.eyev * n_ratio refract_ray = Ray(comps.under_point, direction) temp1 = self.color_at(refract_ray, remaining - 1) temp2 = comps.obj.material.transparency color = temp1 * temp2 return color
def traceRay(self, ray, depth=0, maxDepth= 5): color = Color() # Find the nearest object hit by the ray in the scene distHit, objHit = self.findNearest(ray) if objHit is None: return color hitPos = ray.direction.multiplyVector(distHit).addVector(ray.origin) hitNormal = objHit.surfaceNormal(hitPos) color = color.addVector(self.colorAt(objHit, hitPos, hitNormal)) if depth < maxDepth: #The value of 0.0001 is the minimum displace newRayPos = hitNormal.multiplyVector(0.0001).addVector(hitPos) """Then we implement the reflection formula R = V - 2(V . N) * N where, R is the normalized reflected ray, L is a direction unit vector of the ray to be reflected, N is the direction unit vector normal to the surface the ray stroke """ newRayDirection = ray.direction.subVector(hitNormal.multiplyVector(ray.direction.dotProduct(hitNormal) * 2)) newRay = Ray(newRayPos, newRayDirection) #Attenuation phase color = color.addVector((self.traceRay(newRay, depth+1).multiplyVector(objHit.material.reflection))) return color
def ray_intersection(self, ray: Ray) -> Union[HitRecord, None]: """Checks if a ray intersects the sphere Return a `HitRecord`, or `None` if no intersection was found. """ inv_ray = ray.transform(self.transformation.inverse()) origin_vec = inv_ray.origin.to_vec() a = inv_ray.dir.squared_norm() b = 2.0 * origin_vec.dot(inv_ray.dir) c = origin_vec.squared_norm() - 1.0 delta = b * b - 4.0 * a * c if delta <= 0.0: return None sqrt_delta = sqrt(delta) tmin = (-b - sqrt_delta) / (2.0 * a) tmax = (-b + sqrt_delta) / (2.0 * a) if (tmin > inv_ray.tmin) and (tmin < inv_ray.tmax): first_hit_t = tmin elif (tmax > inv_ray.tmin) and (tmax < inv_ray.tmax): first_hit_t = tmax else: return None hit_point = inv_ray.at(first_hit_t) return HitRecord( world_point=self.transformation * hit_point, normal=self.transformation * _sphere_normal(hit_point, inv_ray.dir), surface_point=_sphere_point_to_uv(hit_point), t=first_hit_t, ray=ray, material=self.material, )
def update(frame, l): cam.position[2] = frame cam.rotation = [0, 0, 0] image = [[(0, 0, 0) for i in range(w)] for j in range(h)] rays = [] for i in range(h): for j in range(w): alphamax = float("inf") rays.append(Ray(0, 0, 0)) rays[-1].init_coord(cam, i, j) for element in scene: alpha = element.intersection(rays[-1], cam) if alpha: # print(alpha, alphamax) if alpha < alphamax: alphamax = alpha # print(alphamax) color = element.ambiante.copy() # color[0] = int(maps(alpha, 0, 1, 0, 255))%255 # print(color[0]) image[i][j] = color plt.imsave("res/{}.png".format(l), np.array(image, dtype="uint8").reshape(w, h, 3))
def render_scene(self): zw = 100 zdir = -1 image = Image.new('RGB', (self.vp.hres, self.vp.vres), (0, 0, 0)) draw = ImageDraw.Draw(image) for r in range(self.vp.vres): for c in range(self.vp.hres): x = self.vp.s * (r - 0.5 * (self.vp.hres - 1)) y = self.vp.s * (c - 0.5 * (self.vp.vres - 1)) ray = Ray() ray.setOriginXYZ(x, y, zw) ray.setDirXYZ(0, 0, zdir) # pixel = self.tracer.trace_ray(ray) pixel = self.mul_tracer.trace_ray(ray).color draw.point((r, c), fill=(pixel.r, pixel.g, pixel.b)) image.save('code.jpg', 'jpeg')
def render_scene(self, world): zw = 100 zdir = -1 vp = ViewPlane() image = Image.new('RGB', (vp.hres, vp.vres), (0, 0, 0)) draw = ImageDraw.Draw(image) for r in range(vp.vres): for c in range(vp.hres): x = vp.s * (r - 0.5 * (vp.hres - 1)) y = vp.s * (c - 0.5 * (vp.vres - 1)) ray = Ray() ray.setOriginXYZ(x, y, zw) ray.setDirXYZ(0, 0, zdir) pixel = world.mul_tracer.trace_ray(ray).color draw.point((r, c), fill=(pixel.r, pixel.g, pixel.b)) image.save('camera.jpg', 'jpeg')
def hit(self, ray: Ray, t_min: float, t_max: float, rec: hit_record): oc = ray.origin() - self.center a = Vector3.dot(ray.direction(), ray.direction()) b = Vector3.dot(oc, ray.direction()) c = Vector3.dot(oc, oc) - self.radius * self.radius discriminant = b * b - a * c if (discriminant > 0): temp = (-b - math.sqrt(discriminant)) / a if (temp < t_max and temp > t_min): rec.t = temp rec.p = ray.point_at_parameter(rec.t) rec.normal = (rec.p - self.center).scalar_div(self.radius) return True temp = (-b + math.sqrt(discriminant)) / a if (temp < t_max and temp > t_min): rec.t = temp rec.p = ray.point_at_parameter(rec.t) rec.normal = (rec.p - self.center).scalar_div(self.radius) return True return False
def main(n_rays, surfaces, regions, length, ngroup, plot=False, physics=True, cutoff_length=300, deadzone=50): """ Run MOC and write outputs to file """ start = time.perf_counter() print(header) rays = [] print('Laying down tracks') all_track_length = 0 all_active_length = 0 # Initiate rays and fill each with segments for i in range(n_rays): rstart = np.array([rand(),rand()])*length polar = (2*rand()-1)*pi/2 theta = rand()*2*pi ray_init = Ray(r=rstart, theta=theta, varphi=polar) ray = make_segments(ray_init, surfaces, regions, cutoff_length=cutoff_length, deadzone=deadzone) all_track_length += ray.length all_active_length += ray.active_length rays.append(ray) for region in regions: # Assign volumes region.vol = region.tot_track_length/all_active_length print('Region vol:', region.mat, region.vol) print('Tracks laid and volume calculated') if physics: print('Begin physics') counter = 0 #Initial k and q guess k = 1 print('Calculating initial q') fission_source_old, k = calc_q(regions, ngroup, k) ks = [k] converged = False print('Begin iterations') # while counter < 2 while not converged and counter < 500: normalize_phi(regions, ngroup) #Print out flux in each region # for region in regions: # print(counter, 'Flux in region', region.uid, region.mat, region.phi) counter += 1 print('Iterations: ', counter, ' k = ', k) rays = ray_contributions(rays, ngroup, regions) #Update phi and set counter to 0 for next iteration for region in regions: sigma_t = MATERIALS[region.mat]['total'] vol = region.vol term = (1/vol/sigma_t) region.phi = (term*region.tracks_phi/all_active_length + 4*pi*region.q) # Zero out phi counters region.tracks_phi = np.zeros(region.phi.shape) region.q_phi = np.zeros(region.phi.shape) fission_source_new, k = calc_q(regions, ngroup, k, update_k=True, old_fission_source=fission_source_old) fission_source_old = fission_source_new ks.append(k) converged = checktol(ks[counter-1], k, tol=1e-5) print('k = ', k, ' after ', counter, 'iterations') end = time.perf_counter() elapsed_time = end - start segments = 0 for ray in rays: for segment in ray.segments: segments += 1 print('Elapsed time: ', elapsed_time) try: print('Time per segment per group: ', elapsed_time/(segments*ngroup)) except: print('Time per segment per group: n/a') if plot: ktitle ='k = '+str(k)+' Rays ='+str(n_rays) print('Plotting tracks') plot_from_rays(rays, regions, MATERIALS, length = length) plot_k(np.arange(counter+1),ks, ktitle) if ngroup == 10: energy_groups = [0.0, 0.058, 0.14, 0.28, 0.625, 4.0, 10.0, 40.0, 5530.0, 821e3, 20e6] plot_flux(energy_groups, regions) return k, regions
def main(): p = Point(1, 2, 3) v = Vector(0, 0, 1) r = Ray(p, v) s = Sphere(Point(1, 1, 1), 2) print(s.intersectionParameter(r))
def get_ray(self, u, v): return Ray(self.origin, self.lowerLeftCorner + (u * self.horizontal) + (v * self.vertical) - self.origin)
100.0 * y / (h - 1))) for x in range(w): # pixel column i = (h - 1 - y) * w + x for s in range(nb_samples): # samples per pixel dx = rng.uniform_float() dy = rng.uniform_float() #create camera vector multipliers that range between screen-space coordinates of -0.5 to 0.5 cam_x_multiplier = (dx + x) / w - 0.5 cam_y_multiplier = (dy + y) / h - 0.5 directional_vec = cam_x * cam_x_multiplier + cam_y * cam_y_multiplier + gaze L = Vector3() ray = Ray(eye + directional_vec * 130, directional_vec.normalize()) if args.passtype == "direct": L = shadow_ray_pass(ray, rng) elif args.passtype == "albedo": L = albedo_pass(ray, rng) elif args.passtype == "normal": L = normal_pass(ray, rng) elif args.passtype == "indirect": L = indirect_light_pass(ray, rng) elif args.passtype == "depth": L = depth_pass(ray, rng) Ls[i] += (1.0 / nb_samples) * L #split into separate color planes
def getray(self, u, v): rad = self.lens_radius * random_unit_disk() offset = self.i * rad[0] + self.j * rad[1] origin_off = self.origin + offset return Ray(origin_off, self.lowerleft_corner() + u * self.horizontal() + v * self.vertical() - origin_off)
def render_dof(scene, camera, HEIGHT=100, WIDTH=100, V_SAMPLES=6, H_SAMPLES=6): """ Render the image for the given scene and camera using raytracing with depth of field. Args: scene(Scene): The scene that contains objects, cameras and lights. camera(Camera): The camera that is rendering this image. Returns: numpy.array: The pixels with the raytraced colors. """ output = np.zeros((HEIGHT, WIDTH, RGB_CHANNELS), dtype=np.uint8) if not scene or scene.is_empty() or not camera or camera.inside( scene.objects): print("Cannot generate an image") return output total_samples = H_SAMPLES * V_SAMPLES # This is for showing progress % iterations = HEIGHT * WIDTH * total_samples step_size = np.ceil((iterations * PERCENTAGE_STEP) / 100).astype('int') counter = 0 bar = Bar('Raytracing', max=100 / PERCENTAGE_STEP) # This is needed to use it in Git Bash bar.check_tty = False for j in range(HEIGHT): for i in range(WIDTH): color = np.array([0, 0, 0], dtype=float) lens_sample_offsets = [] n0 = camera.n0 n1 = camera.n1 for n in range(V_SAMPLES): for m in range(H_SAMPLES): r0, r1 = np.random.random_sample(2) ap_sx = camera.lens_params.ap_sx ap_sy = camera.lens_params.ap_sy x_offset = ((r0 - 0.5) * m) / H_SAMPLES * ap_sx y_offset = ((r1 - 0.5) * n) / V_SAMPLES * ap_sy lens_sample_offsets.append((x_offset, y_offset)) random_start = np.random.random_integers(0, total_samples - 1) for n in range(V_SAMPLES): for m in range(H_SAMPLES): r0, r1 = np.random.random_sample(2) x = i + ((float(m) + r0) / H_SAMPLES) y = HEIGHT - 1 - j + ((float(n) + r1) / V_SAMPLES) # Get x projected in view coord xp = (x / float(WIDTH)) * camera.scale_x # Get y projected in view coord yp = (y / float(HEIGHT)) * camera.scale_y pp = camera.p00 + xp * camera.n0 + yp * camera.n1 npe = utils.normalize(pp - camera.position) sample_idx = n + m * H_SAMPLES - random_start x_offset, y_offset = lens_sample_offsets[sample_idx] ps = pp + x_offset * n0 + y_offset * n1 fp = pp + npe * camera.lens_params.f director = utils.normalize(fp - ps) ray = Ray(ps, director) color += raytrace(ray, scene) / float(total_samples) counter += 1 if counter % step_size == 0: bar.next() output[j][i] = color.round().astype(np.uint8) bar.finish() return output
def scatter(self, r_in, rec): target = rec["p"] + rec["normal"] + Material.random_in_unit_sphere() scattered = Ray(rec["p"], target - rec["p"]) attenuation = self.albedo return attenuation, scattered
def color(r): """Get colour from vector.""" unit_direction = r.direction.unit_vector() t = (unit_direction.y + 1.0) * 0.5 return Vec3(1.0, 1.0, 1.0) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t nx = 200 ny = 100 print('P3\n%d %d 255' % (nx, ny)) lower_left_corner = Vec3(-2.0, -1.0, -1.0) horizontal = Vec3(4.0, 0.0, 0.0) vertical = Vec3(0.0, 2.0, 0.0) origin = Vec3(0.0, 0.0, 0.) for j in range(ny)[::-1]: for i in range(nx): u = float(i) / float(nx) v = float(j) / float(ny) r = Ray(origin, lower_left_corner + horizontal * u + vertical * v) col = color(r) ir = int(255.99 * col.r) ig = int(255.99 * col.g) ib = int(255.99 * col.b) print('%d %d %d' % (ir, ig, ib))
from vec3 import Vec3 from ray import Ray from ray import ray_color image_width = 200 image_height = 100 if __name__ == "__main__": with open("../../outputs/2-simple_gradient_background.ppm", "w") as f: f.write("P3\n") f.write("{} {}\n".format(image_width, image_height)) f.write("255\n") # let's setup the camera and scene lower_left_corner = Vec3(-2., -1., -1.) horizontal = Vec3(4.0, 0., 0.) # could be any other simple X vector vertical = Vec3(0., 2., 0.) # could be any other simple Y vector origin = Vec3(0., 0., 0.) for j in tqdm(range(image_height - 1, -1, -1)): for i in range(image_width): u = i / image_width v = j / image_height ray = Ray(origin, lower_left_corner + u * horizontal + v * vertical) color = ray_color(ray) f.write(color.write_colour() + "\n") print("All done!")
def __init__(self, pos, n): self.x, self.y = pos self.rays = [] for i in range(n): self.rays.append(Ray(self.x, self.y, i * 2 * np.pi / n))
import math from game_map import GameMap from get_key import ClearConsole, GetKey, Wait, WindowSize from player import Player from ray import Ray from screen import Screen from vector import Vector if __name__ == '__main__': get_key = GetKey() game_map = GameMap() screen = Screen() player = Player(2 , 2) ray = Ray(player.position.x, player.position.y) WindowSize() while True: ClearConsole() screen.cleaner() key = get_key() if key == 27: break elif key == 299: # left arrow - (rotation) player.angle = -0.2 elif key == 301: # right arrow - (rotation) player.angle = 0.2 elif key == 296: # up arrow - (step) player.way = 0.25
H = 200 D = 200 im = Image.new('RGB', (W, H)) pix = im.load() if False: ## this is done in image coordinates eye = Point(W / 2, H / 2, D) sphere = Sphere() ts = Matrix.scale(50, 50, 50) tt = Matrix.translate(W / 2, H / 2, D / 4) sphere.transform = tt * ts for x in range(W): for y in range(H): ray = Ray(eye, Point(x, y, 0) - eye) xs = sphere.intersect(ray) if xs: pix[x, y] = (255, 0, 0) print(x) else: ## this is done in object coordinates eye = Point(0, 0, -5) sphere = Sphere() tt = Matrix.translate(0, 0, -2) sphere.transform = tt wall = (-3, 3, -3, 3) # LRBT ms = Matrix.scale( float(wall[1] - wall[0]) / W,
def test_intersecting_ray_with_empty_group(self): g = Group() r = Ray(Point(0, 0, 0), Vector(0, 0, 1)) xs = g.local_intersect(r) self.assertEqual(len(xs), 0)
unit_direction = r.direction.unit_vector() t = 0.5 * (unit_direction.y + 1.0) return Vec3(1.0, 1.0, 1.0) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t nx = 200 ny = 100 print('P3\n%d %d 255' % (nx, ny)) lower_left_corner = Vec3(-2.0, -1.0, -1.0) horizontal = Vec3(4.0, 0.0, 0.0) vertical = Vec3(0.0, 2.0, 0.0) origin = Vec3(0.0, 0.0, 0.0) hlist = [Sphere(Vec3(0.0, 0.0, -1.0), 0.5), Sphere(Vec3(0.0, -100.5, -1.0), 100.0)] world = HitableList(hlist) for j in range(ny)[::-1]: for i in range(nx): u = float(i) / float(nx) v = float(j) / float(ny) r = Ray(origin, lower_left_corner + horizontal * u + vertical * v) p = r.point_at_parameter(2.0) col = color(r, world) ir = int(255.99 * col.r) ig = int(255.99 * col.g) ib = int(255.99 * col.b) print('%d %d %d' % (ir, ig, ib))