def constrain(self):
dx = self.w * <NUM_LIT:0.1><EOL>dy = self.h * <NUM_LIT:0.1> <EOL>for b in self:<EOL><INDENT>if b.x < self.x-dx: b.vx += _ctx.random(dx)<EOL>if b.y < self.y-dy: b.vy += _ctx.random(dy)<EOL>if b.x > self.x+self.w+dx: b.vx -= _ctx.random(dx)<EOL>if b.y > self.y+self.h+dy: b.vy -= _ctx.random(dy)<EOL>if b.z < <NUM_LIT:0>: b.vz += <NUM_LIT:10><EOL>if b.z > <NUM_LIT:100>: b.vz -= <NUM_LIT:10><EOL>if b.y > self._perch_y and _ctx.random() < self._perch:<EOL><INDENT>b.y = self._perch_y<EOL>b.vy = -abs(b.vy) * <NUM_LIT><EOL>b.is_perching = True<EOL>try:<EOL><INDENT>b._perch_t = self._perch_t()<EOL><DEDENT>except:<EOL><INDENT>b._perch_t = self._perch_t<EOL><DEDENT><DEDENT><DEDENT>
Cages the flock inside the x, y, w, h area.

        The actual cage is a bit larger,
        so boids don't seem to bounce of invisible walls
        (they are rather "encouraged" to stay in the area).

        If a boid touches the ground level,
        it may decide to perch there for a while.