def draw(self, offset): """Fundamental draw method. """ # The big rectangle. l = 0.5 * self.LENGTH w = 0.5 * self.WIDTH Rectangle(self.CENTER, self.LENGTH, self.WIDTH).draw(offset) # The two center lines. plt.hlines(0, -l, l) plt.vlines(0, -w, w) # Small centering holes. r = 1.5 Hole(self.CENTER.vmove(w), r).draw(offset) Hole(self.CENTER.vmove(-w), r).draw(offset) Hole(self.CENTER.hmove(l), r).draw(offset) Hole(self.CENTER.hmove(-l), r).draw(offset) # Bigger centering holes. r = 3. Hole(self.CENTER.vmove(w - self.BORDER), r).draw(offset) Hole(self.CENTER.vmove(-w + self.BORDER), r).draw(offset) Hole(self.CENTER.hmove(l - self.BORDER), r).draw(offset) Hole(self.CENTER.hmove(-l + self.BORDER), r).draw(offset) # And, finally, the branding :-) x = -l + self.BORDER + offset.x y = w - 2. * self.BORDER + offset.y plt.text(x, y, GITHUB_URL)
def dim(p1, p2, offset, padding: float = 2., distance: float = 15., margin: float = 5.): """ """ p1 += offset p2 += offset fmt = dict(offset=Point(0., 0.), color='lightgray') # Basic setup. line = Line(p1, p2) phi = line.slope() - 90. length = line.length() d = distance + margin # Draw the two lines from the original points defining the dimension. Line(p1.move(padding, phi), p1.move(d, phi)).draw(**fmt) Line(p2.move(padding, phi), p2.move(d, phi)).draw(**fmt) # Now the actual dimension. _p1 = p1.move(distance, phi) _p2 = p2.move(distance, phi) l = Line(_p1, _p2) m = l.midpoint() text = '{:.2f}'.format(length) rot = phi + 90. if rot < -90.: rot += 180. elif rot > 90: rot -= 180 print(rot) plt.text(*m.xy(), text, rotation=rot, ha='center', va='center') _d = 1.2 * len(text) Arrow(m.move(_d, phi - 90.), _p1).draw(**fmt) Arrow(m.move(_d, phi + 90.), _p2).draw(**fmt)
def draw(self, offset, ha: str = 'left', va: str = 'bottom', **kwargs): """Draw method. """ kwargs.setdefault('color', 'black') kwargs.setdefault('markersize', 4.) x = self.x + offset.x y = self.y + offset.y plt.plot(x, y, 'o', **kwargs) if self.name is not None: kwargs.pop('markersize') plt.text(x, y, ' {}'.format(self.name), ha=ha, va=va, **kwargs)
def draw_parameters(self, offset, line_spacing=6.): """ """ y = 0. params = asdict(self) keys = list(params.keys()) keys.reverse() for key in keys: value = params[key] key = key.replace('_', ' ') plt.text(offset.x, offset.y - y, f'{key} = {value} mm') y -= line_spacing
def vruler(x, ymin, ymax, step=10., line_width=0.15): """ """ fmt = dict(lw=mm_to_points(line_width)) plt.vlines(x, ymin, ymax, **fmt) y = np.arange(ymin, ymax + 0.5 * step, step) plt.hlines(y, x, x + 2., **fmt) fmt = dict(size='small', ha='left', va='center') for _y in y: text = '{:.0f}'.format(_y) if text == '0': text += ' mm' plt.text(x + 3, _y, text, **fmt)
def hruler(y, xmin, xmax, step=10., line_width=0.15): """ """ fmt = dict(lw=mm_to_points(line_width)) plt.hlines(y, xmin, xmax, **fmt) x = np.arange(xmin, xmax + 0.5 * step, step) plt.vlines(x, y, y - 2., **fmt) fmt = dict(size='small', ha='center', va='top') for _x in x: text = '{:.0f}'.format(_x) if text == '0': text += ' mm' plt.text(_x, y - 3., text, **fmt)
def write_logo(width=450., height=350, dpi=100, text_size=3., line_width=2.5, margin=-0.01): """Create the logo for the package. """ body = MusicManAxis() offset = Point(-200., 0.) width, height, dpi = setup_page((width, height), dpi, text_size, line_width) plt.figure('metalute logo') plt.gca().set_aspect('equal') hmargin = margin vmargin = hmargin * width / height plt.subplots_adjust(left=hmargin, right=1. - hmargin, top=1. - vmargin, bottom=vmargin) plt.xticks([]) plt.yticks([]) w = 0.5 * width * (1. - 2. * hmargin) h = 0.5 * height * (1. - 2. * vmargin) plt.gca().axis([-w, w, -h, h]) body.draw(offset) kwargs = dict(ha='center', va='center', family='DejaVu Sans Mono') plt.text(-75., 40., 'M', **kwargs, size=450) plt.text(20., 18., 'eta', **kwargs, size=150, color='orange') plt.text(-51., -50., 'L', **kwargs, size=450) plt.text(-8., -55., 'ute', **kwargs, size=150, color='orange') plt.tight_layout(pad=-1.) file_path = os.path.join(METALUTE_DOCS, '_static', 'metalute_logo.png') plt.savefig(file_path)
def blueprint(name: str, size: str, author=None, orientation: str = 'Landscape', dpi: float = 100., text_size: float = 3., line_width: float = 0.25, margin: float = 0.05, pitch: float = 50., tick_size: float = 7.5): """Create a custom figure for techical drawings. """ assert orientation in PAPER_ORIENTATIONS width, height = PAPER_SIZE_DICT[size] if orientation == 'Landscape': width, height = height, width # Setup the page. width, height, dpi = setup_page((width, height), dpi, text_size, line_width) # Create an empty figure. plt.figure(name) # Setup the axes. plt.gca().set_aspect('equal') hmargin = margin vmargin = hmargin * width / height plt.subplots_adjust(left=hmargin, right=1. - hmargin, top=1. - vmargin, bottom=vmargin) plt.xticks([]) plt.yticks([]) w = 0.5 * width * (1. - 2. * hmargin) h = 0.5 * height * (1. - 2. * vmargin) plt.gca().axis([-w, w, -h, h]) # Add the reference grid on the borders. nx = int(width / pitch + 0.5) ny = int(height / pitch + 0.5) x = np.linspace(-w, w, nx + 1) y = np.linspace(-h, h, ny + 1) plt.hlines(y, -w, -w - tick_size, clip_on=False) plt.hlines(y, w, w + tick_size, clip_on=False) plt.vlines(x, -h, -h - tick_size, clip_on=False) plt.vlines(x, h, h + tick_size, clip_on=False) # Add the letters and numbers to the reference grid. dx = w / nx dy = h / ny fmt = dict(size='large', ha='center', va='center') for i, _x in enumerate(np.flip((x + dx)[:-1])): plt.text(_x, -h - tick_size, '{}'.format(i + 1), **fmt) plt.text(_x, h + tick_size, '{}'.format(i + 1), rotation=90., **fmt) for i, _y in enumerate((y + dy)[:-1]): plt.text(-w - tick_size, _y, '{}'.format(ascii_uppercase[i]), **fmt) plt.text(w + tick_size, _y, '{}'.format(ascii_uppercase[i]), rotation=90., **fmt) # Add the reference rulers. delta = 5. span = 0.75 l = 10 * int((span * w) / 10.) hruler(h - delta, -l, l) l = 10 * int((span * h) / 10.) vruler(-w + delta, -l, l) box = BlueprintBox(name, author)