예제 #1
0
    def lines(self):
        textsize = self.textsize(self._result, scaled=True)

        dx, _ = self.box.get_padding_for(textsize, halign=self.halign,
                                         padding=self.padding)

        width = self.box.width - dx + self.line_spacing
        base_xy = XY(self.box.x1, self.box.y1)
        for string in self._result:
            textsize = self.textsize(string, scaled=True)
            _, dy = self.box.get_padding_for(textsize, valign=self.valign,
                                             padding=self.line_spacing)

            height = dy
            width -= textsize.width + self.line_spacing
            for char in string:
                charsize = self.textsize(char, scaled=True)

                if self.adjustBaseline:
                    draw_xy = base_xy.shift(width, height + charsize.height)
                else:
                    draw_xy = base_xy.shift(width, height)

                yield char, draw_xy

                height += charsize.height + self.line_spacing
예제 #2
0
    def lines(self):
        textsize = self.textsize(self._result, scaled=True)

        _, dy = self.box.get_padding_for(textsize, valign=self.valign,
                                         padding=self.line_spacing)

        height = dy
        base_xy = XY(self.box.x1, self.box.y1)
        for string in self._result:
            textsize = self.textsize(string, scaled=True)
            dx, _ = self.box.get_padding_for(textsize, halign=self.halign,
                                             padding=self.padding)

            if self.adjustBaseline:
                draw_xy = base_xy.shift(dx, height + textsize.height)
            else:
                draw_xy = base_xy.shift(dx, height)

            yield string, draw_xy

            height += textsize.height + self.line_spacing
예제 #3
0
파일: metrics.py 프로젝트: Jenyay/outwiker
    def _scale(cls, value, ratio):
        if ratio == 1:
            return value

        klass = value.__class__
        if klass == XY:
            ret = XY(value.x * ratio, value.y * ratio)
        elif klass == Size:
            ret = Size(value.width * ratio, value.height * ratio)
        elif klass == Box:
            ret = Box(value[0] * ratio, value[1] * ratio,
                      value[2] * ratio, value[3] * ratio)
        elif klass == tuple:
            ret = tuple([cls.scale(x, ratio) for x in value])
        elif klass == list:
            ret = [cls.scale(x, ratio) for x in value]
        elif klass == EdgeLines:
            ret = EdgeLines()
            ret.polylines = cls.scale(value.polylines, ratio)
        elif klass == FontInfo:
            ret = FontInfo(value.familyname, value.path, value.size * ratio)
        elif klass == int:
            ret = value * ratio
        elif klass == str:
            ret = value
        else:
            ret = cls(value, ratio)

        return ret
예제 #4
0
    def func(self, *args, **kwargs):
        args = list(args)

        if kwargs.get('filter') not in ('blur', 'transp-blur'):
            return fn(self, *args, **kwargs)
        else:
            box = get_shape_box(*args)
            args[0] = get_abs_coordinate(box, *args)

            size = Size(box.width + PADDING * 2, box.height + PADDING * 2)
            shadow = create_shadow(self, size, *args, **kwargs)
            xy = XY(box.x1 - PADDING, box.y1 - PADDING)
            self.paste(shadow, xy, shadow)
예제 #5
0
    def lifeline(self, node):
        delayed = []
        for sep in self.separators:
            if sep.type == 'delay':
                delayed.append(sep)

        lines = []
        d = self.cellsize
        pt = self.node(node).bottom
        for sep in delayed:
            m = self.cell(sep)
            y1 = m.top.y
            y2 = m.bottom.y
            lines.append(((pt, XY(pt.x, y1)), '8,4'))
            lines.append(((XY(pt.x, y1 + d), XY(pt.x, y2 - d)), '2,8'))

            pt = XY(pt.x, y2)

        y = self.bottomheight + self.cellsize * 4
        lines.append(((pt, XY(pt.x, y)), '8,4'))

        return lines
예제 #6
0
 def __init__(self, elemid):
     self.id = unquote(elemid)
     self.label = ''
     self.xy = XY(0, 0)
     self.group = None
     self.drawable = False
     self.order = 0
     self.color = self.basecolor
     self.width = None
     self.height = None
     self.colwidth = 1
     self.colheight = 1
     self.stacked = False
예제 #7
0
    def racknumber(self, rack, number):
        if rack.descending:
            y = rack.colheight - number - 1
        else:
            y = number

        dummy = elements.DiagramNode(None)
        dummy.xy = XY(rack.xy.x, y)
        dummy.colwidth = 1
        dummy.colheight = 1

        box = self.cell(dummy, use_padding=False).box
        return Box(0, box[1], box[0], box[3])
예제 #8
0
    def outlinebox(self):
        corners = []
        for string, xy in self.lines:
            textsize = self.textsize(string)
            width = textsize[0] * self.scale
            height = textsize[1] * self.scale

            if self.adjustBaseline:
                xy = XY(xy.x, xy.y - textsize[1])

            corners.append(xy)
            corners.append(XY(xy.x + width, xy.y + height))

        if corners:
            box = Box(min(p.x for p in corners) - self.padding,
                      min(p.y for p in corners) - self.line_spacing,
                      max(p.x for p in corners) + self.padding,
                      max(p.y for p in corners) + self.line_spacing)
        else:
            box = Box(self.box[0], self.box[1], self.box[0], self.box[1])

        return box
예제 #9
0
    def shift_shadow(self, value):
        xdiff = self.metrics.shadow_offset.x
        ydiff = self.metrics.shadow_offset.y

        if isinstance(value, XY):
            ret = XY(value.x + xdiff, value.y + ydiff)
        elif isinstance(value, Box):
            ret = Box(value.x1 + xdiff, value.y1 + ydiff, value.x2 + xdiff,
                      value.y2 + ydiff)
        elif isinstance(value, (list, tuple)):
            ret = [self.shift_shadow(x) for x in value]

        return ret
예제 #10
0
파일: drawer.py 프로젝트: tk0miya/seqdiag
    def edge_shadow(self, edge):
        m = self.metrics
        dx, dy = m.shadow_offset

        if edge.leftnote:
            polygon = m.edge(edge).leftnoteshape
            shadow = [XY(pt.x + dx, pt.y + dy) for pt in polygon]
            if self.diagram.shadow_style == 'solid':
                self.drawer.polygon(shadow, fill=self.shadow,
                                    outline=self.shadow)
            else:
                self.drawer.polygon(shadow, fill=self.shadow,
                                    outline=self.shadow, filter='transp-blur')

        if edge.rightnote:
            polygon = m.edge(edge).rightnoteshape
            shadow = [XY(pt.x + dx, pt.y + dy) for pt in polygon]
            if self.diagram.shadow_style == 'solid':
                self.drawer.polygon(shadow, fill=self.shadow,
                                    outline=self.shadow)
            else:
                self.drawer.polygon(shadow, fill=self.shadow,
                                    outline=self.shadow, filter='transp-blur')
예제 #11
0
파일: actor.py 프로젝트: xillmera/outwiker
    def __init__(self, node, metrics=None):
        super(Actor, self).__init__(node, metrics)

        m = metrics.cell(node)
        if node.label:
            font = metrics.font_for(self.node)
            textsize = metrics.textsize(node.label, font)
            shortside = min(m.width, m.height - textsize.height)
        else:
            textsize = Size(0, 0)
            shortside = min(m.width, m.height)

        r = self.radius = shortside // 8  # radius of actor's head
        self.center = metrics.cell(node).center

        self.connectors[0] = XY(self.center.x, self.center.y - r * 9 // 2)
        self.connectors[1] = XY(self.center.x + r * 4, self.center.y)
        self.connectors[2] = XY(self.center.x,
                                self.center.y + r * 4 + textsize.height)
        self.connectors[3] = XY(self.center.x - r * 4, self.center.y)

        self.textbox = Box(m.left.x, self.center.y + r * 4, m.right.x,
                           self.connectors[2].y)
예제 #12
0
    def lines(self):
        textsize = self.textsize(self._result, scaled=True)

        _, dy = self.box.get_padding_for(textsize,
                                         valign=self.valign,
                                         padding=self.line_spacing)

        height = dy
        base_xy = XY(self.box.x1, self.box.y1)
        for string in self._result:
            textsize = self.textsize(string, scaled=True)
            dx, _ = self.box.get_padding_for(textsize,
                                             halign=self.halign,
                                             padding=self.padding)

            if self.adjustBaseline:
                draw_xy = base_xy.shift(dx, height + textsize.height)
            else:
                draw_xy = base_xy.shift(dx, height)

            yield string, draw_xy

            height += textsize.height + self.line_spacing
예제 #13
0
    def _draw_background(self):
        metrics = self.metrics

        pagesize = self.pagesize()
        margin = metrics.page_margin
        for i in range(self.diagram.height + 2):
            height = margin.y + i * metrics.cellsize * 4
            _from = XY(margin.x, height)
            _to = XY(pagesize.x - margin.x, height)

            self.drawer.line((_from, _to), fill=self.fill)

        # left side of frame
        line = (XY(margin.x, margin.y), XY(margin.x, pagesize.y - margin.y))
        self.drawer.line(line, fill=self.fill)

        # right side of textbox
        line = (XY(margin.x + 10 * metrics.cellsize, margin.y),
                XY(margin.x + 10 * metrics.cellsize, pagesize.y - margin.y))
        self.drawer.line(line, fill=self.fill)

        # right side of frame
        line = (XY(pagesize.x - margin.x, margin.y),
                XY(pagesize.x - margin.x, pagesize.y - margin.y))
        self.drawer.line(line, fill=self.fill)

        for i in range(self.diagram.width - 1):
            width = margin.x + (i + 1 + 5) * metrics.cellsize * 2
            _from = XY(width, margin.y)
            _to = XY(width, pagesize.y - margin.y)

            self.drawer.line((_from, _to), fill='gray')

        # Smoothing back-ground images.
        if self.format == 'PNG':
            self.drawer.smoothCanvas()
예제 #14
0
파일: svg.py 프로젝트: sunlynx/blockdiag
    def arc(self, box, start, end, **kwargs):
        fill = kwargs.get('fill')

        w = box.width / 2
        h = box.height / 2

        if start > end:
            end += 360

        endpoints = ellipse_endpoints(1, w, h, start, end)
        pt1 = XY(box.x + w + round(endpoints[0].x, 0),
                 box.y + h + round(endpoints[0].y, 0))
        pt2 = XY(box.x + w + round(endpoints[1].x, 0),
                 box.y + h + round(endpoints[1].y, 0))

        if end - start > 180:
            largearc = 1
        else:
            largearc = 0

        pd = pathdata(pt1[0], pt1[1])
        pd.ellarc(w, h, 0, largearc, 1, pt2[0], pt2[1])
        p = path(pd, fill="none", stroke=rgb(fill), **drawing_params(kwargs))
        self.svg.addElement(p)
예제 #15
0
    def edge_textsize(self, edge):
        width = 0
        height = 0
        if edge.label:
            if edge.direction == 'self':
                cell = self.cell(edge.node1)
                width = self.edge(edge).right - cell.center.x
            else:
                width = (self.cell(edge.right_node).center.x -
                         self.cell(edge.left_node).center.x - self.cellsize * 4
                         )  # 4: width of activity and padding
            width, height = self.textsize(edge.label,
                                          width=width,
                                          font=self.font_for(edge))

        return XY(width, height)
예제 #16
0
    def fixiate(self, fixiate_nodes=False):
        if self.separated:
            self.colwidth = 1
            self.colheight = 1

            return
        elif len(self.nodes) > 0:
            self.colwidth = max(x.xy.x + x.colwidth for x in self.nodes)
            self.colheight = max(x.xy.y + x.colheight for x in self.nodes)

        for node in self.nodes:
            if fixiate_nodes:
                node.xy = XY(self.xy.x + node.xy.x, self.xy.y + node.xy.y)

            if isinstance(node, NodeGroup):
                node.fixiate(fixiate_nodes)
예제 #17
0
    def failedmark(self):
        lines = []
        if self.edge.failed:
            r = self.metrics.cellsize
            if self.edge.direction == 'right':
                pt = self.shaft[-1]
                lines.append((XY(pt.x + r,
                                 pt.y - r), XY(pt.x + r * 3, pt.y + r)))
                lines.append((XY(pt.x + r,
                                 pt.y + r), XY(pt.x + r * 3, pt.y - r)))
            else:
                pt = self.shaft[0]
                lines.append((XY(pt.x - r * 3,
                                 pt.y - r), XY(pt.x - r, pt.y + r)))
                lines.append((XY(pt.x - r * 3,
                                 pt.y + r), XY(pt.x - r, pt.y - r)))

        return lines
예제 #18
0
    def build(self, tree):
        self.diagram = Diagram()
        self.instantiate(None, None, tree)
        for network in self.diagram.networks:
            nodes = [n for n in self.diagram.nodes if network in n.networks]
            if len(nodes) == 0:
                self.diagram.networks.remove(network)

        for i, network in enumerate(self.diagram.networks):
            network.xy = XY(0, i)

        for subgroup in self.diagram.groups:
            if len(subgroup.nodes) == 0:
                self.diagram.groups.remove(subgroup)

        for node in self.diagram.nodes:
            if len(node.networks) == 0:
                msg = "DiagramNode %s does not belong to any networks"
                raise RuntimeError(msg % node.id)

        # show networks including same nodes
        for nw in self.diagram.networks:
            if nw.hidden and len(nw.nodes) == 2:

                def is_same(x):
                    return set(nodes) & set(x.nodes) == set(nodes)

                nodes = nw.nodes
                for n in self.diagram.networks:
                    if n != nw and is_same(n):
                        nw.hidden = False
                        break

        # show network for multiple peer networks from same node
        nodes = []
        for nw in self.diagram.networks:
            if nw.hidden and len(nw.nodes) == 2:
                nodes.append(nw.nodes[0])  # parent node (FROM node)

        for node in [n for n in set(nodes) if nodes.count(n) > 1]:
            for network in node.networks:
                if len(network.nodes) == 2:
                    network.hidden = False

        return self.diagram
예제 #19
0
    def set_node_xpos(self, depth=0):
        for node in self.diagram.nodes:
            if node.xy.x != depth:
                continue

            for child in self.get_child_nodes(node):
                if self.is_circular_ref(node, child):
                    pass
                elif node == child:
                    pass
                elif child.xy.x > node.xy.x + node.colwidth:
                    pass
                else:
                    child.xy = XY(node.xy.x + node.colwidth, 0)

        depther_node = [x for x in self.diagram.nodes if x.xy.x > depth]
        if len(depther_node) > 0:
            self.set_node_xpos(depth + 1)
예제 #20
0
def dots(box, cycle, start=0, end=360):
    # calcrate rendering pattern from cycle
    base = 0
    rendered = []
    for index in range(0, len(cycle), 2):
        i, j = cycle[index:index + 2]
        for n in range(base * 2, (base + i) * 2):
            rendered.append(n)
        base += i + j

    a = float(box.width) / 2
    b = float(box.height) / 2
    du = 1
    _max = sum(cycle) * 2
    center = box.center
    for i, coord in enumerate(_coordinates(du, a, b, start, end)):
        if i % _max in rendered:
            yield XY(center.x + coord[0], center.y + coord[1])
예제 #21
0
    def build(self, tree):
        self.diagram = Diagram()
        self.diagram = self.instantiate(self.diagram, tree)

        _min = min(n._to or n._from for n in self.diagram.nodes)
        _max = max(n._to or n._from for n in self.diagram.nodes)

        self.diagram.width = (_max - _min).days + 1
        self.diagram.height = len(self.diagram.nodes)
        for i, node in enumerate(self.diagram.nodes):
            node.xy = XY((node._from - _min).days, i)

            if node._to:
                node.width = (node._to - node._from).days + 1
            else:
                node.width = 1

        return self.diagram
예제 #22
0
    def labelbox(self):
        _dir = self.edge.direction
        if _dir == 'right':
            span = XY(self.span_width, self.span_height)
            cell1 = self.cell(self.edge.node1, use_padding=False)
            cell2 = self.cell(self.edge.node2, use_padding=False)

            if self.edge.skipped:
                box = Box(cell1.bottom.x, cell1.bottom.y,
                          cell1.bottomright.x,
                          cell1.bottomright.y + span.y // 2)
            else:
                box = Box(cell1.bottom.x, cell2.left.y - span.y // 2,
                          cell1.bottom.x, cell2.left.y)
        else:
            box = super(FlowchartLandscapeEdgeMetrics, self).labelbox

        return box
예제 #23
0
    def lineTo(self, x, y=None):
        if y is None:
            elem = x
        else:
            elem = XY(x, y)

        if self.stroking is False:
            self.stroking = True
            polyline = []
            if self.xy:
                polyline.append(self.xy)
            self.polylines.append(polyline)

        if len(self.polylines[-1]) > 0:
            if self.polylines[-1][-1] == elem:
                return

        self.polylines[-1].append(elem)
예제 #24
0
    def render_shape_outline(self, drawer, **kwargs):
        m = self.metrics.cell(self.node)
        r = self.metrics.cellsize
        box = m.box

        lines = [(XY(box[0] + r, box[1]), XY(box[2] - r, box[1])),
                 (XY(box[2], box[1] + r), XY(box[2], box[3] - r)),
                 (XY(box[0] + r, box[3]), XY(box[2] - r, box[3])),
                 (XY(box[0], box[1] + r), XY(box[0], box[3] - r))]
        for line in lines:
            drawer.line(line, fill=self.node.linecolor, style=self.node.style)

        r2 = r * 2
        arcs = [(Box(box[0], box[1], box[0] + r2, box[1] + r2), 180, 270),
                (Box(box[2] - r2, box[1], box[2], box[1] + r2), 270, 360),
                (Box(box[2] - r2, box[3] - r2, box[2], box[3]), 0, 90),
                (Box(box[0], box[3] - r2, box[0] + r2, box[3]), 90, 180)]
        for arc in arcs:
            drawer.arc(arc[0], arc[1], arc[2],
                       fill=self.node.linecolor, style=self.node.style)
예제 #25
0
    def rightnoteshape(self):
        if not self.edge.rightnote:
            return []

        r = self.metrics.cellsize
        box = self.rightnotebox
        return [
            XY(box[0], box[1]),
            XY(box[2], box[1]),
            XY(box[2] + r, box[1] + r),
            XY(box[2] + r, box[3]),
            XY(box[0], box[3]),
            XY(box[0], box[1])
        ]
예제 #26
0
파일: builder.py 프로젝트: tk0miya/nwdiag
    def run(self):
        filled = {}
        for field in self.split_field_by_column():
            x = field.number % self.diagram.colwidth
            y = field.number // self.diagram.colwidth

            if filled.get(y) is None:
                filled[y] = {}

            for rx in range(x, x + field.colwidth):
                if filled[y].get(rx):
                    msg = ("Field '%s' is conflicted to other field\n" %
                           field.label)
                    raise AttributeError(msg)
                filled[y][rx] = True

            if self.diagram.scale_direction == "right_to_left":
                x = self.diagram.colwidth - x - field.colwidth

            field.xy = XY(x, y)

        self.diagram.fixiate()
예제 #27
0
    def render_shape(self, drawer, _, **kwargs):
        fill = kwargs.get('fill')

        m = self.metrics.cell(self.node)
        xdiff = self.metrics.node_width // 4
        ydiff = self.metrics.node_height // 4

        shape = [
            XY(m.topleft.x + xdiff, m.topleft.y),
            XY(m.topright.x - xdiff, m.topleft.y),
            XY(m.topright.x, m.topright.y + ydiff),
            XY(m.topright.x, m.bottomright.y),
            XY(m.topleft.x, m.bottomleft.y),
            XY(m.topleft.x, m.topleft.y + ydiff),
            XY(m.topleft.x + xdiff, m.topleft.y)
        ]

        # draw outline
        if kwargs.get('shadow'):
            shape = self.shift_shadow(shape)
            if kwargs.get('style') == 'blur':
                drawer.polygon(shape,
                               fill=fill,
                               outline=fill,
                               filter='transp-blur')
            else:
                drawer.polygon(shape, fill=fill, outline=fill)
        elif self.node.background:
            drawer.polygon(shape,
                           fill=self.node.color,
                           outline=self.node.color)
            drawer.image(self.textbox, self.node.background)
            drawer.polygon(shape,
                           fill="none",
                           outline=self.node.linecolor,
                           style=self.node.style)
        else:
            drawer.polygon(shape,
                           fill=self.node.color,
                           outline=self.node.linecolor,
                           style=self.node.style)
예제 #28
0
    def adjust_node_widths(self):
        i = 0
        linked_widths = {}
        widths = []
        while i < self.colheight:
            levels = self.get_linked_levels(i)

            if levels:
                linked_widths[i] = []
                for level in levels:
                    nodes = self.items(level)
                    if nodes:
                        width = max(n.xy.x for n in nodes) + 1
                        widths.append(width)
                        linked_widths[i].append(width)

                i += len(levels)
            else:
                i += 1

        i = 0
        self.colwidth = lcm(*widths) or 1
        while i < self.colheight:
            levels = self.get_linked_levels(i)

            if levels:
                colwidth = max(linked_widths[i]) or 1
                for level in levels:
                    nodes = self.items(level)
                    if nodes:
                        width = self.colwidth // colwidth
                        for node in nodes:
                            node.xy = XY(node.xy.x * width, node.xy.y)
                            node.colwidth = width

                i += len(levels)
            else:
                i += 1
예제 #29
0
    def _groups(self):
        # Store nodes and edges of subgroups
        nodes = {self.diagram: self.diagram.nodes}
        edges = {self.diagram: self.diagram.edges}
        levels = {self.diagram: self.diagram.level}
        for group in self.diagram.traverse_groups():
            nodes[group] = group.nodes
            edges[group] = group.edges
            levels[group] = group.level

        groups = {}
        orders = {}
        for node in self.diagram.traverse_nodes():
            groups[node] = node.group
            orders[node] = node.order

        for group in self.diagram.traverse_groups():
            yield group

            # Restore nodes, groups and edges
            for g in nodes:
                g.nodes = nodes[g]
                g.edges = edges[g]
                g.level = levels[g]

            for n in groups:
                n.group = groups[n]
                n.order = orders[n]
                n.xy = XY(0, 0)
                n.colwidth = 1
                n.colheight = 1
                n.separated = False

            for edge in DiagramEdge.find_all():
                edge.skipped = False
                edge.crosspoints = []

        yield self.diagram
예제 #30
0
    def _shaft(self):
        if self.edge.direction == 'right-down':
            span = XY(self.span_width, self.span_height)
            node1 = self.node(self.edge.node1)
            cell1 = self.cell(self.edge.node1, use_padding=False)
            node2 = self.node(self.edge.node2)
            cell2 = self.cell(self.edge.node2, use_padding=False)

            shaft = EdgeLines()
            shaft.moveTo(node1.bottom)

            if self.edge.skipped:
                shaft.lineTo(cell1.bottom.x, cell1.bottom.y + span.y // 2)
                shaft.lineTo(cell2.left.x - span.x // 4,
                             cell1.bottom.y + span.y // 2)
                shaft.lineTo(cell2.left.x - span.x // 4, cell2.left.y)
            else:
                shaft.lineTo(cell1.bottom.x, cell2.left.y)

            shaft.lineTo(node2.left)
        else:
            shaft = super(FlowchartLandscapeEdgeMetrics, self)._shaft

        return shaft
예제 #31
0
    def head(self):
        cell = self.metrics.cellsize

        head = []
        if self.edge.direction == 'right':
            xy = self.shaft[-1]
            head.append(XY(xy.x - cell, xy.y - cell // 2))
            head.append(xy)
            head.append(XY(xy.x - cell, xy.y + cell // 2))
        elif self.edge.direction == 'left':
            xy = self.shaft[0]
            head.append(XY(xy.x + cell, xy.y - cell // 2))
            head.append(xy)
            head.append(XY(xy.x + cell, xy.y + cell // 2))
        else:  # self
            xy = self.shaft[-1]
            head.append(XY(xy.x + cell, xy.y - cell // 2))
            head.append(xy)
            head.append(XY(xy.x + cell, xy.y + cell // 2))

        return head
예제 #32
0
파일: actor.py 프로젝트: xillmera/outwiker
    def body_part(self):
        r = self.radius
        m = self.metrics.cell(self.node)

        bodyC = m.center
        neckWidth = r * 2 // 3  # neck size
        arm = r * 4  # arm length
        armWidth = r
        bodyWidth = r * 2 // 3  # half of body width
        bodyHeight = r
        legXout = r * 7 // 2  # toe outer position
        legYout = bodyHeight + r * 3
        legXin = r * 2  # toe inner position
        legYin = bodyHeight + r * 3

        return [
            XY(bodyC.x + neckWidth, bodyC.y - r * 2),
            XY(bodyC.x + neckWidth, bodyC.y - armWidth),  # neck end
            XY(bodyC.x + arm, bodyC.y - armWidth),
            XY(bodyC.x + arm, bodyC.y),  # right arm end
            XY(bodyC.x + bodyWidth, bodyC.y),  # right body end
            XY(bodyC.x + bodyWidth, bodyC.y + bodyHeight),
            XY(bodyC.x + legXout, bodyC.y + legYout),
            XY(bodyC.x + legXin, bodyC.y + legYin),
            XY(bodyC.x, bodyC.y + (bodyHeight * 2)),  # body bottom center
            XY(bodyC.x - legXin, bodyC.y + legYin),
            XY(bodyC.x - legXout, bodyC.y + legYout),
            XY(bodyC.x - bodyWidth, bodyC.y + bodyHeight),
            XY(bodyC.x - bodyWidth, bodyC.y),  # left body end
            XY(bodyC.x - arm, bodyC.y),
            XY(bodyC.x - arm, bodyC.y - armWidth),
            XY(bodyC.x - neckWidth, bodyC.y - armWidth),  # left arm end
            XY(bodyC.x - neckWidth, bodyC.y - r * 2)
        ]
예제 #33
0
 def right(self):
     pt = self.box.right
     return XY(pt.x + self.span_width // 2, pt.y)