Пример #1
0
    def test_full_rotate(self):
        point = (10, 10)
        origin = (0, 0)

        (x, y) = rotate(origin, point, 2 * math.pi)
        self.assertAlmostEqual(x, 10, delta=0.00000001)
        self.assertAlmostEqual(y, 10, delta=0.00000001)
Пример #2
0
    def test_rotate_63(self):
        point = (-4, 4)
        origin = (-4, 1.98)

        (x, y) = rotate(origin, point, 0.35 * math.pi)
        self.assertAlmostEqual(x, -5.8, delta=0.01)
        self.assertAlmostEqual(y, 2.9, delta=0.01)
Пример #3
0
    def test_rotate_180(self):
        point = (10, 10)
        origin = (0, 0)

        (x, y) = rotate(origin, point, math.pi)
        self.assertAlmostEqual(x, -10, delta=0.00000001)
        self.assertAlmostEqual(y, -10, delta=0.00000001)
Пример #4
0
    def __get_spline_positions(self,
                               node1: PositionedNode,
                               node2: PositionedNode,
                               distance: float,
                               x_offset=0) -> (int, int, int, int):
        """
        Get initial spline positions relative to nodes.
        """
        tan = math.atan2(node1.y - node2.y, node1.x - node2.x)
        spline1_x, spline1_y = rotate([node1.x, node1.y],
                                      [node1.x - x_offset, node1.y + distance],
                                      tan)

        spline2_x, spline2_y = rotate([node2.x, node2.y],
                                      [node2.x + x_offset, node2.y + distance],
                                      tan)

        return spline1_x, spline1_y, spline2_x, spline2_y
Пример #5
0
    def create_self_loop(self, node: PositionedNode, weight=""):
        """
        Create a self loop.
        """
        logger.debug("Create self loop")
        y_offset = -100
        y_offset_label = -40
        angle_deg = 45
        x, y = node.x, node.y
        spline_1x, spline_1y = rotate((x, y), (x, y + y_offset),
                                      math.radians(angle_deg))
        spline_2x, spline_2y = rotate((x, y), (x, y + y_offset),
                                      math.radians(-angle_deg))

        # Check if there are other self loops
        other_loops = list(
            filter(lambda branch: branch.start == node and branch.end == node,
                   self.__model.graph.branches))
        if (len(other_loops) > 0):
            all_far_away = False
            while (not all_far_away):
                all_far_away = True
                for branch in other_loops:
                    (exist_start, exist_end, exist_spline1,
                     exist_spline2) = self.__get_points_of_branch(branch)
                    new_spline1 = [spline_1x, spline_1y]
                    new_spline2 = [spline_2x, spline_2y]
                    if ((distance(exist_spline1, new_spline1) +
                         distance(exist_spline2, new_spline2) < 40)
                            or (distance(exist_spline1, new_spline2) +
                                distance(exist_spline2, new_spline1) < 40)):
                        all_far_away = False

                if (not all_far_away):
                    spline_1x += 30
                    spline_1y -= 30
                    spline_2x -= 30
                    spline_2y -= 30
        self.create_branch(node, node, spline_1x, spline_1y, spline_2x,
                           spline_2y, 0, y_offset_label, weight)
Пример #6
0
    def create_branch_auto_pos(self,
                               start_node: PositionedNode,
                               end_node: PositionedNode,
                               weight: str = ""):
        """Create branch between nodes, calculate initial spline positions"""
        logger.debug("Create branch auto pos")
        # Calculate initial spline position
        # Branch should not overlap with other branches

        if start_node is end_node:
            raise ValueError("Cannot create self loop, use dedicated method.")

        # Find Branches with similar start / end positions
        # or which are straight lines and are on the same line
        # (collinear points)
        overlap = list()
        for branch in self.__model.graph.branches:
            (exist_start, exist_end, exist_spline1,
             exist_spline2) = self.__get_points_of_branch(branch)

            new_start = [start_node.x, start_node.y]
            new_end = [end_node.x, end_node.y]

            # Add branch to overlap if it has similar start
            # and end points (check both ways if one branch is flipped)
            if ((distance(exist_start, new_start) +
                 distance(exist_end, new_end) < 40)
                    or (distance(exist_start, new_end) +
                        distance(exist_end, new_start) < 40)):
                overlap.append(branch)

            # Check if the existing branch is straight and
            # is on the same line as the new branch
            if (collinear([
                    exist_spline1, exist_spline2, exist_start, exist_end,
                    new_start, new_end
            ])):
                overlap.append(branch)

        # Calculate inital spline positions (forming a straight line)
        max_x = max(start_node.x, end_node.x)
        max_y = max(start_node.y, end_node.y)
        min_x = min(start_node.x, end_node.x)
        min_y = min(start_node.y, end_node.y)

        spline1_x = min_x + (max_x - min_x) / 2
        spline1_y = min_y + (max_y - min_y) / 2
        spline2_x, spline2_y = spline1_x, spline1_y

        if len(overlap) > 0:
            distance_step_size = math.hypot(max_x - min_x, max_y - min_y) / 2

            # Adjust the splines until all other branches are far away
            all_far_away = False
            i = 0
            j = 1

            # Start on the upper side
            use_left_side = (start_node.x < end_node.x)
            while (not all_far_away):
                all_far_away = True

                # Check all near branches for overlapping
                for o in overlap:
                    (exist_start, exist_end, exist_spline1,
                     exist_spline2) = self.__get_points_of_branch(o)

                    new_spline1 = [spline1_x, spline1_y]
                    new_spline2 = [spline2_x, spline2_y]
                    new_start = [start_node.x, start_node.y]
                    new_end = [end_node.x, end_node.y]

                    # Check if the splines have similar position which means
                    # that the branch have also a similar position
                    if ((distance(exist_spline1, new_spline1) +
                         distance(exist_spline2, new_spline2) < 40)
                            or (distance(exist_spline1, new_spline2) +
                                distance(exist_spline2, new_spline1) < 40)):
                        all_far_away = False

                    # Check if all points are on the same line
                    if (collinear([
                            exist_spline1, exist_spline2, exist_start,
                            exist_end, new_spline1, new_start, new_spline2,
                            new_end
                    ])):
                        if (self.__check_if_crossing([exist_start, exist_end],
                                                     [new_start, new_end])):
                            all_far_away = False

                # Increase spline position if any spline was to near
                if (not all_far_away):
                    if use_left_side:
                        (spline1_x, spline1_y, spline2_x,
                         spline2_y) = self.__get_spline_positions(
                             start_node, end_node, j * distance_step_size)
                    else:
                        (spline2_x, spline2_y, spline1_x,
                         spline1_y) = self.__get_spline_positions(
                             end_node, start_node, j * distance_step_size)

                    # Try other side on next iteration
                    use_left_side = not use_left_side
                    j += i % 2
                    i += 1

        # Calulate initial label position
        middle_x = (start_node.x + end_node.x) / 2
        middle_y = (start_node.y + end_node.y) / 2
        [label_x, label_y] = rotate([middle_x, middle_y],
                                    move([middle_x, middle_y],
                                         [end_node.x, end_node.y], 30),
                                    math.pi / 2)

        # Create branch
        self.create_branch(start_node, end_node, spline1_x, spline1_y,
                           spline2_x, spline2_y, label_x - middle_x,
                           label_y - middle_y, weight)
Пример #7
0
def rotate_point(origin: QPoint, point: QPoint, angle: QPoint):
    """
    Rotate point around origin by the angle.
    """
    [x, y] = rotate([origin.x(), origin.y()], [point.x(), point.y()], angle)
    return QPoint(x, y)