예제 #1
0
    def _refresh(self):
        # get the positions of the centers of the head and tail circles
        direction = Vector([cos(self._rotation), sin(self._rotation), 0])
        distance = (self._length - self._width) / 2
        displacement = distance * direction

        self._head_center = self._position + displacement
        self._tail_center = self._position - displacement

        # get the positions of the corners of the bacilli box
        side = Vector([-sin(self._rotation), cos(self._rotation), 0])
        radius = self._width / 2

        self._head_right = self._head_center + radius * side
        self._head_left = self._head_center - radius * side
        self._tail_right = self._tail_center + radius * side
        self._tail_left = self._tail_center - radius * side

        # compute the region of interest
        self._region = Rectangle(
            floor(min(self._head_center.x, self._tail_center.x) -
                  radius),  #left
            floor(min(self._head_center.y, self._tail_center.y) -
                  radius),  #top
            ceil(max(self._head_center.x, self._tail_center.x) + radius) +
            1,  #right
            ceil(max(self._head_center.y, self._tail_center.y) + radius) +
            1)  #bottom

        self._needs_refresh = False
예제 #2
0
파일: cell.py 프로젝트: bbklk/CellUniverse
    def split(self, alpha: float) -> (Cell, Cell):
        assert 0 < alpha < 1

        direction = Vector([np.cos(self.rotation), np.sin(self.rotation), 0])
        unit = self.dimensions.length * direction

        front = self.position + unit / 2
        back = self.position - unit / 2
        center = self.position + (1 / 2 - alpha) * unit

        position_1 = (front + center) / 2
        position_2 = (center + back) / 2

        cell_1 = Bacilli(self.name + '0',
                         position_1.x,
                         position_1.y,
                         self.dimensions.width,
                         alpha * self.dimensions.length,
                         self.rotation,
                         in_flux=True)

        cell_2 = Bacilli(self.name + '1',
                         position_2.x,
                         position_2.y,
                         self.dimensions.width,
                         (1 - alpha) * self.dimensions.length,
                         self.rotation,
                         in_flux=True)

        return cell_1, cell_2
예제 #3
0
    def split(self, alpha):
        """Splits a cell into two cells with a ratio determined by alpha."""
        if self._needs_refresh:
            self._refresh()

        direction = Vector([cos(self._rotation), sin(self._rotation), 0])
        unit = self._length * direction

        front = self._position + unit / 2
        back = self._position - unit / 2
        center = self._position + (0.5 - float(alpha)) * unit

        position1 = (front + center) / 2
        position2 = (center + back) / 2

        cell1 = Bacilli(self._name + '0',
                        position1.x, position1.y, self._width,
                        self._length * float(alpha), self._rotation, alpha,
                        self._opacity)

        cell2 = Bacilli(self._name + '1', position2.x,
                        position2.y, self._width,
                        self._length * (1 - float(alpha)), self._rotation,
                        alpha, self._opacity)

        return cell1, cell2
예제 #4
0
 def __init__(self, name, x, y, width, length, rotation):
     super().__init__(name)
     self._position = Vector([x, y, 0])
     self._width = width
     self._length = length
     self._rotation = rotation
     self._needs_refresh = True
예제 #5
0
 def __init__(self, name, x, y, width, length, rotation):
     #upper left corner is the origin
     #x,y are index of the array
     #x:column index y:row index
     super().__init__(name)
     self._position = Vector([x, y, 0])
     self._width = width
     self._length = length
     self._rotation = rotation
     self._needs_refresh = True
예제 #6
0
    def combine(self, cell):
        """Combines this cell with another cell."""
        if self._needs_refresh:
            self._refresh()

        if cell._needs_refresh:
            cell._refresh()

        separation = self._position - cell._position
        direction = separation / sqrt(separation @ separation)

        # get combined front
        direction1 = Vector([cos(self._rotation), sin(self._rotation), 0])
        distance1 = self._length - self._width
        if direction1 @ direction >= 0:
            head1 = self._position + distance1 * direction1 / 2
        else:
            head1 = self._position - distance1 * direction1 / 2
        extent1 = head1 + self._width * direction / 2
        front = self._position + (
            (extent1 - self._position) @ direction) * direction

        # get combined back
        direction2 = Vector([cos(cell._rotation), sin(cell._rotation), 0])
        distance2 = cell._length - cell._width
        if direction2 @ direction >= 0:
            tail2 = cell._position - distance2 * direction2 / 2
        else:
            tail2 = cell._position + distance2 * direction2 / 2
        extent2 = tail2 - cell._width * direction / 2
        back = cell._position + (
            (extent2 - cell._position) @ direction) * direction

        # create new cell
        position = (front + back) / 2
        rotation = atan2(direction.y, direction.x)
        width = (self._width + cell._width) / 2
        length = sqrt((front - back) @ (front - back))

        return Bacilli(self._name[:-1], position.x, position.y, width, length,
                       rotation, "combined alpha unknown",
                       (self._opacity + cell.opacity) / 2)
예제 #7
0
 def __init__(self, name, x, y, width, length, rotation):
     super().__init__(name)
     self._position = Vector([x, y, 0])
     self._width = width
     self._length = length
     self._rotation = rotation
     self._needs_refresh = True
     # diffraction constant, controlling how much does the pattern spread
     self._sigma = 3.0
     # diffraction value, controlling how bright the diffraction pattern is
     self._diff_v = 0.5
예제 #8
0
파일: cell.py 프로젝트: bbklk/CellUniverse
    def combine(self, cell_1: Cell, cell_2: Cell):

        separation = cell_1.position - cell_2.position
        direction = separation / np.sqrt(separation @ separation)

        # get combined front
        direction_1 = Vector(
            [np.cos(cell_1.rotation),
             np.sin(cell_1.rotation), 0])
        distance_1 = cell_1.dimensions.length - cell_1.dimensions.width
        if direction_1 @ direction >= 0:
            head_1 = cell_1.position + distance_1 * direction_1 / 2
        else:
            head_1 = cell_1.position - distance_1 * direction_1 / 2
        extent_1 = head_1 + cell_1.dimensions.width * direction / 2
        front = cell_1.position + (
            (extent_1 - cell_1.position) @ direction) * direction

        # get combined back
        direction_2 = Vector(
            [np.cos(cell_2.rotation),
             np.sin(cell_2.rotation), 0])
        distance_2 = cell_2.dimensions.length - cell_2.dimensions.width
        if direction_2 @ direction >= 0:
            tail_2 = cell_2.position - distance_2 * direction_2 / 2
        else:
            tail_2 = cell_2.position + distance_2 * direction_2 / 2
        extent_2 = tail_2 - cell_2.dimensions.width * direction / 2
        back = cell_2.position + (
            (extent_2 - cell_2.position) @ direction) * direction

        # update cell
        self.position = (front + back) / 2
        self.rotation = np.arctan2(direction.y, direction.x)
        self.dimensions.width = (cell_1.dimensions.width +
                                 cell_2.dimensions.width) / 2
        self.dimensions.length = np.sqrt((front - back) @ (front - back))
        self._update()
예제 #9
0
파일: cell.py 프로젝트: bbklk/CellUniverse
    def _update(self):

        # head and tail
        direction = Vector([np.cos(self.rotation), np.sin(self.rotation), 0])
        distance = self.dimensions.length - self.dimensions.width

        self._head = self.position + distance * direction / 2
        self._tail = self.position - distance * direction / 2

        # body
        right = Vector([-np.sin(self.rotation), np.cos(self.rotation), 0])
        radius = self.dimensions.width / 2

        self._head_right = self._head + radius * right
        self._head_left = self._head - radius * right
        self._tail_right = self._tail + radius * right
        self._tail_left = self._tail - radius * right

        # region of interest
        self._region = Rectangle()
        self._region.left = min(self._head.x, self._tail.x) - radius
        self._region.right = max(self._head.x, self._tail.x) + radius
        self._region.top = min(self._head.y, self._tail.y) - radius
        self._region.bottom = max(self._head.y, self._tail.y) + radius
예제 #10
0
파일: cell.py 프로젝트: bbklk/CellUniverse
    def update(self, position=None, rotation=None, dimensions=None):
        changes = False

        if position is not None:
            self.position = Vector(position)
            changes = True

        if rotation is not None:
            self.rotation = float(rotation)
            changes = True

        if dimensions is not None:
            self.dimensions = Dimensions(dimensions)
            changes = True

        if changes is not None:
            self._update()
예제 #11
0
파일: cell.py 프로젝트: bbklk/CellUniverse
    def __init__(self, name, x, y, width, length, rotation, in_flux=False):
        super().__init__(name)

        self.position = Vector([x, y, 0])
        self.dimensions = Dimensions([length, width])
        self.rotation = float(rotation)
        self.in_flux = in_flux

        self._head = None
        self._tail = None

        self._head_left = None
        self._head_right = None
        self._tail_left = None
        self._tail_right = None

        self._region = None

        self._update()