コード例 #1
0
def output_to_svg(circle: Circle, config):
    style = style_from_config(config)
    label_style = label_style_from_config(config)

    return [
        svg.circle(circle, style),
        svg.text(f'O {circle.center}', circle.center, Vector(0, 0),
                 label_style),
        svg.text(f'r = {circle.radius}', circle.center, Vector(0, 20),
                 label_style)
    ]
コード例 #2
0
def caption_to_svg(caption: str, position: Point, angle: float, color: str,
                   config):
    """
    Creates the SVG caption with the `caption` text, located at
    `position` and rotated `angle` radians.

    :param caption: caption's text
    :param position: caption's position
    :param angle: caption's rotated angle
    :param color: caption's color
    :param config: configuration dictionary
    :return: `SVG`
    """
    font = config['font']['family']
    size = config['font']['size']

    rotation = make_rotation(angle, position)
    scale = make_scale(1, -1, position)
    transform = rotation.then(scale)

    return svg.text(caption, position, Vector(0, 0), [
        attributes.fill_color(color),
        attributes.affine_transform(transform),
        attributes.font_family(font),
        attributes.font_size(size)
    ])
コード例 #3
0
    def reaction_for_node(self, node: StrNodeSolution):
        """
        Computes the external reaction force for a given node.

        To compute the reaction, it takes into account the external
        loads and the internal forces from the bars connected to
        the node.

        A node that isn't externally constrained has no reaction
        force.

        :param node: node to compute the reaction force
        :return: reaction force on the node
        """
        if not node.is_constrained:
            return Vector(0, 0)

        forces = [
            bar.force_in_node(node) for bar in self.bars if bar.has_node(node)
        ]

        if node.is_loaded:
            forces.append(node.net_load.opposite())

        return reduce(operator.add, forces)
コード例 #4
0
    def net_load(self):
        """
        The net load vector: the result of adding all the applied
        external load vectors.

        :return: `Vector` net load
        """
        return reduce(operator.add, self.loads, Vector(0, 0))
コード例 #5
0
def input_to_svg(points: [Point], point_radius: float, config):
    style = style_from_config(config)
    label_style = label_style_from_config(config)
    [a, b, c] = points
    disp = Vector(1.25 * point_radius, 0)

    return [
        svg.circle(Circle(a, point_radius), style),
        svg.circle(Circle(b, point_radius), style),
        svg.circle(Circle(c, point_radius), style),
        svg.text(f'A {a}', a, disp, label_style),
        svg.text(f'B {b}', b, disp, label_style),
        svg.text(f'C {c}', c, disp, label_style)
    ]
コード例 #6
0
ファイル: structure_test.py プロジェクト: xpology/Mechanics
    def setUp(self):
        section = 5
        young = 10
        load = Vector(500, -1000)

        self.n_1 = StrNode(1, Point(0, 0))
        self.n_2 = StrNode(2, Point(0, 200))
        self.n_3 = StrNode(3, Point(400, 200), [load])
        self.b_12 = StrBar(1, self.n_1, self.n_2, section, young)
        self.b_23 = StrBar(2, self.n_2, self.n_3, section, young)
        self.b_13 = StrBar(3, self.n_1, self.n_3, section, young)

        self.structure = Structure([self.n_1, self.n_2, self.n_3],
                                   [self.b_12, self.b_23, self.b_13])
コード例 #7
0
ファイル: node_svg.py プロジェクト: xpology/Mechanics
    def node_to_svg(node: StrNodeSolution):
        radius = config['sizes']['node_radius']
        stroke_size = config['sizes']['stroke']
        stroke_color = config['colors']['node_stroke']
        fill_color = config['colors']['back']
        position = node.displaced_pos_scaled(settings.disp_scale)
        caption_pos = position.displaced(Vector(radius, radius))

        return svg.group([
            svg.circle(Circle(position, radius), [
                attributes.stroke_width(stroke_size),
                attributes.stroke_color(stroke_color),
                attributes.fill_color(fill_color)
            ]),
            caption_to_svg(f'{node.id}', caption_pos, 0, stroke_color, config)
        ])
コード例 #8
0
ファイル: load_parse.py プロジェクト: xpology/Mechanics
def parse_load(load_str: str):
    """
    Parses a load vector from a string or raises a `ValueError` if
    the given string doesn't follow the expected format.

    :param load_str: definition string
    :return: tuple of node id and load vector
    """

    match = re.match(__LOAD_REGEX, load_str)
    if not match:
        raise ValueError(
            f'Cannot parse load from string: "{load_str}"'
        )

    node_id = int(match.group('node_id'))
    [fx, fy] = [
        float(num)
        for num in match.group('vec').split(',')
    ]

    return node_id, Vector(fx, fy)
コード例 #9
0

def __generate_upper_horizontal_bars(spans: int, cross_sec: float,
                                     young: float):
    print('# upper horizontal bars')

    current_id = 7 * spans
    for i in range(3 * spans + 2, 4 * spans):
        __print_bar(current_id, i, i + 1, cross_sec, young)
        current_id += 1


def __print_bar(bar_id, id_from, id_to, cross_sec, young):
    print(f'{bar_id}: ({id_from} -> {id_to}) {cross_sec} {young}')


if __name__ == '__main__':
    if len(sys.argv) < 8:
        print('Usage:')
        print('\tgen_baltimore <spans> <span> <height> <section> ' +
              '<young> <Fx> <Fy>')
        sys.exit(1)

    generate_baltimore_structure(spans=int(sys.argv[1]),
                                 span=float(sys.argv[2]),
                                 height=float(sys.argv[3]),
                                 cross_sec=float(sys.argv[4]),
                                 young=float(sys.argv[5]),
                                 node_load=Vector(float(sys.argv[6]),
                                                  float(sys.argv[7])))
コード例 #10
0
ファイル: node_test.py プロジェクト: xpology/Mechanics
 def test_net_load(self):
     loads = [Vector(10, 20), Vector(30, 40)]
     node = StrNode(1, Point(2, 5), loads)
     expected = Vector(40, 60)
     self.assertEqual(expected, node.net_load)
コード例 #11
0
from math import sqrt
from typing import List

from geom2d import Segment, Vector
from graphic import svg
from graphic.svg import attributes
from structures.solution.bar import StrBarSolution
from .captions_svg import caption_to_svg

__I_VERSOR = Vector(1, 0)
__STRESS_DISP = 10
__DECIMAL_POS = 4


def bars_to_svg(bars: List[StrBarSolution], settings, config):
    """
    Creates the list of SVG elements representing the bars.

    :param bars: list of `StrBarSolution`
    :param settings:
    :param config:
    :return: list of SVG elements
    """
    def original_bar_to_svg(_bar: StrBarSolution):
        color = config['colors']['original']
        return __bar_svg(_bar.original_geometry, color, _bar.cross_section)

    def bar_to_svg(_bar: StrBarSolution):
        return __bar_svg(
            _bar.final_geometry_scaling_displacement(settings.disp_scale),
            bar_color(_bar), _bar.cross_section)
コード例 #12
0
ファイル: load_parse_test.py プロジェクト: xpology/Mechanics
 def test_parse_load_vector(self):
     expected = Vector(250.0, -3500.0)
     self.assertEqual(expected, self.load)
コード例 #13
0
 def test_text(self):
     actual = primitives.text('foo bar', Point(2, 3), Vector(4, 5))
     props = 'x="2" y="3" dx="4" dy="5"'
     expected = f'<text {props} >\n    foo bar\n</text>'
     self.assertEqual(expected, actual)
コード例 #14
0
 def __node_to_solution(self, node: StrNode) -> StrNodeSolution:
     (dof_x, dof_y) = self.__dofs_dict[node.id]
     disp = Vector(self.__global_displacements.value_at(dof_x),
                   self.__global_displacements.value_at(dof_y))
     return StrNodeSolution(node, disp)
コード例 #15
0
 def test_apply_load_to_node(self):
     node = self.structure._Structure__nodes[1]
     self.assertEqual(Vector(2500, -3500), node.net_load)