예제 #1
0
 def test_normal_vector(self, a: Point):
     if isclose(abs(a), 0.0):
         with pytest.raises(ZeroDivisionError):
             a.normal()
     else:
         angle = a.normal().angle() - a.angle()
         assert isclose(angle, np.pi / 2.0)
예제 #2
0
 def test_rotation_about_zero(self, a: Point, angle: Angle):
     assume(abs(a) != 0)
     b = a.rotate(angle, Point(0.0, 0.0))
     aa = a.angle()
     bb = b.angle()
     note(f"a angle: {aa}")
     note(f"b angle: {bb}")
     assert isclose(bb - aa, angle)
예제 #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)
예제 #4
0
 def test_angle(self, a: Point):
     if a.x != 0.0:
         assume(abs(a.y / a.x) < 1e4)
     if a.y != 0.0:
         assume(abs(a.x / a.y) < 1e4)
     angle = a.angle()
     note(angle)
     b = Point(abs(a), 0.0).rotate(angle, Point(0.0, 0.0))
     note(f"The angle is : {np.format_float_scientific(a.angle())}")
     note(f"The length is : {np.format_float_scientific(abs(a))}")
     assert b == a
     assert -np.pi <= angle <= np.pi
예제 #5
0
 def composition(self):
     shape1 = Line(Point(0, 1), Point(1, 1))
     shape2 = Line(Point(1, 1), Point(0, 2))
     text = Text("This is a test.", Point(2, 2))
     composition = Composition(
         {
             "shape1": shape1,
             "shape2": shape2,
             "test": text,
         }
     )
     return composition
예제 #6
0
def main():
    circle = Circle(Point(0, 0), 1)
    line = Line(Point(0, 0), Point(0, 1))

    def func(frame: int):
        new_line = line.rotate(Angle(2 * np.pi * frame / 360), Point(0, 0))
        model = Composition({"circle": circle, "line": new_line})
        return model

    fig = Figure(-1.2, 1.2, -1.2, 1.2, backend=MatplotlibBackend)
    fig.animate(func, (0, 360))
    fig.save_animation("animation.mp4")
예제 #7
0
 def test_rotation(self, a: Point, angle: Angle, center: Point):
     assume(abs(a - center) != 0)
     b = a.rotate(angle, center)
     new_angle = (b - center).angle() - (a - center).angle()
     note(angle)
     note(new_angle)
     assert isclose(angle, angle)
예제 #8
0
def main() -> None:
    logging.basicConfig(level=logging.INFO)

    L = 8.0
    H = 1.0
    x_pos = 2.0
    y_pos = 3.0

    fig = Figure(0, x_pos + 1.2 * L, 0, y_pos + 5 * H, MatplotlibBackend)

    p0 = Point(x_pos, y_pos)
    main = Rectangle(p0, L,
                     H).set_fill_pattern(Style.FillPattern.UP_LEFT_TO_RIGHT)
    h = L / 16  # size of support, clamped wall etc
    support = SimpleSupport(p0, h)
    clamped = Rectangle(p0 + Point(L, 0) - Point(0, 2 * h), h, 6 *
                        h).set_fill_pattern(Style.FillPattern.UP_RIGHT_TO_LEFT)
    F_pt = Point(p0.x + L / 2, p0.y + H)
    force = Force("$F$", F_pt + Point(0, 2 * H), F_pt).set_line_width(3)
    L_dim = LinearDimension("$L$", Point(x_pos, p0.y - 3 * h),
                            Point(x_pos + L, p0.y - 3 * h))
    beam = Composition({
        "main": main,
        "simply supported end": support,
        "clamped end": clamped,
        "force": force,
        "L": L_dim,
    })

    fig.add(beam)
    fig.show()
예제 #9
0
 def test_unit_vector(self, x: float, y: float):
     a = Point(x, y)
     if isclose(abs(a), 0.0):
         with pytest.raises(ZeroDivisionError):
             a.unit_vector
     else:
         b = a.unit_vector
         note(f"angle of a: {np.format_float_scientific(a.angle)}")
         note(f"angle of b: {np.format_float_scientific(b.angle)}")
         assert isclose(a.angle, b.angle)
         note(f"magnitude of b: {abs(b)}")
         assert isclose(abs(b), 1.0)
예제 #10
0
def inclined_plane():
    theta = np.pi / 6
    L = 10.0
    a = 1.0
    x_min = 0.0
    y_min = -3.0

    B = Point(a + L, 0)
    A = Point(a, np.tan(theta) * L)

    wall = Wall([A, B], thickness=-0.25)
    wall.style.fill_pattern = Style.FillPattern.UP_LEFT_TO_RIGHT

    angle = ArcWithText(
        r"$\theta$", center=B, radius=3, start_angle=np.pi - theta, arc_angle=theta
    )
    angle.style.line_color = Style.Color.BLACK
    angle.style.line_width = 1

    ground = Line(Point(B.x - L / 10.0, 0), Point(B.x - L / 2.0, 0))
    ground.style.line_color = Style.Color.BLACK
    ground.style.line_style = Style.LineStyle.DASHED
    ground.style.line_width = 1

    r = 1.0  # radius of wheel
    help_line = Line(A, B)
    x = a + 3 * L / 10.0
    y = help_line(x=x)
    contact = Point(x, y)
    normal_vec = Point(np.sin(theta), np.cos(theta))
    c = contact + normal_vec * r
    outer_wheel = (
        Circle(c, r).set_line_color(Style.Color.BLUE).set_fill_color(Style.Color.BLUE)
    )
    hole = (
        Circle(c, r / 2.0)
        .set_line_color(Style.Color.BLUE)
        .set_fill_color(Style.Color.WHITE)
    )
    wheel = Composition({"outer": outer_wheel, "inner": hole})

    N = Force("$N$", contact - normal_vec * 2 * r, contact, spacing=0.2)
    N.style.line_color = Style.Color.BLACK

    # text_alignment='left')
    mg = Gravity(c, 3 * r, text="$Mg$", text_position=Gravity.TextPosition.END)

    x_const = Line(contact, contact + Point(0, 4))
    x_const.style.line_style = Style.LineStyle.DOTTED
    x_const = x_const.rotate(-theta, contact)

    x_axis = Axis(
        start=contact + normal_vec * 3.0 * r,
        length=4 * r,
        label="$x$",
        rotation_angle=-theta,
    )

    body = Composition({"wheel": wheel, "N": N, "mg": mg})
    fixed = Composition(
        {
            "angle": angle,
            "inclined wall": wall,
            "wheel": wheel,
            "ground": ground,
            "x start": x_const,
            "x axis": x_axis,
        }
    )

    model = Composition({"fixed elements": fixed, "body": body})

    fig = Figure(x_min, x_min + 1.5 * L, y_min, y_min + L, backend=MatplotlibBackend)

    fig.add(model)
    fig.show()
    time.sleep(1)
    tangent_vec = Point(normal_vec.y, -normal_vec.x)

    def position(t):
        """Position of center point of wheel."""
        return c + tangent_vec * 7 * t ** 2

    def move(fig: Shape, t: float, dt: float = None) -> fig:
        x = position(t)
        x0 = position(t - dt)
        displacement = x - x0
        return fig["body"].translate(displacement)
예제 #11
0
 def test_coordinates(self, x: float, y: float) -> None:
     p = Point(x, y)
     assert p.x == x
     assert p.y == y
예제 #12
0
 def composition(self):
     shape1 = Line(Point(0, 1), Point(1, 1))
     shape2 = Line(Point(1, 1), Point(0, 2))
     composition = Composition({"shape1": shape1, "shape2": shape2})
     return composition
예제 #13
0
 def func(frame: int):
     new_line = line.rotate(Angle(2 * np.pi * frame / 360), Point(0, 0))
     model = Composition({"circle": circle, "line": new_line})
     return model
예제 #14
0
 def test_equality(self, x: float, y: float) -> None:
     assert Point(x, y) == Point(x, y)
예제 #15
0
 def test_adding(self, x1: float, x2: float, y1: float, y2: float):
     a = Point(x1, y1)
     b = Point(x2, y2)
     assert a + b == Point(x1 + x2, y1 + y2)
예제 #16
0
 def test_abs(self, x: float, y: float):
     assume(x * x != inf)
     assume(y * y != inf)
     a = Point(x, y)
     assert abs(a) == np.hypot(x, y)
예제 #17
0
 def test_scale(self, x: float, y: float, s: float):
     a = Point(x, y)
     assert a.scale(s) == Point(x * s, y * s)
예제 #18
0
 def test_multiplication(self, x: float, y: float, s: float):
     a = Point(x, y)
     assert a * s == Point(x * s, y * s)
예제 #19
0
 def test_subtraction(self, x1: float, x2: float, y1: float, y2: float):
     a = Point(x1, y1)
     b = Point(x2, y2)
     assert a - b == Point(x1 - x2, y1 - y2)
예제 #20
0
 def test_translation(self, x1: float, x2: float, y1: float, y2: float):
     a = Point(x1, y1)
     b = Point(x2, y2)
     assert a + b == Point(x1 + x2, y1 + y2)