File size: 4,740 Bytes
26f7fa0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
"""
MLSTRUCT-FP - DB - CRECT

Rectangle component (wall segment).
"""

__all__ = ['Rect']

from MLStructFP.db._c import BaseComponent
from MLStructFP._types import NumberType, NumberInstance, List, TYPE_CHECKING
from MLStructFP.utils import GeomLine2D, GeomPoint2D

import matplotlib.pyplot as plt
import plotly.graph_objects as go

if TYPE_CHECKING:
    from MLStructFP.db._floor import Floor


class Rect(BaseComponent):
    """
    FP Rectangle.
    """
    angle: float
    length: float
    line: GeomLine2D
    partition: bool
    thickness: float
    wall: int

    def __init__(
            self,
            rect_id: int,
            wall_id: int,
            floor: 'Floor',
            angle: NumberType,
            length: NumberType,
            thickness: NumberType,
            x: List[float],
            y: List[float],
            line_m: NumberType,
            line_n: NumberType,
            line_theta: NumberType,
            partition: bool
    ) -> None:
        """
        Constructor.

        :param rect_id: ID of the rect
        :param wall_id: ID of the wall
        :param floor: Floor object
        :param angle: Rect angle
        :param length: Rect length
        :param thickness: Rect thickness
        :param x: List of coordinates within x-axis
        :param y: List of coordinates within y-axis
        :param line_m: Line slope
        :param line_n: Line intercept
        :param line_theta: Line angle
        :param partition: Rect is partition wall
        """
        BaseComponent.__init__(self, rect_id, x, y, floor)
        assert isinstance(wall_id, int) and wall_id > 0
        assert isinstance(angle, NumberInstance)
        assert isinstance(length, NumberInstance) and length > 0
        assert isinstance(line_m, NumberInstance)
        assert isinstance(line_n, NumberInstance)
        assert isinstance(line_theta, NumberInstance)
        assert isinstance(partition, bool)
        self.angle = float(angle)
        self.length = float(length)
        self.line = GeomLine2D()
        self.line.m = float(line_m)
        self.line.n = float(line_n)
        self.line.theta = float(line_theta)
        self.partition = partition
        self.thickness = float(thickness)
        self.wall = wall_id
        # noinspection PyProtectedMember
        self.floor._rect[self.id] = self

    def get_mass_center(self) -> 'GeomPoint2D':
        """
        Returns the mass center of the rect.
        """
        return GeomPoint2D(sum(p.x for p in self._points), sum(p.y for p in self._points)).scale(1 / len(self._points))

    def plot_plotly(
            self,
            fig: 'go.Figure',
            dx: NumberType = 0,
            dy: NumberType = 0,
            postname: str = '',
            fill: bool = False,
            opacity: NumberType = 1.0,
            color: str = '',
            show_legend: bool = True
    ) -> None:
        """
        Plot rect.

        :param fig: Figure object
        :param dx: X displacement
        :param dy: Y displacement
        :param postname: String added at the end of the name
        :param fill: Fill figure
        :param opacity: Object opacity
        :param color: Color, if empty use default object color
        :param show_legend: Add object legend to plot
        """
        px, py = [p.x for p in self._points], [p.y for p in self._points]
        px.append(px[0])
        py.append(py[0])
        if color == '':
            color = '#0000ff'
        for i in range(len(px)):
            px[i] += dx
            py[i] += dy
        _fill = 'none'
        if fill:
            _fill = 'toself'
        fig.add_trace(go.Scatter(
            fill=_fill,
            line=dict(color=color),
            mode='lines',
            name=f'Rect ID {self.id} - W {self.wall}{round(self.angle, 3)}°{postname}',
            opacity=opacity,
            showlegend=show_legend,
            x=px,
            y=py
        ))

    def plot_matplotlib(
            self,
            ax: 'plt.Axes',
            linewidth: NumberType = 2.0,
            alpha: NumberType = 1.0,
            color: str = '',
            fill: bool = True
    ) -> None:
        """
        Plot simple using matplotlib.

        :param ax: Matplotlib axes reference
        :param linewidth: Plot linewidth
        :param alpha: Alpha transparency value (0-1)
        :param color: Override color
        :param fill: Fill rect object
        """
        if color == '':
            color = '#000000'
        px, py = [p.x for p in self._points], [p.y for p in self._points]
        if fill:
            ax.fill(px, py, color=color, lw=None, alpha=alpha)
        else:
            ax.plot(px, py, color=color, lw=linewidth, alpha=alpha)