Esempio n. 1
0
    def self_intersects(self):
        '''
        Algorithm to check for self intersections in a Bézier curve as explained
        in 'Calculating the Self-Intersction of Bézier Curves' by Dieter Lasser
        from Technische Hochschule Darmstadt Department of Mathematics, in West
        Germany. We're only interested in if there is a self intersection though
        '''
        # Lines connecting initial point, control points and final point of curve
        # in that order
        line1 = QLineF(self.initialPoint.position, self.ctrlPoint1.position)
        line2 = QLineF(self.ctrlPoint1.position, self.ctrlPoint2.position)
        line3 = QLineF(self.ctrlPoint2.position, self.finalPoint.position)

        # Angles between the 3 lines
        angle1 = line1.angleTo(
            line2)  # Positive angle between the first two lines
        # Fixing the sine for the first angle
        if line1.angle() < line2.angle():
            angle1 *= -1
        angle2 = line2.angleTo(
            line3)  # Positive angle between the last two lines
        # Fixing the sine for the second angle
        if line2.angle() < line3.angle():
            angle2 *= -1

        # If the angles sum up to 180 degrees or greater, there is a self-intersection
        if abs(angle1 + angle2) > 180:
            return True
        # Othewise, there is no self intersection
        return False
Esempio n. 2
0
    def findNearestPoint(self, part_item, target_scenepos):
        """
        Args:
            part_item (TYPE): Description
            target_scenepos (TYPE): Description
        """
        li = self._line_item
        pos = li.mapFromScene(target_scenepos)

        line = li.line()
        mouse_point_vec = QLineF(self._CENTER_OF_HELIX, pos)

        # Check if the click happened on the origin VH
        if mouse_point_vec.length() < self._RADIUS:
            # return part_item.mapFromScene(target_scenepos)
            return None

        angle_min = 9999
        direction_min = None
        for vector in self.vectors:
            angle_new = mouse_point_vec.angleTo(vector)
            if angle_new < angle_min:
                direction_min = vector
                angle_min = angle_new
        if direction_min is not None:
            li.setLine(direction_min)
            return part_item.mapFromItem(li, direction_min.p2())
        else:
            print("default point")
            line.setP2(pos)
            li.setLine(line)
            return part_item.mapFromItem(li, pos)
Esempio n. 3
0
    def setActive5p(self, is_active, neighbor_item=None):
        """Summary

        Args:
            is_active (TYPE): Description
            neighbor_item (None, optional): Description
        """
        phos = self.phos_item
        bond = self.bond_3p
        if bond is None:
            return
        if not self.is_active5p and is_active:
            self.pre_xover_item_group.virtual_helix_item.setZValue(styles.ZGRIDHELIX + 10)
            self.is_active5p = True
            if neighbor_item is not None:
                n_scene_pos = neighbor_item.scenePos()
                p2 = self.mapFromScene(n_scene_pos)
                bline = bond.line()
                test = QLineF(bline.p1(), p2)
                # angle = test.angleTo(bline) + self.theta0 if self.is_fwd else -bline.angleTo(test) + self.theta0
                angle = -bline.angleTo(test) + self.theta0 if self.is_fwd else test.angleTo(bline) + self.theta0
            else:
                p2 = self._active_p2_3p
                angle = -90 if self.is_fwd else 90
            self.animate(phos, 'rotation', 300, self.theta0, angle)
            self.animate(bond, 'bondp2', 300, self._default_p2_3p, p2)
        elif self.is_active5p:
            self.pre_xover_item_group.virtual_helix_item.setZValue(styles.ZGRIDHELIX)
            self.is_active5p = False
            self.animate(phos, 'rotation', 300, phos.rotation(), self.theta0)
            self.animate(bond, 'bondp2', 300, bond.line().p2(), self._default_p2_3p)
Esempio n. 4
0
    def findNearestPoint(self, part_item, target_scenepos):
        """
        Args:
            part_item (TYPE): Description
            target_scenepos (TYPE): Description
        """
        li = self._line_item
        pos = li.mapFromScene(target_scenepos)

        line = li.line()
        mouse_point_vec = QLineF(self._CENTER_OF_HELIX, pos)

        # Check if the click happened on the origin VH
        if mouse_point_vec.length() < self._RADIUS:
            # return part_item.mapFromScene(target_scenepos)
            return None

        angle_min = 9999
        direction_min = None
        for vector in self.vectors:
            angle_new = mouse_point_vec.angleTo(vector)
            if angle_new < angle_min:
                direction_min = vector
                angle_min = angle_new
        if direction_min is not None:
            li.setLine(direction_min)
            return part_item.mapFromItem(li, direction_min.p2())
        else:
            print("default point")
            line.setP2(pos)
            li.setLine(line)
            return part_item.mapFromItem(li, pos)
Esempio n. 5
0
    def setActive5p(self, is_active, neighbor_item=None):
        """Summary

        Args:
            is_active (TYPE): Description
            neighbor_item (None, optional): Description
        """
        phos = self.phos_item
        bond = self.bond_3p
        if bond is None:
            return
        if not self.is_active5p and is_active:
            self.pre_xover_item_group.virtual_helix_item.setZValue(styles.ZSLICEHELIX + 10)
            self.is_active5p = True
            if neighbor_item is not None:
                n_scene_pos = neighbor_item.scenePos()
                p2 = self.mapFromScene(n_scene_pos)
                bline = bond.line()
                test = QLineF(bline.p1(), p2)
                # angle = test.angleTo(bline) + self.theta0 if self.is_fwd else -bline.angleTo(test) + self.theta0
                angle = -bline.angleTo(test) + self.theta0 if self.is_fwd else test.angleTo(bline) + self.theta0
            else:
                p2 = self._active_p2_3p
                angle = -90 if self.is_fwd else 90
            self.animate(phos, 'rotation', 300, self.theta0, angle)
            self.animate(bond, 'bondp2', 300, self._default_p2_3p, p2)
        elif self.is_active5p:
            self.pre_xover_item_group.virtual_helix_item.setZValue(styles.ZSLICEHELIX)
            self.is_active5p = False
            self.animate(phos, 'rotation', 300, phos.rotation(), self.theta0)
            self.animate(bond, 'bondp2', 300, bond.line().p2(), self._default_p2_3p)
Esempio n. 6
0
 def area(self) -> float:
     d1 = QLineF(self.points[0], self.points[2])
     d2 = QLineF(self.points[1], self.points[3])
     angle = d1.angleTo(d2)
     angle = math.radians(angle)
     d1 = d1.length()
     d2 = d2.length()
     return abs(d1 * d2 * math.sin(angle))
Esempio n. 7
0
    def draw(self, painter):
        rect = QRectF(self.center.x() - self.radius,
                      self.center.y() - self.radius, self.radius * 2,
                      self.radius * 2)
        lineA = QLineF(self.center, self.A)
        lineB = QLineF(self.center, self.B)

        sweepAngle = lineA.angleTo(lineB)
        if (sweepAngle > 180):
            sweepAngle -= 360

        painter.drawArc(rect, 16 * lineA.angle(), 16 * sweepAngle)