def _generate_shapes(self) -> Dict[str, Shape]:
        arrow1 = Arrow(
            self._edge + (self._edge - self._center) * self._offset, self._edge
        )
        text = LineAnnotation(self._text, arrow1, TextPosition.START)
        text.style.font_size = 24
        ret_dict = {"arrow1": arrow1, "text": text}

        if self._diameter:
            inward_vector = self._center - self._edge
            offset_vector = inward_vector.unit_vector * self._offset
            start = self._edge + inward_vector * 2 + offset_vector
            end = self._edge + inward_vector * 2

            ret_dict["arrow2"] = Arrow(start, end)

        if self._center_mark:
            ret_dict["center_mark_h"] = Line(
                self._center - Point(-self._offset * 0.5, 0),
                self._center - Point(self._offset * 0.5, 0),
            )
            ret_dict["center_mark_v"] = Line(
                self._center - Point(0, -self._offset * 0.5),
                self._center - Point(0, self._offset * 0.5),
            )

        if self._center_line:
            ret_dict["center_line"] = Line(self._edge, self._center)

        if self._center_line and self._diameter:
            ret_dict["center_line2"] = Line(
                self._center, self._center + (self._center - self._edge)
            )
        return ret_dict
    def _generate_extension_lines(self) -> Dict[str, Shape]:
        extension_lines = {}

        def extension_line_vector(p: Point, c: Point):
            if self._orientation == self.Orientation.EXTERNAL:
                vec = (p - c).unit_vector
            elif self._orientation == self.Orientation.INTERNAL:
                vec = (p - c).unit_vector * -1
            else:
                raise ValueError(
                    f"Invalid value for Orientation: {self._orientation}")
            return vec

        if self._extension_lines:
            extension_line1_vector = extension_line_vector(
                self._start, self._center)
            extension_lines["extension_line_1"] = Line(
                self._start + extension_line1_vector * self._minor_offset,
                self._start + extension_line1_vector *
                (self._offset + self._minor_offset),
            )

            extension_line2_vector = extension_line_vector(
                self._end, self._center)
            extension_lines["extension_line_2"] = Line(
                self._end + extension_line2_vector * self._minor_offset,
                self._end + extension_line2_vector *
                (self._offset + self._minor_offset),
            )
        return extension_lines
Beispiel #3
0
    def __init__(
        self,
        start: Point,
        length: float,
        width: float = None,
        bar_length: float = None,
        num_windings: int = 11,
        teeth: bool = False,
    ):
        B = start
        n = num_windings - 1  # n counts teeth intervals
        if n <= 6:
            n = 7
        # n must be odd:
        if n % 2 == 0:
            n = n + 1
        L = length
        if width is None:
            w = L / 10.0
        else:
            w = width / 2.0
        s = bar_length

        shapes = {}
        if s is None:
            f = Spring.spring_fraction
            s = L * (1 - f) / 2.0  # start of spring

        self.bar_length = s  # record
        self.width = 2 * w

        p0 = Point(B.x, B.y + s)
        p1 = Point(B.x, B.y + L - s)
        p2 = Point(B.x, B.y + L)

        if s >= L:
            raise ValueError(
                "length of first bar: %g is larger than total length: %g" %
                (s, L))

        shapes["bar1"] = Line(B, p0)
        spring_length = L - 2 * s
        t = spring_length / n  # height increment per winding
        if teeth:
            resolution = 4
        else:
            resolution = 90
        q = np.linspace(0, n, n * resolution + 1)
        xs = p0.x + w * np.sin(2 * np.pi * q)
        ys = p0.y + q * t
        points = Point.from_coordinate_lists(xs, ys)
        shapes["spiral"] = Curve(points)
        shapes["bar2"] = Line(p1, p2)
        super().__init__(shapes)
Beispiel #4
0
    def __init__(
        self, center: Point, radius: float, inner_radius: float = None, nlines: int = 10
    ):
        self._center = center
        self._radius = radius
        self._inner_radius = inner_radius
        self._nlines = nlines

        if inner_radius is None:
            self._inner_radius = radius / 5.0

        outer = Circle(center, radius)
        inner = Circle(center, inner_radius)
        lines = []
        # Draw nlines+1 since the first and last coincide
        # (then nlines lines will be visible)
        t = np.linspace(0, 2 * np.pi, nlines + 1)

        xinner = self._center.x + self._inner_radius * np.cos(t)
        yinner = self._center.y + self._inner_radius * np.sin(t)
        xouter = self._center.x + self._radius * np.cos(t)
        youter = self._center.y + self._radius * np.sin(t)
        lines = [
            Line(Point(xi, yi), Point(xo, yo))
            for xi, yi, xo, yo in zip(xinner, yinner, xouter, youter)
        ]
        super().__init__(
            {
                "inner": inner,
                "outer": outer,
                "spokes": Composition(
                    {"spoke%d" % i: lines[i] for i in range(len(lines))}
                ),
            }
        )
    def __init__(
        self,
        start: Point,
        height: float,
        profile: Callable[[float], Point],
        num_arrows: int,
        scaling: float = 1,
    ):

        self._start = start
        self._height = height
        self._profile = profile
        self._num_arrows = num_arrows
        self._scaling = scaling

        shapes = dict()

        # Draw left line
        shapes["start line"] = Line(self._start,
                                    (self._start + Point(0, self._height)))

        # Draw velocity arrows
        dy = float(self._height) / (self._num_arrows - 1)

        end_points = []

        for i in range(self._num_arrows):
            start_position = Point(start.x, start.y + i * dy)
            end_position = start_position + profile(
                start_position.y) * self._scaling
            end_points += [end_position]
            if start_position == end_position:
                continue
            shapes["arrow%d" % i] = Arrow(start_position, end_position)

        shapes["smooth curve"] = Spline(end_points)
        super().__init__(shapes)
Beispiel #6
0
    def __init__(
        self,
        start: Point,
        total_length: float,
        bar_length: float = None,
        width: float = None,
        dashpot_length: float = None,
        piston_pos: float = None,
    ):
        B = start
        L = total_length
        if width is None:
            w = L / 10.0  # total width 1/5 of length
        else:
            w = width / 2.0
        s = bar_length

        shapes = {}
        # dashpot is p0-p1 in y and width 2*w
        if dashpot_length is None:
            if s is None:
                f = Dashpot._dashpot_fraction
                s = L * (1 - f) / 2.0  # default
            p1 = Point(B.x, B.y + L - s)
            dashpot_length = f * L
        else:
            if s is None:
                f = 1.0 / 2  # the bar lengths are taken as f*dashpot_length
                s = f * dashpot_length  # default
            p1 = Point(B.x, B.y + s + dashpot_length)
        p0 = Point(B.x, B.y + s)
        p2 = Point(B.x, B.y + L)

        if not (p2.y > p1.y > p0.y):
            raise ValueError(
                ("Dashpot has inconsistent dimensions! start: %g, "
                 "dashpot begin: %g, dashpot end: %g, very end: %g" %
                 (B.y, p0.y, p1.y, p2.y)))

        shapes["line start"] = Line(B, p0)

        shapes["pot"] = Curve([
            Point(p1.x - w, p1.y),
            Point(p0.x - w, p0.y),
            Point(p0.x + w, p0.y),
            Point(p1.x + w, p1.y),
        ])
        piston_thickness = dashpot_length * Dashpot._piston_thickness_fraction
        if piston_pos is None:
            piston_pos = 1 / 3.0 * dashpot_length
        if piston_pos < 0:
            piston_pos = 0
        elif piston_pos > dashpot_length:
            piston_pos = dashpot_length - piston_thickness

        abs_piston_pos = p0.y + piston_pos

        gap = w * Dashpot._piston_gap_fraction
        shapes["piston"] = Composition({
            "line":
            Line(p2, Point(B.x, abs_piston_pos + piston_thickness)),
            "rectangle":
            Rectangle(
                Point(B.x - w + gap, abs_piston_pos),
                2 * w - 2 * gap,
                piston_thickness,
            ),
        })
        shapes["piston"]["rectangle"].set_fill_pattern(Style.FillPattern.CROSS)

        super().__init__(shapes)
 def extension_line(start: Point, end: Point) -> Line:
     return Line(
         start + (end - start) * self._minor_offset,
         end + (end - start) * self._minor_offset,
     )