Example #1
0
 def test_reflected_color_nonreflective_material(self):
     w = World.default_world()
     r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
     shape = w.objects[1]
     shape.material.ambient = 1
     i = Intersection(1, shape)
     comps = Computations.prepare_computations(i, r)
     color = World.reflected_color(w, comps)
     self.assertEqual(color, Color(0, 0, 0))
Example #2
0
 def test_under_point_offset_below_surface(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     shape = GlassSphere()
     shape.transform = Transformations.translation(0, 0, 1)
     i = Intersection(5, shape)
     xs = Intersection.intersections(i)
     comps = Computations.prepare_computations(i, r, xs)
     self.assertGreater(comps.under_point.z, Constants.epsilon / 2)
     self.assertLess(comps.point.z, comps.under_point.z)
Example #3
0
def TraceMontecCarloRay(SceneRayIntersectionSamplecount):
    I = Intersection()
    res = 0.0
    if (SceneRayIntersectionSamplecount[0].intersect(
            SceneRayIntersectionSamplecount[1], I)):
        res += I.ell * np.pi

    return (res / SceneRayIntersectionSamplecount[3],
            SceneRayIntersectionSamplecount[2])
Example #4
0
    def getRefraction(self, intersection, pt, light, shapeSet):
        # iterate over number of refractions
        reflection = reflect(intersection.ray.direction, self.normalFromPt(pt))

        r = Ray(pt, reflection)
        i = Intersection(r, RAY_T_MAX)
        if shapeSet.intersect(i, light, self):
            return i.color
        return black
Example #5
0
 def intersect(self, ray):
     o = ray.origin
     dir = ray.direction
     n = self.normal
     d = self.d
     if np.dot(dir, n) == 0:
         return None
     t = -(np.dot(o, n) + d) / np.dot(dir, n)
     return Intersection(ray, self, t)
Example #6
0
 def test_hit_inside(self):
     r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
     shape = Sphere()
     i = Intersection(1, shape)
     comps = Computations.prepare_computations(i, r)
     self.assertEqual(comps.point, Point(0, 0, 1))
     self.assertEqual(comps.eyev, Vector(0, 0, -1))
     self.assertTrue(comps.inside)
     # normal would have been (0, 0, 1), but is inverted!
     self.assertEqual(comps.normalv, Vector(0, 0, -1))
Example #7
0
 def test_precompute_state_intersection(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     shape = Sphere()
     i = Intersection(4, shape)
     comps = Computations.prepare_computations(i, r)
     self.assertEqual(comps.t, i.t)
     self.assertEqual(comps.object, i.object)
     self.assertEqual(comps.point, Point(0, 0, -1))
     self.assertEqual(comps.eyev, Vector(0, 0, -1))
     self.assertEqual(comps.normalv, Vector(0, 0, -1))
Example #8
0
 def __init__(self, max_q_size):
     border_names = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"]
     intersection_names = ["A", "B", "C", "D"]
     self.intersections = []
     self.borders = []
     for name in border_names:
         self.borders.append(BorderNode(name))
     for name in intersection_names:
         self.intersections.append(Intersection(name, max_q_size))
     self.set_connections()
Example #9
0
 def test_shade_hit_reflective_material(self):
     w = World.default_world()
     shape = Plane()
     shape.material.reflective = 0.5
     shape.transform = Transformations.translation(0, -1, 0)
     w.objects.append(shape)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     i = Intersection(math.sqrt(2), shape)
     comps = Computations.prepare_computations(i, r)
     color = World.shade_hit(w, comps)
     self.assertEqual(color, Color(0.87677, 0.92436, 0.82918))
Example #10
0
 def test_reflected_color_at_maximum_recursive_depth(self):
     w = World.default_world()
     shape = Plane()
     shape.material.reflective = 0.5
     shape.transform = Transformations.translation(0, -1, 0)
     w.objects.append(shape)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     i = Intersection(math.sqrt(2), shape)
     comps = Computations.prepare_computations(i, r)
     color = World.reflected_color(w, comps, 0)
     self.assertEqual(color, Color(0, 0, 0))
Example #11
0
 def test_shade_hit_intersection_in_shadow(self):
     w = World()
     w.light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
     s1 = Sphere()
     w.objects.append(s1)
     s2 = Sphere()
     s2.transform = Transformations.translation(0, 0, 10)
     w.objects.append(s2)
     r = Ray(Point(0, 0, 5), Vector(0, 0, 1))
     i = Intersection(4, s2)
     comps = Computations.prepare_computations(i, r)
     c = World.shade_hit(w, comps)
     self.assertEqual(c, Color(0.1, 0.1, 0.1))
Example #12
0
    def setup_intersection(self, x, y, image, size=None, name=None):
        ''' Sets up an intersection. '''
        if size == None:
            size = self.img_size, self.img_size
        s = Sprite(image, size)
        # y is self.height - y because of the way graphics works
        # (Positive = down; (0,0) is the top left).
        s.move_to(x=x, y=self.height - y)

        i = Intersection(x, y, size[0], name=name)
        self.intersection_set.add(i)
        self.window.add_sprite(s)
        return i
    def find_intersections(self, ray, a, b, c) -> Iterable[Intersection]:
        disc = b ** 2 - 4 * a * c

        # ray does not intersect shape
        if disc < 0:
            return []

        t0 = (-b - math.sqrt(disc)) / (2 * a)
        t1 = (-b + math.sqrt(disc)) / (2 * a)

        # for truncated shapes
        xs = []

        y0 = ray.origin.y + t0 * ray.direction.y
        if self.minimum < y0 and y0 < self.maximum:
            xs.append(Intersection(t0, self))

        y1 = ray.origin.y + t1 * ray.direction.y
        if self.minimum < y1 and y1 < self.maximum:
            xs.append(Intersection(t1, self))

        return xs
Example #14
0
    def ell(self, scene, ray, camera):
        intersection = Intersection(np.array([0., 0., 0.]),
                                    np.array([0., 1., 0.]))
        intersection.color = np.array([1., 1., 1.])
        if (scene.intersect(ray, intersection)):
            return np.max([
                0.0,
                np.min([
                    1.0,
                    intersection.ell + MonteCarlo(intersection, scene, 256)
                ])
            ]) * intersection.color

        return np.array([0., 0., 0.])
Example #15
0
    def __init__(self, max_q_size):

        self.intersections = []
        self.borders = []
        for border in border_data:
            self.borders.append(BorderNode(border[0], border[1], border[2]))
        for intersection in intersection_data:
            self.intersections.append(
                Intersection(intersection[0], max_q_size, intersection[1],
                             intersection[2]))
        self.set_connections()
        self.global_state = []
        self.global_reward = 0

        self.action_size = 2401
        self.state_size = 16  #the state is now the number of cars per queue, for 4 intersections
Example #16
0
def intersections(streets_dict, num_intersections):
  #initialize intersection
  intersections = []
  
  for intersection in range(0, num_intersections):
    intersections.append(Intersection(intersection))
  
  # add the ingoing
  for street in streets_dict:
    #1st number is start 2nd number is end
    #1st number add to outgoing of that intersection
    index = streets_dict[street][1]
    name = street
    intersections[index].add_incoming(name)
    #2nd number add to incoming of that Intersection

  return intersections
Example #17
0
 def test_shade_hit_with_transparent_material(self):
     w = World.default_world()
     floor = Plane()
     floor.transform = Transformations.translation(0, -1, 0)
     floor.material.transparency = 0.5
     floor.material.refractive_index = 1.5
     w.objects.append(floor)
     ball = Sphere()
     ball.material.color = Color(1, 0, 0)
     ball.material.ambient = 0.5
     ball.transform = Transformations.translation(0, -3.5, -0.5)
     w.objects.append(ball)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     xs = Intersection.intersections(Intersection(math.sqrt(2), floor))
     comps = Computations.prepare_computations(xs[0], r, xs)
     color = World.shade_hit(w, comps, 5)
     self.assertEqual(color, Color(0.93642, 0.68642, 0.68642))
Example #18
0
	def __init__(self, max_q_size):

		self.intersections = []
		self.borders = []
		for border in border_data:
			self.borders.append(BorderNode(border[0], border[1], border[2]))
		for intersection in intersection_data:
			self.intersections.append(Intersection(intersection[0], max_q_size, intersection[1], intersection[2]))
		self.set_connections()
		self.global_state = []
		self.global_reward = 0

		# self.action_space = combinations
		# self.observation_space = spaces.Box(-high, high, dtype=np.float32)
		# self.observation_space = 
		#self.action_size = 7
		self.action_size = 2401
		#self.state_size = 8
		self.state_size = 32
Example #19
0
def RayTrace(image, camera, shape, light):

    black = np.array([0.,0.,0.])
    white = np.array([1.,1.,1])

    for x in range(image.getWidth()):
        for y in range(image.getHeight()):
            
            # screen coord
            X = 2. * x / image.getWidth() - 1
            Y = -2. * y / image.getHeight() + 1.

            r = camera.getRay(X,Y)
            i = Intersection(r, RAY_T_MAX)
            #print(x,y, image.getWidth(), image.getHeight())
            if shape.intersect(i, light):
                image.image[y, x] = clamp_color(i.color)
            else:
                image.image[y, x] = black
Example #20
0
    def local_intersect(self, ray: Ray) -> Iterable[Intersection]:
        a = ray.direction.x**2 - ray.direction.y**2 + ray.direction.z**2
        b = 2 * ray.origin.x * ray.direction.x - 2 * ray.origin.y * ray.direction.y + 2 * ray.origin.z * ray.direction.z

        if abs(a) < Constants.epsilon and abs(b) < Constants.epsilon:
            return []

        c = ray.origin.x**2 - ray.origin.y**2 + ray.origin.z**2

        # ray is parallel to the y axis
        if abs(a) < Constants.epsilon and abs(b) > Constants.epsilon:
            xs = [Intersection(-c / (2 * b), self)]
            Cone.intersect_caps(self, ray, xs)
            return xs

        xs = self.find_intersections(ray, a, b, c)

        Cone.intersect_caps(self, ray, xs)

        return xs
Example #21
0
    def local_intersect(self, ray: Ray) -> Iterable[Intersection]:
        dir_cross_e2 = ray.direction.cross(self.e2)
        det = self.e1.dot(dir_cross_e2)
        if abs(det) < Constants.epsilon:
            return []

        f = 1.0 / det

        p1_to_origin = ray.origin - self.p1
        u = f * p1_to_origin.dot(dir_cross_e2)
        if u < 0 or u > 1:
            return []

        origin_cross_e1 = p1_to_origin.cross(self.e1)
        v = f * ray.direction.dot(origin_cross_e1)
        if v < 0 or (u + v) > 1:
            return []

        t = f * self.e2.dot(origin_cross_e1)
        return [Intersection(t, self, u, v)]
Example #22
0
    def __init__(self, stepsize=0.01, dimensions=(3, 3), static_open=None):
        self.dimensions = dimensions
        self.static_open = static_open or \
                           [(x, y) for x in range(dimensions[0]) for y in range(dimensions[1])
                            if x in (0, dimensions[0] - 1) or y in (0, dimensions[1] - 1)]
        self.intersections = []
        for x in range(self.dimensions[0]):
            for y in range(self.dimensions[1]):
                static_open = True if (x, y) in self.static_open else False
                self.intersections.append(Intersection(x, y, static_open=static_open))
        self.cars = []
        self.stepsize = stepsize
        self.total_wait_time = 0

        # Set up window
        self.labels = []
        self.tk = tkinter.Tk()
        self.tk.title('City')
        # Window stays on top of normal windows
        self.tk.wm_attributes("-topmost", 1)
        # Window size
        self.tk.wm_geometry("%dx%d%+d%+d" % (
            100 * (self.dimensions[0] + 1), 100 * (self.dimensions[1] + 1), 0, 0))
    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 loadScenario(scenario_nr):
        scenarios = [

            #           DIRECTIONS
            #
            #               0
            #               ↑
            #          3 ←    → 1
            #               ↓
            #               2

            # ________________________________________________________________________________________________________
            #
            #                                                  [0]
            #                                       1D, 2 intersections, 2 cars
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(100, [-1, 0, -1, -1]),
                    Link(50, [-1, 1, -1, 0]),
                    Link(120, [-1, -1, -1, 1])
                ],
                'intersections': [
                    Intersection([-1, 1, -1, 0],
                                 [[0, 30], [30, 60], [0, 30], [30, 60]]),
                    Intersection([-1, 2, -1, 1],
                                 [[0, 30], [30, 60], [0, 30], [30, 60]])
                ],
                'cars': [Car(0, 1, 6, 2), Car(2, 3, 12, 0)]
            },

            # ________________________________________________________________________________________________________
            #
            #                                                 [1]
            #                                       2D, 1 intersection, 2 cars
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(80, [0, -1, -1, -1]),
                    Link(80, [-1, 0, -1, -1]),
                    Link(80, [-1, -1, 0, -1]),
                    Link(80, [-1, -1, -1, 0])
                ],
                'intersections': [Intersection([2, 3, 0, 1])],
                'cars': [],
                'entries': [
                    Entry(0, 0, 360, [2]),
                    Entry(2, 2, 360, [0]),
                    Entry(1, 1, 300, [3]),
                    Entry(3, 3, 300, [1])
                ]
            },

            # ________________________________________________________________________________________________________
            #
            #                                                  [2]
            #                                       2D, 6 intersections, 9 cars
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(40, [0, -1, 3, -1]),
                    Link(100, [-1, 0, -1, -1]),
                    Link(50, [-1, -1, 0, -1]),
                    Link(120, [-1, 1, -1, 0]),
                    Link(40, [1, -1, 4, -1]),
                    Link(30, [-1, -1, 1, -1]),
                    Link(70, [-1, 2, -1, 1]),
                    Link(40, [2, -1, 5, -1]),
                    Link(60, [-1, -1, 2, -1]),
                    Link(90, [-1, -1, 2, -1]),
                    Link(80, [3, -1, -1, -1]),
                    Link(100, [-1, 3, -1, -1]),
                    Link(120, [-1, 4, -1, 3]),
                    Link(80, [4, -1, -1, -1]),
                    Link(70, [-1, 5, -1, 4]),
                    Link(80, [5, -1, -1, -1]),
                    Link(90, [-1, -1, -1, 5])
                ],
                'intersections': [
                    Intersection([2, 3, 0, 1]),
                    Intersection([8, 9, 7, 6]),
                    Intersection([0, 12, 10, 11]),
                    Intersection([7, 16, 15, 14]),
                    Intersection([4, 14, 13, 12]),
                    Intersection([5, 6, 4, 3])
                ],
                'cars': [],
                'entries': [
                    Entry(1, 1, 300, [9]),
                    Entry(2, 2, 150, [10]),
                    Entry(5, 2, 90, [13]),
                    Entry(8, 2, 180, [15]),
                    Entry(16, 3, 100, [11]),
                    Entry(15, 0, 400, [8]),
                    Entry(13, 0, 200, [5]),
                    Entry(10, 0, 150, [2]),
                    Entry(11, 1, 240, [16])
                ]
            },

            # ________________________________________________________________________________________________________
            #
            #                                              [3]
            #          1D, 2 intersections, 2 cars, moving in same direction, test cars reacting to cars
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(100, [-1, 0, -1, -1]),
                    Link(50, [-1, 1, -1, 0]),
                    Link(120, [-1, -1, -1, 1])
                ],
                'intersections': [
                    Intersection([-1, 1, -1, 0],
                                 [[0, 30], [30, 60], [0, 30], [30, 60]]),
                    Intersection([-1, 2, -1, 1],
                                 [[0, 30], [30, 60], [0, 30], [30, 60]])
                ],
                'cars': [Car(0, 1, 6, 2),
                         Car(0, 1, 5, 2, distanceInLink=20)]
            },

            # ________________________________________________________________________________________________________
            #
            #                                              [4]
            #                            1D, 1 intersection, cars in vehicles/h
            # ________________________________________________________________________________________________________
            {
                'links':
                [Link(100, [-1, 0, -1, -1]),
                 Link(50, [-1, 1, -1, 0])],
                'intersections': [
                    Intersection([-1, 1, -1, 0],
                                 [[0, 30], [30, 60], [0, 30], [30, 60]])
                ],
                'cars': [Car(0, 1, 6, 2),
                         Car(0, 1, 5, 2, distanceInLink=20)],
                'inputs': []
            },

            # ________________________________________________________________________________________________________
            #
            #                                                 [5]
            #                                         2D, 2 intersections
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(50, [0, -1, -1, -1]),
                    Link(50, [-1, 0, -1, -1]),
                    Link(50, [-1, -1, 0, -1]),
                    Link(50, [-1, 1, -1, 0]),
                    Link(50, [-1, -1, -1, 1]),
                    Link(50, [-1, -1, -1, 1]),
                    Link(50, [1, -1, -1, -1])
                ],
                'intersections':
                [Intersection([2, 3, 0, 1]),
                 Intersection([4, 5, 6, 3])],
                'cars': [],
                'entries': [
                    Entry(0, 0, 360, [2]),
                    Entry(2, 2, 360, [0]),
                    Entry(1, 1, 300, [3]),
                    Entry(5, 3, 300, [1]),
                    Entry(6, 0, 360, [4])
                ]
            },

            # ________________________________________________________________________________________________________
            #
            #                                                 [6]
            #                                      Scenario: Webster Case No 5
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(80, [0, -1, -1, -1]),
                    Link(80, [-1, 0, -1, -1]),
                    Link(80, [-1, -1, 0, -1]),
                    Link(80, [-1, -1, -1, 0])
                ],
                'intersections': [Intersection([2, 3, 0, 1])],
                'cars': [],
                'entries': [
                    Entry(0, 0, 600, [2]),
                    Entry(2, 2, 600, [0]),
                    Entry(1, 1, 300, [3]),
                    Entry(3, 3, 300, [1])
                ]
            },

            # ________________________________________________________________________________________________________
            #
            #                                                 [7]
            #                                         Scenario: Logic Test
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(100, [0, -1, -1, -1]),
                    Link(100, [-1, 0, -1, -1]),
                    Link(100, [-1, -1, 0, -1]),
                    Link(140, [-1, 1, -1, 0]),
                    Link(100, [-1, -1, 1, -1]),
                    Link(100, [-1, -1, -1, 1]),
                    Link(100, [1, -1, -1, -1])
                ],
                'intersections':
                [Intersection([2, 3, 0, 1]),
                 Intersection([4, 5, 6, 3])],
                'cars': [],
                'entries': [
                    Entry(0, 0, 150, [2]),
                    Entry(2, 2, 150, [0]),
                    Entry(1, 1, 600, [3]),
                    Entry(5, 3, 150, [1]),
                    Entry(6, 0, 150, [4]),
                    Entry(4, 2, 150, [6])
                ]
            },

            # ________________________________________________________________________________________________________
            #
            #                                                  [2]
            #                                       2D, 6 intersections, 9 cars
            # ________________________________________________________________________________________________________
            {
                'links': [
                    Link(40, [0, -1, 3, -1]),
                    Link(100, [-1, 0, -1, -1]),
                    Link(50, [-1, -1, 0, -1]),
                    Link(120, [-1, 1, -1, 0]),
                    Link(40, [1, -1, 4, -1]),
                    Link(30, [-1, -1, 1, -1]),
                    Link(70, [-1, 2, -1, 1]),
                    Link(40, [2, -1, 5, -1]),
                    Link(60, [-1, -1, 2, -1]),
                    Link(90, [-1, -1, 2, -1]),
                    Link(80, [3, -1, -1, -1]),
                    Link(100, [-1, 3, -1, -1]),
                    Link(120, [-1, 4, -1, 3]),
                    Link(80, [4, -1, -1, -1]),
                    Link(70, [-1, 5, -1, 4]),
                    Link(80, [5, -1, -1, -1]),
                    Link(90, [-1, -1, -1, 5])
                ],
                'intersections': [
                    Intersection([2, 3, 0, 1]),
                    Intersection([8, 9, 7, 6]),
                    Intersection([0, 12, 10, 11]),
                    Intersection([7, 16, 15, 14]),
                    Intersection([4, 14, 13, 12]),
                    Intersection([5, 6, 4, 3])
                ],
                'cars': [],
                'entries': [
                    Entry(1, 1, 300, [9]),
                    Entry(2, 2, 150, [10]),
                    Entry(5, 2, 90, [13]),
                    Entry(8, 2, 180, [15]),
                    Entry(16, 3, 100, [11]),
                    Entry(15, 0, 400, [8]),
                    Entry(13, 0, 200, [5]),
                    Entry(10, 0, 150, [2]),
                    Entry(11, 1, 240, [16])
                ]
            }
        ]

        return scenarios[scenario_nr]
Example #25
0
File: car.py Project: CErgusa/ADT
    def turn(self):    
        #print('ID:', self.ID, 'direction:', self.direction, 'path:', self.path, 'point:', self.point.x, ',', self.point.y)
        if self.path == None:
            self.which_way_to_turn()

        if not self.direction_stack.empty():
            self.direction_stack.clear()

        # GOING UP (cant go up through 5)
        if self.direction == predefines.UP and self.path == predefines.UP:
            # go through intersection (cant be int. 1 or 5)
            # check which intersection and occupy the correct spots
            self.direction_stack.push(Intersection(predefines.UP, 5))
            self.direction_stack.push(Intersection(predefines.UP, 4))
            self.direction_stack.push(Intersection(predefines.UP, 3))
            self.direction_stack.push(Intersection(predefines.UP, 2))
            self.direction_stack.push(Intersection(predefines.UP, 1))

            if self.intersectionID == predefines.INTERSECTION2:
                self.int_array = [0, 4, -1], [0, 3, 0], [0, 2, 0], [0, 1, -1]
                # TODO: dir_stack implementation
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 4, -1], [0, 0, 3, 0], [0, 0, 2, 0], [-1, 0, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 4], [0, 0, 3], [0, 0, 2], [-1, 0, 1]
            else:
                return

        elif self.direction == predefines.UP and self.path == predefines.DOWN:
            # take a u-turn
            self.direction_stack.push(Intersection(predefines.DOWN, 4))
            self.direction_stack.push(Intersection(predefines.DOWN, 3))
            self.direction_stack.push(Intersection(predefines.LEFT, 2))
            self.direction_stack.push(Intersection(predefines.UP, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 0, 0, 0], [0, 0, 0, 0], [-1, 2, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION2:
                self.int_array = [0, 0, -1], [0, 0, 0], [0, 0, 0], [2, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 0], [0, 0, 0, 0], [-1, 2, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 0], [0, 0, 0], [0, 0, 0], [-1, 2, 1]
            else:
                return

        elif self.direction == predefines.UP and self.path == predefines.LEFT:
            # take a left turn (cant turn left at 2)
            self.direction_stack.push(Intersection(predefines.LEFT, 6))
            self.direction_stack.push(Intersection(predefines.LEFT, 5))
            self.direction_stack.push(Intersection(predefines.LEFT, 4))
            self.direction_stack.push(Intersection(predefines.UP, 3))
            self.direction_stack.push(Intersection(predefines.UP, 2))
            self.direction_stack.push(Intersection(predefines.UP, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [5, 4, 3, 0], [0, 0, 2, 0], [-1, 0, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [5, 4, 3, 0], [0, 0, 2, 0], [-1, 0, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 0], [5, 4, 3], [0, 0, 2], [-1, 0, 1]
            else:
                return

        elif self.direction == predefines.UP and self.path == predefines.RIGHT:
            # take a right turn (cant turn right at 4)
            self.direction_stack.push(Intersection(predefines.RIGHT, 4))
            self.direction_stack.push(Intersection(predefines.RIGHT, 3))
            self.direction_stack.push(Intersection(predefines.UP, 2))
            self.direction_stack.push(Intersection(predefines.UP, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 0, 0, 0], [0, 0, 2, 3], [-1, 0, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION2:
                self.int_array = [0, 0, -1], [0, 0, 0], [0, 2, 3], [0, 1, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 0], [0, 0, 2, 3], [-1, 0, 1, -1]
            else:
                return


        # GOING DOWN (cant go down from 1)
        elif self.direction == predefines.DOWN and self.path == predefines.UP:
            # go through self.intersectionID(cant go down through 5)
            self.direction_stack.push(Intersection(predefines.DOWN, 5))
            self.direction_stack.push(Intersection(predefines.DOWN, 4))
            self.direction_stack.push(Intersection(predefines.DOWN, 3))
            self.direction_stack.push(Intersection(predefines.DOWN, 2))
            self.direction_stack.push(Intersection(predefines.DOWN, 1))

            if self.intersectionID == predefines.INTERSECTION2:
                self.int_array = [1, 0, -1], [2, 0, 0], [3, 0, 0], [4, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION3:
                self.int_array = [-1, 1, 0, -1], [0, 2, 0, 0], [0, 3, 0, 0], [-1, 4, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION4:
                self.int_array = [-1, 1, 0], [0, 2, 0], [0, 3, 0], [-1, 4, 0]
            else:
                return

        elif self.direction == predefines.DOWN and self.path == predefines.DOWN:
            # take a u-turn
            self.direction_stack.push(Intersection(predefines.UP, 4))
            self.direction_stack.push(Intersection(predefines.UP, 3))
            self.direction_stack.push(Intersection(predefines.RIGHT, 2))
            self.direction_stack.push(Intersection(predefines.DOWN, 1))

            if self.intersectionID == predefines.INTERSECTION2:
                self.int_array = [1, 2, -1], [0, 0, 0], [0, 0, 0], [0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION3:
                self.int_array = [-1, 1, 2, -1], [0, 0, 0, 0], [0, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION4:
                self.int_array = [-1, 1, 2], [0, 0, 0], [0, 0, 0], [-1, 0, 0]
            elif self.intersectionID == predefines.INTERSECTION5:
                self.int_array = [-1, 1, 2, -1], [0, 0, 0, 0], [0, 0, 0, 0]
            else:
                return

        elif self.direction == predefines.DOWN and self.path == predefines.RIGHT:
            # take a right turn (cant turn right at 2)
            self.direction_stack.push(Intersection(predefines.LEFT, 4))
            self.direction_stack.push(Intersection(predefines.LEFT, 3))
            self.direction_stack.push(Intersection(predefines.DOWN, 2))
            self.direction_stack.push(Intersection(predefines.DOWN, 1))

            if self.intersectionID == predefines.INTERSECTION3:
                self.int_array = [-1, 1, 0, -1], [3, 2, 0, 0], [0, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION4:
                self.int_array = [-1, 1, 0], [3, 2, 0], [0, 0, 0], [-1, 0, 0]
            elif self.intersectionID == predefines.INTERSECTION5:
                self.int_array = [-1, 1, 0, -1], [3, 2, 0, 0], [0, 0, 0, 0]
            else:
                return

        elif self.direction == predefines.DOWN and self.path == predefines.LEFT:
            # take a left turn (cant turn left at 4)
            self.direction_stack.push(Intersection(predefines.RIGHT, 6))
            self.direction_stack.push(Intersection(predefines.RIGHT, 5))
            self.direction_stack.push(Intersection(predefines.RIGHT, 4))
            self.direction_stack.push(Intersection(predefines.DOWN, 3))
            self.direction_stack.push(Intersection(predefines.DOWN, 2))
            self.direction_stack.push(Intersection(predefines.DOWN, 1))

            if self.intersectionID== predefines.INTERSECTION2:
                self.int_array = [1, 0, -1], [2, 0, 0], [3, 4, 5], [0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 1, 0, -1], [0, 2, 0, 0], [0, 3, 4, 5], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION5:
                self.int_array = [-1, 1, 0, -1], [0, 2, 0, 0], [0, 3, 4, 5]
            else:
                return       


        # GOING LEFT (cant go left from 4)
        elif self.direction == predefines.LEFT and self.path == predefines.UP:
            # go through self.intersectionID(cant go through 2)
            self.direction_stack.push(Intersection(predefines.LEFT, 5))
            self.direction_stack.push(Intersection(predefines.LEFT, 4))
            self.direction_stack.push(Intersection(predefines.LEFT, 3))
            self.direction_stack.push(Intersection(predefines.LEFT, 2))
            self.direction_stack.push(Intersection(predefines.LEFT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [4, 3, 2, 1], [0, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [4, 3, 2, 1], [0, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION5:
                self.int_array = [-1, 0, 0, -1], [4, 3, 2, 1], [0, 0, 0, 0]
            else:
                return
            
        elif self.direction == predefines.LEFT and self.path == predefines.DOWN:
            # take a u-turn
            self.direction_stack.push(Intersection(predefines.RIGHT, 4))
            self.direction_stack.push(Intersection(predefines.RIGHT, 3))
            self.direction_stack.push(Intersection(predefines.DOWN, 2))
            self.direction_stack.push(Intersection(predefines.LEFT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 0, 0, 1], [0, 0, 0, 2], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION2:
                self.int_array = [0, 0, -1], [0, 0, 1], [0, 0, 2], [0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 1], [0, 0, 0, 2], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION5:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 1], [0, 0, 0, 2]
            else:
                return
            
        elif self.direction == predefines.LEFT and self.path == predefines.LEFT:
            # take a left turn (cant go down from 5)
            self.direction_stack.push(Intersection(predefines.DOWN, 6))
            self.direction_stack.push(Intersection(predefines.DOWN, 5))
            self.direction_stack.push(Intersection(predefines.DOWN, 4))
            self.direction_stack.push(Intersection(predefines.LEFT, 3))
            self.direction_stack.push(Intersection(predefines.LEFT, 2))
            self.direction_stack.push(Intersection(predefines.LEFT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 3, 2, 1], [0, 4, 0, 0], [-1, 5, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION2:
                self.int_array = [0, 0, -1], [3, 2, 1], [4, 0, 0], [5, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 3, 2, 1], [0, 4, 0, 0], [-1, 5, 0, -1]
            else:
                return

        elif self.direction == predefines.LEFT and self.path == predefines.RIGHT:
            # take a right turn (cant go up from 1)
            self.direction_stack.push(Intersection(predefines.UP, 4))
            self.direction_stack.push(Intersection(predefines.UP, 3))
            self.direction_stack.push(Intersection(predefines.LEFT, 2))
            self.direction_stack.push(Intersection(predefines.LEFT, 1))

            if self.intersectionID == predefines.INTERSECTION2:
                self.int_array = [0, 3, -1], [0, 2, 1], [0, 0, 0], [0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION3:
                self.int_array = [-1, 0, 3, -1], [0, 0, 2, 1], [0, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION5:
                self.int_array = [-1, 0, 3, -1], [0, 0, 2, 1], [0, 0, 0, 0]
            else:
                return


        # GOING RIGHT (cant go right from 2)
        elif self.direction == predefines.RIGHT and self.path == predefines.UP:
            # go through intersection(cant go through 4)
            # TODO: Fix leaving intersection to work with this in car_update
            self.direction_stack.push(Intersection(predefines.RIGHT, 5)) # 5 is used for the exiting direction and path
            self.direction_stack.push(Intersection(predefines.RIGHT, 4))
            self.direction_stack.push(Intersection(predefines.RIGHT, 3))
            self.direction_stack.push(Intersection(predefines.RIGHT, 2))
            self.direction_stack.push(Intersection(predefines.RIGHT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 0, 0, 0], [1, 2, 3, 4], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 0], [1, 2, 3, 4], [-1, 0, 0, -1]
            elif self.intersectionID == predefines.INTERSECTION5:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 0], [1, 2, 3, 4]
            else:
                return
            
        elif self.direction == predefines.RIGHT and self.path == predefines.DOWN:
            # take a u-turn
            self.direction_stack.push(Intersection(predefines.LEFT, 4))
            self.direction_stack.push(Intersection(predefines.LEFT, 3))
            self.direction_stack.push(Intersection(predefines.UP, 2))
            self.direction_stack.push(Intersection(predefines.RIGHT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [2, 0, 0, 0], [1, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [2, 0, 0, 0], [1, 0, 0, 0], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 0], [2, 0, 0], [1, 0, 0], [-1, 0, 0]               
            elif self.intersectionID== predefines.INTERSECTION5:
                self.int_array = [-1, 0, 0, -1], [2, 0, 0, 0], [1, 0, 0, 0]
            else:
                return
            
        elif self.direction == predefines.RIGHT and self.path == predefines.LEFT:
            # decide which way to turn in the intersection
            # take a left turn (cant go up from 1)
            self.direction_stack.push(Intersection(predefines.UP, 6))
            self.direction_stack.push(Intersection(predefines.UP, 5))
            self.direction_stack.push(Intersection(predefines.UP, 4))
            self.direction_stack.push(Intersection(predefines.RIGHT, 3))
            self.direction_stack.push(Intersection(predefines.RIGHT, 2))
            self.direction_stack.push(Intersection(predefines.RIGHT, 1))

            if self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 5, -1], [0, 0, 4, 0], [1, 2, 3, 0], [-1, 0, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 5], [0, 0, 4], [1, 2, 3], [-1, 0, 0]
            elif self.intersectionID== predefines.INTERSECTION5:
                self.int_array = [-1, 0, 5, -1], [0, 0, 4, 0], [1, 2, 3, 0]
            else:
                return

        elif self.direction == predefines.RIGHT and self.path == predefines.RIGHT:
            # take a right turn (cant go down from 5)
            self.direction_stack.push(Intersection(predefines.DOWN, 4))
            self.direction_stack.push(Intersection(predefines.DOWN, 3))
            self.direction_stack.push(Intersection(predefines.RIGHT, 2))
            self.direction_stack.push(Intersection(predefines.RIGHT, 1))

            if self.intersectionID== predefines.INTERSECTION1:
                self.int_array = [0, 0, 0, 0], [1, 2, 0, 0], [-1, 3, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION3:
                self.int_array = [-1, 0, 0, -1], [0, 0, 0, 0], [1, 2, 0, 0], [-1, 3, 0, -1]
            elif self.intersectionID== predefines.INTERSECTION4:
                self.int_array = [-1, 0, 0], [0, 0, 0], [1, 2, 0], [-1, 3, 0]
            else:
                return
        else:
            return
Example #26
0
def stackMaze(mazeText):

    #parses maze file and captures maze attributes
    mazeFile = open(mazeText, "r")
    mazeList = mazeFile.read().splitlines(
    )  #https://stackoverflow.com/questions/24946640/removing-r-n-from-a-python-list-after-importing-with-readlines
    mazeFile.close()
    rows = len(mazeList)
    columns = len(mazeList[0])

    #builds blank grid
    maze = Grid(rows, columns)

    #builds maze from list of maze rows
    for row in range(maze.getHeight()):
        for column in range(maze.getWidth()):
            maze[row][column] = mazeList[row][column]

    #creates intersection stack
    stack = ArrayStack()

    #creates a player
    player = Player(maze)

    #searches for starting point of player
    for r in range(0, rows):
        for c in range(0, columns):
            if maze[r][c] == "P":
                player.setRow(r)
                player.setColumn(c)
                break

    choicePoints = 0

    #end condition check
    while maze[player.getRow()][player.getColumn() + 1] != 'T':

        #convenience variables representing the value of the grid at these positions relative to player
        up = maze[player.getRow() - 1][player.getColumn()]
        down = maze[player.getRow() + 1][player.getColumn()]
        right = maze[player.getRow()][player.getColumn() + 1]
        left = maze[player.getRow()][player.getColumn() - 1]

        #dead end check
        routes = 0
        if up == ' ':
            routes += 1
        if down == ' ':
            routes += 1
        if right == ' ':
            routes += 1
        if left == ' ':
            routes += 1
        if routes == 0:
            #player is at a dead end.  REWRITE BACKTRACK LOGIC
            #retrieves the previous intersection from the stack
            pos = stack.pop()
            #backtracks the player to previous intersection
            maze[player.getRow()][player.getColumn()] = '-'
            player.setRow(pos.getRow())
            player.setColumn(pos.getColumn())
            maze[pos.getRow()][pos.getColumn()] = 'P'
            #marks last path as dead end
            maze[pos.getActivePath()[0]][pos.getActivePath()[1]] = '-'

        elif routes > 1:
            #player is at an intersection
            #increment choice points by 1
            choicePoints += 1
            intersection = Intersection(player.getRow(), player.getColumn())
            if up == ' ':
                intersection.setActivePath(
                    [player.getRow() - 1,
                     player.getColumn()])
                nextMove = player.moveUp()
            elif down == ' ':
                intersection.setActivePath(
                    [player.getRow() + 1,
                     player.getColumn()])
                nextMove = player.moveDown()
            elif right == ' ':
                intersection.setActivePath(
                    [player.getRow(), player.getColumn() + 1])
                nextMove = player.moveRight()
            elif left == ' ':
                intersection.setActivePath(
                    [player.getRow(), player.getColumn() - 1])
                nextMove = player.moveLeft()
            stack.push(intersection)

        else:
            #the player is not at a dead end
            if down == ' ':
                nextMove = player.moveDown()
            elif up == ' ':
                nextMove = player.moveUp()
            elif right == ' ':
                nextMove = player.moveRight()
            elif left == ' ':
                nextMove = player.moveLeft()

        #moves player to the next position
        nextMove

    #moves P to the end of the maze
    maze[player.getRow()][player.getColumn()] = "-"
    maze[player.getRow()][player.getColumn() + 1] = "P"
    print("Stack-based Maze Solution:\n")
    print(maze)
    print("Choice points: " + str(choicePoints) + "\n")

    #writes maze solution to text file
    fw = open("stacksolution.txt", "w")
    fw.writelines(str(maze))
    fw.write("Choice points: " + str(choicePoints) + "\n")
    fw.close()
from gui import ZipperView, SetupView
from intersection import Intersection, distance
from rail import Rail, LeftRail, RightRail, StraightRail

cars = []
rails = []
for rotation in range(0, 4):
    leftrail = LeftRail(rotation)
    rightrail = RightRail(rotation)
    straightrail = StraightRail(rotation)
    rails.extend([leftrail, rightrail, straightrail])
#     #rails.append(leftrail)
#     cars.append(Car(1.0, leftrail, "CAR0",start_time=5))
#     #cars.append(Car(1.0, rightrail, "CAR1"))
#     cars.append(Car(1.0, straightrail, "CAR2"))
intersection1 = Intersection(cars, rails)
print(intersection1.rails)
intersection1.update()
# print("Cf", intersection.cars)

#rails2 = [LeftRail(0), LeftRail(1), LeftRail(2)]

# intersection2 = Intersection([
#   Car(1.0, rails2[0], 0, [(133, 1.0), (163, 0.1), (184, 0.1), (318, 0.1)]),
#   Car(1.0, rails2[1], 0, [(155, 0.1), (163, 0.1), (318, 0.1)]),
#   Car(1.0, rails2[2], 0, [(134, 0.2), (155, 0.1), (184, 0.1), (318, 0.1)]),], rails2)

# setup_view = SetupView(intersection=intersection,
#                        window_size=(800, 600),
#                        x_lanes=2,
#                        y_lanes=2)
Example #28
0
# stair in inter7 and 34
blockbf = Block(-0.5, np.array([14.15, 4.8, 0]), np.array([14.95, 4.8, -1]), 0.2)

# block for stairs from floor 2 to floor 1
# stair in inter39 and 23
blockbq = Block(1.5, np.array([10.3, 9.6, 2]), np.array([10.8, 9.6, 1]), 0.2)
# stair in inter40 and 24
blockbr = Block(1.5, np.array([10.3, 8.1, 2]), np.array([10.8, 8.1, 1]), 0.2)
# stair in inter42 and 27
blockbs = Block(1.5, np.array([14.15, 4.8, 2]), np.array([14.95, 4.8, 1]), 0.2)
# stair in inter44 and 21
blockbt = Block(1.5, np.array([17.55, 3.35, 2]), np.array([18.05, 3.35, 1]), 0.2)


# floor -1
intersection13 = Intersection(np.array([10.55, 9.6, -1]), [blockao,blockap], 0.5)
intersection14 = Intersection(np.array([10.55, 8.1, -1]), [blockaq,blockar,blockbb], 0.5)
intersection30 = Intersection(np.array([10.4, 3.4, -1]), [blockau,blockax,blockaw,blockbd], 0.4)
intersection31 = Intersection(np.array([10.4, 2.2, -1]), [blockaw,blockay], 0.4)
intersection32 = Intersection(np.array([8.5, 3.4, -1]), [blockav, blockau,blockbc], 0.4)
intersection33 = Intersection(np.array([13, 2.9, -1]), [blockax, blockay,blockbe], 1.8)
intersection34 = Intersection(np.array([14.55, 4.8, -1]), [blockas, blockat,blockbf], 0.8)
intersection35 = Intersection(np.array([8.55, 9.6, -1]), [blockao,blockba], 0.5)
# floor 0
intersection36 = Intersection(np.array([5.7, 3, 0]), [blocka], 0.8)
intersection0 = Intersection(np.array([3.3, 3, 0]), [blocka,blockam], 0.8)
intersection1 = Intersection(np.array([8.5, 3.4, 0]), [blockb, blockc, blockah, blockbc], 0.4)  # stairs for floor 1
intersection2 = Intersection(np.array([10.4, 3.4, 0]), [blockc, blockd, blocke, blockbd], 0.4)
intersection3 = Intersection(np.array([13, 2.9, 0]), [blocke, blockf, blockai, blockbe], 1.8)
intersection4 = Intersection(np.array([14.55, 3.35, 0]), [blockf, blocki, blockg], 0.5)
intersection5 = Intersection(np.array([17.8, 3.35, 0]), [blockg, blockh, blockaj], 0.5)
    def generateSample(self, intersection, scene, camera, ray, depth=0):
        sample = Irradiance_Sample(intersection.pos, intersection.n)
        minSamples = 64
        l = np.array([0., 0., 0.])

        # generate a sample for irradiance
        if (depth > 0):
            numSample = np.max(
                [minSamples, self.directLightSampleCount / (2**depth)])
            for i in range(int(numSample)):
                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 <= 0:
                        print(
                            "\033[34mWARNING\033[30m: ray intersects with t <= 0"
                        )
                    if (sample.minHitDist > r.t):
                        sample.minHitDist = r.t
                    procData = Irradiance_ProcessData(ni.pos, ni.n,
                                                      self.minWeight,
                                                      self.maxCosAngleDiff)
                    intVal = self.getInterpolatedValue(procData, depth - 1)
                    # if interpolation is successful
                    if (intVal >= 0).all():
                        lightval = ni.color * intVal * ni.BSDF(
                            procData.avgLightDir, d, ni.n)
                        """
                        if lightval < 0:
                            print("\033[34mWARNING\033[30m: Interpolation lead to a negative light value")
                        """

                        l += lightval
                        sample.avgLightDir += d * np.linalg.norm(lightval)
                        v = self.transformH2toR3(
                            np.array([
                                h2Vec[0], (h2Vec[1] - np.pi / 4) % (2 * np.pi)
                            ]), intersection.n)
                        sample.rotGrad += -v * np.tan(
                            h2Vec[0]) * np.linalg.norm(lightval)
                    # else make a new sample und use its irradiance
                    else:
                        s = self.generateSample(ni, scene, camera, r,
                                                depth - 1)
                        lightval = ni.color * s.irradiance * ni.BSDF(
                            s.avgLightDir, d, ni.n)
                        if (lightval < 0).any():
                            print(
                                "\033[31mERROR\033[30m: Generating a new sample lead to a negative light value"
                            )
                        l += lightval
                        sample.avgLightDir += d * np.linalg.norm(
                            lightval)  #s.avgLightDir
                        v = self.transformH2toR3(
                            np.array([
                                h2Vec[0], (h2Vec[1] - np.pi / 4) % (2 * np.pi)
                            ]), intersection.n)
                        sample.rotGrad += -v * np.tan(
                            h2Vec[0]) * np.linalg.norm(lightval)

                    if np.dot(sample.avgLightDir, sample.normal) < 0:
                        print(
                            "\033[34mWARNING\033[30m: The average Light direction points temporally in the wrong half space"
                        )

            l *= np.pi / numSample
            sample.rotGrad *= np.pi / numSample
        else:
            # generate a sample for direct light
            l = self.MonteCarlo(intersection, scene,
                                self.directLightSampleCount,
                                sample)  #+ intersection.ell

        pixelSpacing = self.computeIntersectionPixelSpacing(
            camera, ray, intersection)
        sample.irradiance = l
        sample.computeSampleMaxContribution(self.minPixelDist,
                                            self.maxPixelDist, pixelSpacing)
        norm = np.linalg.norm(sample.avgLightDir)
        if (norm > 0):
            sample.avgLightDir /= norm

        if ((self.showSamples) & (depth == self.maxBounceDepth)):
            camera.imageDepths[-1][ray.pixel[0],
                                   ray.pixel[1], :] = [1., 0., 0.]

        if np.dot(sample.avgLightDir, sample.normal) < 0:
            print(
                "\033[31mERROR\033[30m: Sample was generated with avgLightDir pointing in the wrong half space"
            )

        self.cache[depth].addObj(sample)
        return sample
    def ell(self, scene, ray, camera):
        #very first call for ell() means the cache has to be filled
        cameraImageCount = self.maxBounceDepth + 1 + (1 if self.showSamples
                                                      else 0)
        if len(camera.imageDepths) < cameraImageCount:
            for i in range(len(camera.imageDepths), cameraImageCount):
                camera.addImage()

        if ((ray.pixel[0] == 0) & (ray.pixel[1] == 0)):
            start = time.perf_counter()
            if self.completelyFillCache:
                self.FillCacheComplete(camera, scene)
            else:
                self.fillCache(camera, scene)
            end = time.perf_counter()
            s = end - start
            m = int(s / 60)
            s = s % 60
            h = int(m / 60)
            m = m % 60

            print("filling cache took:", h, "h ", m, "min ", s, "s")
            for i in range(len(self.cache)):
                print("In cache depth: ", i, "are ", self.cache[i].objCount,
                      "samples")

        intersection = Intersection()
        val = np.array([0.0, 0., 0.])
        if (scene.intersect(ray, intersection)):
            #interpolate indirect light
            for i in range(self.maxBounceDepth, 0, -1):
                interpolatedPoint = Irradiance_ProcessData(
                    intersection.pos, intersection.n, self.minWeight,
                    self.maxCosAngleDiff)
                interpval = self.getInterpolatedValue(interpolatedPoint, i)
                e = 0
                if (interpval >= 0).all():
                    e += interpval * intersection.BSDF(
                        interpolatedPoint.avgLightDir, -ray.d, intersection.n)

                #if interpolation failed, compute new sample
                else:
                    #print("new sample generated at ", ray.pixel)
                    s = self.generateSample(intersection, scene, camera, ray,
                                            i)
                    e += s.irradiance * intersection.BSDF(
                        s.avgLightDir, -ray.d, s.normal)

                if (e < 0).any():
                    print(e)

                camera.imageDepths[i][ray.pixel[0], ray.pixel[1], :] = e
                val += e

            #compute direct light
            if self.renderDirectLight:
                sample = Irradiance_Sample(intersection.pos, intersection.n)
                self.MonteCarlo(intersection,
                                scene,
                                sampleCount=self.directLightSampleCount,
                                sample=sample)

                camera.imageDepths[0][
                    ray.pixel[0], ray.pixel[1], :] = intersection.color * (
                        sample.irradiance * intersection.BSDF(
                            sample.avgLightDir, -ray.d, intersection.n) +
                        intersection.ell)

                val += sample.irradiance * intersection.BSDF(
                    sample.avgLightDir, -ray.d, intersection.n)
                val += intersection.ell
            if (val < 0).any():
                print("light value is negative :", val)

        return val * intersection.color