def test_rotation_z_axis(): p = Point(0, 1, 0) h_q = rotation_z(pi / 4) h_f = rotation_z(pi / 2) assert h_q * p == Point(-sqrt(2) / 2, sqrt(2) / 2, 0) assert h_f * p == Point(-1, 0, 0)
def test_ray_position(): r = Ray(Point(2, 3, 4), Vector(1, 0, 0)) assert r.position(0) == Point(2, 3, 4) assert r.position(1) == Point(3, 3, 4) assert r.position(-1) == Point(1, 3, 4) assert r.position(2.5) == Point(4.5, 3, 4)
def test_rotation_y_axis(): p = Point(0, 0, 1) h_q = rotation_y(pi / 4) h_f = rotation_y(pi / 2) assert h_q * p == Point(sqrt(2) / 2, 0, sqrt(2) / 2) assert h_f * p == Point(1, 0, 0)
def test_rotation_x_axis(): p = Point(0, 1, 0) h_q = rotation_x(pi / 4) f_q = rotation_x(pi / 2) assert h_q * p == Point(0, sqrt(2) / 2, sqrt(2) / 2) assert f_q * p == Point(0, 0, 1)
def test_transformation_chain(): p = Point(1, 0, 1) A = rotation_x(pi / 2) B = scaling(5, 5, 5) C = translation(10, 5, 7) T = C @ B @ A assert T * p == Point(15, 0, 7)
def test_lightning_eye_angle(): m = DefaultMaterial() position = Point(0, 0, 0) eyev = Vector(0, sqrt(2) / 2, -sqrt(2) / 2) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, -10), Color(1, 1, 1)) result = m.lighting(light, position, eyev, normalv) assert result == Color(1.0, 1.0, 1.0)
def test_lightning_light_behind(): m = DefaultMaterial() position = Point(0, 0, 0) eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, 10), Color(1, 1, 1)) result = m.lighting(light, position, eyev, normalv) assert result == Color(0.1, 0.1, 0.1)
def test_lighting_direct(): m = DefaultMaterial() position = Point(0, 0, 0) eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, -10), Color(1, 1, 1)) result = m.lighting(light, position, eyev, normalv) assert result == Color(1.9, 1.9, 1.9)
def test_lightning_light_angle(): m = DefaultMaterial() position = Point(0, 0, 0) eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 10, -10), Color(1, 1, 1)) result = m.lighting(light, position, eyev, normalv) assert result == Color(0.7363961030678927, 0.7363961030678927, 0.7363961030678927)
def test_ray_init(): origin = Point(1, 2, 3) direct = Vector(4, 5, 6) r = Ray(origin, direct) assert r.origin == origin assert r.direction == direct
def test_ray_intersect_from_middle(): r = Ray(Point(0, 0, 0), Vector(0, 0, 1)) s = Sphere() x = r.intersects(s) assert len(x) == 2 assert x[0].t == -1 assert x[1].t == 1
def test_ray_intersects_sphere_object(): r = Ray(Point(0, 0, -5), Vector(0, 0, 1)) s = Sphere() x = r.intersects(s) assert len(x) == 2 assert x[0].object == s assert x[1].object == s
def test_sphere_intersection_scaled(): r = Ray(Point(0, 0, -5), Vector(0, 0, 1)) s = Sphere() s.set_transform(scaling(2, 2, 2)) x = r.intersects(s) assert len(x) == 2 assert x[0].t == 3 assert x[1].t == 7
def test_ray_intersect_sphere_tangent(): r = Ray(Point(0, 1, -5), Vector(0, 0, 1)) s = Sphere() x = r.intersects(s) assert len(x) == 2 assert x[0].t == 5 assert x[1].t == 5
def test_ray_intersect_from_behind(): r = Ray(Point(0, 0, 5), Vector(0, 0, 1)) s = Sphere() x = r.intersects(s) assert len(x) == 2 assert x[0].t == -6 assert x[1].t == -4
def intersects(self, s): transformed_ray = self.transform(s.transform.inv) obj_to_ray = transformed_ray.origin - Point(0, 0, 0) a = transformed_ray.direction.dot(transformed_ray.direction) b = 2 * transformed_ray.direction.dot(obj_to_ray) c = obj_to_ray.dot(obj_to_ray) - 1 discriminant = b * b - 4 * a * c if discriminant < 0: return Intersections() else: t1 = (-b - sqrt(discriminant)) / (2 * a) t2 = (-b + sqrt(discriminant)) / (2 * a) i1 = Intersection(s, t1) i2 = Intersection(s, t2) if t1 > t2: return Intersections(i2, i1) else: return Intersections(i1, i2)
def test_sphere_normal_at_arbitrary(): s = Sphere() n = s.normal_at(Point(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3)) assert n == Vector(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3)
def test_sphere_normal_at_z(): s = Sphere() n = s.normal_at(Point(0, 0, 1)) assert n == Vector(0, 0, 1)
def test_sphere_normal_at_x(): s = Sphere() n = s.normal_at(Point(1, 0, 0)) assert n == Vector(1, 0, 0)
def test_sphere_intersection_translate(): r = Ray(Point(0, 0, -5), Vector(0, 0, 1)) s = Sphere() s.set_transform(translation(5, 0, 0)) x = r.intersects(s) assert len(x) == 0
def test_shearing_x_y(): t = shearing(1, 0, 0, 0, 0, 0) p = Point(2, 3, 4) assert t * p == Point(5, 3, 4)
def test_sphere_normal_at_scaled(): s = Sphere() s.set_transform(scaling(1, 0.5, 1)) n = s.normal_at(Point(0, sqrt(2) / 2, -sqrt(2) / 2)) assert n == Vector(0, 0.9701425001453319, -0.24253562503633297)
def test_rotation_x_axis_inverse(): p = Point(0, 1, 0) h_q = rotation_x(pi / 4) inv = h_q.inv assert inv * p == Point(0, sqrt(2) / 2, -sqrt(2) / 2)
def test_ray_intersect_sphere_no_intersection(): r = Ray(Point(0, 2, -5), Vector(0, 0, 1)) s = Sphere() x = r.intersects(s) assert len(x) == 0
def test_sphere_normal_normalized(): s = Sphere() n = s.normal_at(Point(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3)) assert n == n.normalize()
def test_translate(): r = Ray(Point(1, 2, 3), Vector(0, 1, 0)) m = translation(3, 4, 5) r2 = r.transform(m) assert r2.origin == Point(4, 6, 8) assert r2.direction == Vector(0, 1, 0)
def test_sphere_normal_at_translate(): s = Sphere() s.set_transform(translation(0, 1, 0)) n = s.normal_at(Point(0, 1.70711, -0.70711)) assert n == Vector(0, 0.7071067811865475, -0.7071067811865476)
def test_scale(): r = Ray(Point(1, 2, 3), Vector(0, 1, 0)) m = scaling(2, 3, 4) r2 = r.transform(m) assert r2.origin == Point(2, 6, 12) assert r2.direction == Vector(0, 3, 0)
from src.canvas import Canvas from src.color import Color from src.tupl import Vector, Point def tick(p, v): p += v v += Vector(0, -0.1, 0) + Vector(-0.01, 0, 0) return p, v c = Canvas(900, 550) col = Color(255, 255, 255) if __name__ == '__main__': p = Point(0, 1, 0) v = Vector(1, 1.8, 0).normalize() * 11.25 for i in range(100): X = int(p.x) Y = int(p.y) if p.y <= 0: break if (0 <= X < c.width) and (0 <= c.height - Y < c.height): c.write_pixel(X, c.height - Y, col) p, v = tick(p, v) c.to_ppm('trajectory.ppm')
def test_shearing_x_z(): t = shearing(0, 1, 0, 0, 0, 0) p = Point(2, 3, 4) assert t * p == Point(6, 3, 4)