def test_normal_vector_cylinder_end_caps(self):
     cyl = Cylinder()
     cyl.minimum = 1
     cyl.maximum = 2
     cyl.closed = True
     PointNormal = namedtuple("PointNormal", ["point", "normal"])
     point_normals = [
         PointNormal(Point(0, 1, 0), Vector(0, -1, 0)),
         PointNormal(Point(0.5, 1, 0), Vector(0, -1, 0)),
         PointNormal(Point(0, 1, 0.5), Vector(0, -1, 0)),
         PointNormal(Point(0, 2, 0), Vector(0, 1, 0)),
         PointNormal(Point(0.5, 2, 0), Vector(0, 1, 0)),
         PointNormal(Point(0, 2, 0.5), Vector(0, 1, 0))
     ]
     for point_normal in point_normals:
         n = cyl.local_normal_at(point_normal.point)
         self.assertEqual(n, point_normal.normal)
 def test_interserct_caps_of_closed_cylinder(self):
     cyl = Cylinder()
     cyl.minimum = 1
     cyl.maximum = 2
     cyl.closed = True
     cyl.maximum = 2
     CylinderIntersection = namedtuple("CyliderIntersection",
                                       ["point", "direction", "count"])
     cylinder_intersections = [
         CylinderIntersection(Point(0, 3, 0), Vector(0, -1, 0), 2),
         CylinderIntersection(Point(0, 3, -2), Vector(0, -1, 2), 2),
         CylinderIntersection(Point(0, 4, -2), Vector(0, -1, 1),
                              2),  # corner case
         CylinderIntersection(Point(0, 0, -2), Vector(0, 1, 2), 2),
         CylinderIntersection(Point(0, -1, -2), Vector(0, 1, 1),
                              2)  # corner case
     ]
     for cylinder_intersection in cylinder_intersections:
         direction = Vector.normalize(cylinder_intersection.direction)
         r = Ray(cylinder_intersection.point, direction)
         xs = cyl.local_intersect(r)
         self.assertEqual(len(xs), cylinder_intersection.count)