Skip to content

chemdiagrams.managers.collision_manager

CollisionManager

Container for methods related to calculating difference values for object collision avoidance.

Source code in src/chemdiagrams/managers/collision_manager.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
class CollisionManager:
    """
    Container for methods related to calculating difference values
    for object collision avoidance.
    """

    def __init__(
        self,
        figure_manager: FigureManager,
        constants: Constants,
    ) -> None:
        self.figure_manager = figure_manager
        self.constants = constants

    def _get_diff_img_plateau(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
    ) -> float:
        """Compute vertical spacing value for image plateau distance in data coordinates."""
        diff_to_plateau = (
            (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * self.constants.DISTANCE_IMAGE_LINE
        )
        return diff_to_plateau

    def _get_diff_img_number(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        fontsize: int,
    ) -> float:
        """Compute vertical spacing value for image number distance in data coordinates."""
        diff_to_number = (
            (fontsize / self.constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * self.constants.DISTANCE_NUMBER_LINE
        )
        return diff_to_number

    def _get_diff_to_label(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
    ) -> float:
        """Compute vertical spacing needed for label placement in data coordinates."""
        diff_to_label = (
            (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * (self.constants.DISTANCE_TO_LABEL)
        )
        return diff_to_label

    def _get_label_boundaries(
        self,
        label: Text,
    ) -> tuple[float, float]:
        """
        Get vertical maximum and minimum y boundaries of a label in data coordinates.

        Returns
        -------
        tuple
            A tuple of (y_min, y_max) for the label in data coordinates.
        """
        label_window = label.get_window_extent().transformed(
            self.figure_manager.ax.transData.inverted()
        )
        y_min = label_window.ymin
        y_max = label_window.ymax
        return (y_min, y_max)

    def _get_number_diffs(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        fontsize: int,
    ) -> tuple[float, float]:
        """
        Compute vertical spacing values for label placement in data coordinates.

        Both values scale proportionally with font size, y-axis range, and
        figure height so that spacing remains visually consistent regardless
        of the diagram's scale.

        Returns
        -------
        diff_bias : float
            The vertical gap between an energy bar and the first label.
        diff_per_step : float
            The vertical distance between consecutive stacked labels.
        """
        diff_bias = (
            (fontsize / self.constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * self.constants.DISTANCE_NUMBER_LINE
        )
        diff_per_step = (
            (fontsize / self.constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * self.constants.DISTANCE_NUMBER_NUMBER
        )
        return diff_bias, diff_per_step

    def _get_axis_break_stopper_differences(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        angle: float,
    ) -> tuple[float, float]:
        """
        Compute data coordinate differences for axis break stoppers in x and y directions.
        """
        delta_x = (
            np.cos(angle * np.pi / 180)
            * 0.001
            * (margins["x"][1] - margins["x"][0])
            / figsize[0]
        )
        delta_y = (
            np.sin(angle * np.pi / 180)
            * 0.001
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
        )
        return delta_x, delta_y

    def _get_axis_break_whitespace_cover_width(
        self,
        margins: dict[str, tuple],
        figsize: tuple[float, float],
    ) -> float:
        """Compute data coordinate width for axis break whitespace cover."""
        cover_width = (
            self.constants.MERGED_PLATEAU_COVER_WIDTH
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
        )
        return cover_width