def __init__(self, width, height):
        assert numeric_real(width)
        assert width > 0
        assert numeric_real(height)
        assert height > 0

        self._initialized = False
        self._cameras = []
        self._targets = []
        self._geometries = []
        self._walls = []
        self._cur_time = 0
        self._observation = {}

        self._rect = Rectangle(Point2D(0, 0), 0.0, width, height)
        if not self._rect.area():
            print ("warning, environment has zero area")
            return

        self._figure = None

        self._initialized = True
    def step(self, dt):
        assert numeric_real(dt)
        assert dt > 0

        cur_time = self._cur_time

        # update target positions
        for target in self._targets:
            target.step(cur_time, dt, self._walls)

        # detect targets in each camera coverage area
        data = []
        for cam in self._cameras:
            # step ptz cameras
            cam.step(cur_time, dt)

            for target in self._targets:
                cam.detect(target, self._walls)

            data.extend(cam.detection_data())

        observ = {}
        for entry in data:
            # print entry
            _id = entry.id
            if _id in observ.keys():
                observ[_id].append(entry.area_id)
            else:
                observ[_id] = [entry.area_id]
        # for key in sorted(observ.keys()):
        #    print "  observ for target \"%s\": nr. %d, %s" % (key, len(observ[key]), observ[key])

        self._observation = {}
        for targetid, val in observ.iteritems():
            if val == []:
                val = "0"
            else:
                val = "-".join(sorted(val))
            self._observation[targetid] = val

        # open the building passage
        # if self._cur_time == 30:
        #    self._geometries[0].set_passage_open(1)
        #    self._update_walls()

        self._cur_time += dt