def test_vec3_derived_types(): vec3 = Vec3(1.0, 1.5, 2.0) assert str(vec3) == "Vec3(1.0, 1.5, 2.0)" point3 = Point3(1.0, 0.5, 0.0) assert str(point3) == "Point3(1.0, 0.5, 0.0)" color = Color(255.0, 255.0, 255.0) assert str(color) == "Color(255.0, 255.0, 255.0)"
def test_multiplication(): vec3_1 = Vec3(0.0, 1.0, -2.5) vec3_2 = Vec3(1.5, 0.5, 1.0) double_1 = 2.0 assert vec3_1 * vec3_2 == Vec3(0.0, 0.5, -2.5) assert vec3_2 * vec3_1 == Vec3(0.0, 0.5, -2.5) assert vec3_1 * double_1 == Vec3(0.0, 2.0, -5.0) assert double_1 * vec3_2 == Vec3(3.0, 1.0, 2.0)
def test_unary_minus_operator(): vec3_pos = Vec3(0.5, 1.0, 2.5) assert -vec3_pos == Vec3(-0.5, -1.0, -2.5) vec3_neg = Vec3(-0.5, -2.5, -1.0) assert -vec3_neg == Vec3(0.5, 2.5, 1.0) vec3_mix = Vec3(0.0, 2.3, -4.1) assert -vec3_mix == Vec3(0.0, -2.3, 4.1)
def main() -> None: aspect_ratio = 16.0 / 9.0 image_width = 300 image_height = int(image_width / aspect_ratio) samples_per_pixel = 20 max_depth = 50 world = random_scene() lookfrom = Point3(13, 2, 3) lookat = Point3(0, 0, 0) vup = Vec3(0, 1, 0) dist_to_focus = 10.0 aperture = 0.1 cam = Camera(lookfrom, lookat, vup, 20.0, aspect_ratio, aperture, dist_to_focus) pool = multiprocessing.Pool() manager = multiprocessing.Manager() queue = manager.Queue() coords = itertools.product(range(image_height - 1, -1, -1), range(image_width)) func = functools.partial( consume_color, image_width, image_height, cam, world, max_depth, samples_per_pixel, queue, ) result = pool.map_async(func, coords) while not result.ready(): remaining = image_height - queue.qsize() // image_width print(f"\rScanlines remaining: {remaining}", end=" ", file=sys.stderr) time.sleep(0.1) colors = result.get() print(f"P3\n{image_width} {image_height}\n255") for pixel_color in colors: write_color(pixel_color, samples_per_pixel) print("\nDone.", file=sys.stderr)
def __init__(self, p: Point3, t: float, material: Material) -> None: self.p = p self.t = t self.material = material self.front_face = False self.normal = Vec3(0.0, 0.0, 0.0)
def random_in_unit_sphere() -> Vec3: while True: p = Vec3.random(-1, 1) if p.length_squared >= 1: continue return p
def random_in_unit_disk() -> Vec3: while True: p = Vec3(random_double(-1, 1), random_double(-1, 1), 0) if p.length_squared >= 1: continue return p
def cross(u: Vec3, v: Vec3) -> Vec3: return Vec3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x)
def random_unit_vector() -> Vec3: a = random_double(0.0, 2 * math.pi) z = random_double(-1, 1) r = pow(1 - pow(z, 2), 0.5) return Vec3(r * math.cos(a), r * math.sin(a), z)
def test_vec3_length(): vec3_1 = Vec3(1.0, 2.0, 3.0) assert vec3_1.length_squared == 14.0 assert vec3_1.length == 3.7416573867739413
def test_true_division(): vec3_1 = Vec3(1.0, 2.0, 3.0) vec3_2 = Vec3(0.5, -4.0, -1.2) double_1 = 2.0 assert vec3_1 / vec3_2 == Vec3(2.0, -0.5, -2.5) assert vec3_2 / double_1 == Vec3(0.25, -2.0, -0.6)
def test_subtraction(): vec3_1 = Vec3(0.0, 1.0, -2.5) vec3_2 = Vec3(1.5, 0.5, 1.0) assert vec3_1 - vec3_2 == Vec3(-1.5, 0.5, -3.5) assert vec3_2 - vec3_1 == Vec3(1.5, -0.5, 3.5)
def test_addition(): vec3_1 = Vec3(-1.5, 0.5, -3.5) vec3_2 = Vec3(1.5, 0.5, 1.0) assert vec3_1 + vec3_2 == Vec3(0.0, 1.0, -2.5) assert vec3_2 + vec3_1 == Vec3(0.0, 1.0, -2.5)