def draw(self, draw: ImageDraw): if not self.show: return horizontal_pad = self.width // 25 bottom_pad = self.height // 4 draw.line((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad, self.abs_col + self.width - horizontal_pad, self.abs_row + self.height - bottom_pad), fill=self.foreground) text_w, text_h = self.font.getsize(' ') polygon_pts = ((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad), (self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), (self.abs_col + horizontal_pad + text_w * 8, self.abs_row + self.height - bottom_pad - text_h), (self.abs_col + horizontal_pad + text_w * 9, self.abs_row + self.height - bottom_pad)) date_str = datetime.datetime.strftime(self.date, ' %b %d') draw.polygon(polygon_pts, fill=self.foreground) draw.text((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), date_str, fill=self.background, font=self.font) event_max_chars = (self.width - 2 * horizontal_pad) * 4 // 5 // text_w if len(self.event) > event_max_chars: self.event = self.event[:event_max_chars - 3] + '...' draw.text( (self.abs_col + (self.width - 2 * horizontal_pad) // 5 + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), self.event, fill=self.foreground, font=self.font)
def draw(self, image: ImageDraw, x_shift: int = 0, y_shift: int = 0): self.x_shift += x_shift self.y_shift += y_shift for child in self.children: image.line( ( self.x * X_UNIT, self.y * Y_UNIT, child.x * X_UNIT + self.x_shift * X_UNIT, child.y * Y_UNIT + self.y_shift * Y_UNIT, ), fill='black', width=LINE_WIDTH, ) child.draw(image, self.x_shift, self.y_shift) image.ellipse( ( self.x * X_UNIT - DOT_SIZE / 2, self.y * Y_UNIT - DOT_SIZE / 2, self.x * X_UNIT + DOT_SIZE / 2, self.y * Y_UNIT + DOT_SIZE / 2, ), fill='white', outline='black', width=LINE_WIDTH, )
def draw_box( draw: ImageDraw, box: Tuple[float, float, float, float], img_width: int, img_height: int, text: str = "", color: Tuple[int, int, int] = (255, 255, 0), ) -> None: """ Draw a bounding box on and image. The bounding box is defined by the tuple (y_min, x_min, y_max, x_max) where the coordinates are floats in the range [0.0, 1.0] and relative to the width and height of the image. For example, if an image is 100 x 200 pixels (height x width) and the bounding box is `(0.1, 0.2, 0.5, 0.9)`, the upper-left and bottom-right coordinates of the bounding box will be `(40, 10)` to `(180, 50)` (in (x,y) coordinates). """ line_width = 5 y_min, x_min, y_max, x_max = box (left, right, top, bottom) = ( x_min * img_width, x_max * img_width, y_min * img_height, y_max * img_height, ) draw.line( [(left, top), (left, bottom), (right, bottom), (right, top), (left, top)], width=line_width, fill=color, ) if text: draw.text((left + line_width, abs(top - line_width)), text, fill=color)
def draw(self, image_draw: ImageDraw): image_draw.line((self._coordinates.x - self._diameter, self._coordinates.y - self._diameter, self._coordinates.x + self._diameter, self._coordinates.y + self._diameter), fill=self._color, width=self._linewidth) image_draw.line((self._coordinates.x + self._diameter, self._coordinates.y - self._diameter, self._coordinates.x - self._diameter, self._coordinates.y + self._diameter), fill=self._color, width=self._linewidth)
def set_noise(self, __image: ImageDraw, img_width, img_height): for i in range(self.max_line_count): # 噪线的起点横坐标和纵坐标 x1 = random.randint(0, img_width) y1 = random.randint(0, img_height) # 噪线的终点横坐标和纵坐标 x2 = random.randint(0, img_width) y2 = random.randint(0, img_height) # 通过画笔对象draw.line((起点的xy, 终点的xy), fill='颜色')来划线 __image.line((x1, y1, x2, y2), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))) for i in range(self.max_point_count): __image.point( [random.randint(0, img_width), random.randint(0, img_height)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))) x = random.randint(0, img_width) y = random.randint(0, img_height) __image.arc((x, y, x + 4, y + 4), 0, 40, fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
def get_code(request): mode = 'RGB' size = (200, 100) image = Image.new(mode=mode, size=size, color=rand_color()) image_draw = ImageDraw(image, mode=mode) font = ImageFont.truetype(code_font, 80) text = rand_wd().lower() request.session['verify_code'] = text for i in range(4): image_draw.text((45 * i + randrange(20), randrange(30)), text[i], fill=rand_color(), font=font) for i in range(6000): image_draw.point((randrange(201), randrange(101)), rand_color()) for i in range(randrange(3)): xy = ((randrange(201), randrange(101)), (randrange(201), randrange(101))) image_draw.line(xy, fill=rand_color(), width=2) fp = BytesIO() image.save(fp, 'png') return HttpResponse(fp.getvalue(), content_type='image/png')
def _draw_footer(self, draw: ImageDraw) -> None: y = self._display.height - self._display.character_height * 2 - 1 draw.line([(0, y), (self._display.width, y)], fill=(255, 255, 255), width=1) y += 1 for l in self._multiline_split(self._selections[self._selected].description, 2): draw.text((1, y), l, fill=(255, 255, 255)) y += self._display.character_height
def draw_bar(self, position: int, value: int, draw: ImageDraw, color: (int, int, int)) -> None: """ Draws a color bar of the correct height on the image at the position. Args: position (int): the index of the bar. value (int): the new bar value. draw (ImageDraw): the drawing object. color (int, int, int, int): RGB color code. Modifies: draw: a bar is drawn onto the image associated with the drawing object. Raises: InputError: number of values is too large for the image size. Returns: None. """ if position < 0 or position > (self.num_bars - 1): raise InputError((position), "invalid bar position") if value < 0 or value > (self.image_height - 2*self.border_size): raise InputError((value), "invalid bar value") # drawing range divided by number of bars + white space between them if self.bar_width < 1: raise InputError(self.bar_width, "bar_width cannot be less than 1") # calculate starting offset to ensure graph is centered within the border x_start = self.border_size + math.ceil(self.padding/2) + self.bar_width//2 x_offset = x_start + (2*self.bar_width)*position y_offset = self.image_height - self.border_size if value != 0: draw.line ([(x_offset, y_offset),(x_offset, y_offset - value)], fill=color, width=self.bar_width)
def draw(self, draw: ImageDraw): nub_length = 0.25 # top if self.pt == top_pt: xy0 = top_pt xy1 = (top_pt[0], top_pt[1] + nub_length) # right elif self.pt == right_pt: xy0 = right_pt xy1 = (right_pt[0] - nub_length, right_pt[1]) # bot elif self.pt == bot_pt: xy0 = bot_pt xy1 = (bot_pt[0], bot_pt[1] - nub_length) # left elif self.pt == left_pt: xy0 = left_pt xy1 = (left_pt[0] + nub_length, left_pt[1]) else: raise Exception xy0_px = tuple_multiply(xy0, self.canvas_px) xy1_px = tuple_multiply(xy1, self.canvas_px) draw.line((xy0_px, xy1_px), self.color.value, width=int(self.canvas_px * LINE_WIDTH_PCT), joint="curve") return
def draw(self, draw: ImageDraw): xy1 = (0.5, 0.5) # middle for pt in self.points: # top if pt == top_pt: xy0 = top_pt # right elif pt == right_pt: xy0 = right_pt # bot elif pt == bot_pt: xy0 = bot_pt # left elif pt == left_pt: xy0 = left_pt else: raise Exception(f'pt is {pt.__str__}, type {type(pt)}') xy0_px = tuple_multiply(xy0, self.canvas_px) xy1_px = tuple_multiply(xy1, self.canvas_px) draw.line((xy0_px, xy1_px), self.color.value, width=int(self.canvas_px * LINE_WIDTH_PCT), joint="curve") return
def __visualize_limb(draw: ImageDraw, limb: Limb2D, limb_color: Color, line_width: int = 4): draw.line((int(limb.joint_from.x), int( limb.joint_from.y), int(limb.joint_to.x), int(limb.joint_to.y)), fill=limb_color.tuple_rgb, width=line_width)
def render_candlestick(ohlc: Tuple[float, ...], x: int, y_transformer: Callable[[float], int], draw: ImageDraw): color = (255, 55, 55, 255) if ohlc[3] < ohlc[0] else (55, 255, 55, 255) draw.rectangle((x, y_transformer(max( ohlc[0], ohlc[3])), x + 2, y_transformer(min(ohlc[0], ohlc[3]))), fill=color) draw.line((x + 1, y_transformer(ohlc[1]), x + 1, y_transformer(ohlc[2])), fill=color)
def draw_line(image: Image, draw: ImageDraw, pstart: world.Point, pend: world.Point, grid_size: int, style: int): step_size = int(image.width / grid_size) x0 = step_size * pstart.x + int(step_size / 2) y0 = step_size * pstart.y + int(step_size / 2) x1 = step_size * pend.x + int(step_size / 2) y1 = step_size * pend.y + int(step_size / 2) draw.line(((x0, y0), (x1, y1)), fill='orange', width=2)
def draw_func(draw: ImageDraw): s = path.path[0].to_img(image.dimensions) for point in path.path[1:]: e = point.to_img(image.dimensions) draw.line([s.x * scale, s.y * scale, e.x * scale, e.y * scale], width=int(scale), fill=color) s = e
def render_candlestick(ohlc: Tuple[float, ...], x: int, y_transformer: Callable[[float], int], draw: ImageDraw): #empty rectangle to represent negative candle sticks fill_rectangle = 0 if ohlc[3] < ohlc[0] else 1 draw.line((x + 1, y_transformer(ohlc[1]), x + 1, y_transformer(ohlc[2])), fill=1) draw.rectangle((x, y_transformer(max( ohlc[0], ohlc[3])), x + 2, y_transformer(min(ohlc[0], ohlc[3]))), fill=fill_rectangle, outline=1)
def drawlines(ImageDraw): for i in range(0, 6): for k in range(0, 3): ImageDraw.line( (i * iw + 25, ih * k - 35 + 25, i * iw + 25, ih * k + 35 + 25), fill="#707070", width=3) ImageDraw.line( (i * iw - 35 + 25, k * ih + 25, i * iw + 35 + 25, k * ih + 25), fill="#707070", width=3)
def draw_func(draw: ImageDraw): for current_path in path.path: if len(current_path) > 1: s = current_path[0].to_img(image.dimensions) for point in current_path[1:]: e = point.to_img(image.dimensions) draw.line([ s.x * scale, s.y * scale, e.x * scale, e.y * scale ], width=int(scale * path_width), fill=color) s = e
def draw(self, image_draw: ImageDraw): image_draw.line( (self._coordinates.x - self._diameter, self._coordinates.y - self._diameter, self._coordinates.x + self._diameter, self._coordinates.y + self._diameter), fill=self._color, width=self._linewidth) image_draw.line( (self._coordinates.x + self._diameter, self._coordinates.y - self._diameter, self._coordinates.x - self._diameter, self._coordinates.y + self._diameter), fill=self._color, width=self._linewidth)
def stroke_poly(img: Image, draw: ImageDraw, points, color: Tuple[int, ...], width: int): draw.line(points, fill=color, width=width) for point in points: draw.ellipse( ( point[0] - (int(width / 2) - 1), point[1] - (int(width / 2) - 1), point[0] + (int(width / 2) - 1), point[1] + (int(width / 2) - 1) ), fill=color ) return draw, img
def render_layer(self, dungeon: Dungeon, paintableRooms: Dict[DungeonRoom, PaintableRoom], img: Image, draw: ImageDraw) -> None: """See RenderLayer for docs.""" path = [] for room in dungeon.mainPath: path.append(paintableRooms[room].center) draw.line(path, fill=self.pathColor, width=3) self.draw_starting_triangle(dungeon.rooms[0], dungeon, paintableRooms, draw) self.draw_ending_square(dungeon.rooms[-1], paintableRooms, draw) for sidePath in dungeon.mainPath.sidePaths: self.draw_side_path(sidePath, paintableRooms, draw)
def generate_captcha(request): path = '.' im = Image.new('RGBA', (200, 50), (0, 0, 0, 0)) draw = ImageDraw(im) number = '' margin_left, margin_top = 0, 0 colnum = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') i = 0 while i < 6: font_color = '#' + str(random.randint(0, 9)) y = 0 while y < 5: rand = random.choice(colnum) font_color = font_color + rand y += 1 rand_x11 = random.randint(0, 100) rand_x12 = random.randint(100, 200) rand_y11 = random.randint(0, 50) rand_y12 = random.randint(0, 50) draw.line((rand_x11, rand_y11, rand_x12, rand_y12), fill='#a9a6a6') font_rand = str(random.randint(1, 10)) font_size_rand = random.randint(30, 40) font = ImageFont.truetype(path + "fonts/" + font_rand + ".ttf", font_size_rand) a = str(random.randint(0, 9)) draw.text((margin_left, margin_top), a, fill=str(font_color), font=font) rand_x11 = random.randint(0, 100) rand_x12 = random.randint(100, 200) rand_y11 = random.randint(0, 50) rand_y12 = random.randint(0, 50) draw.line((rand_x11, rand_y11, rand_x12, rand_y12), fill="#a9a6a6") margin_left = margin_left + random.randint(20, 35) margin_top = random.randint(0, 20) i += 1 number += a salt = "$@!SAf*$@)ASFfacnq==124-2542SFDQ!@$1512czvaRV" key = md5(str(number + salt)).hexdigest() output = StringIO() im.save(output, format="PNG") contents = output.getvalue().encode("base64").replace("\n", "") img_tag = '<img value="' + key + '" src="data:image/png;base64,{0}">'.format( contents) output.close() return img_tag
def drawnetwork(sol): # 建立image对象 img = Image.new('RGB', (400, 400), (255, 255, 255)) draw = ImageDraw(img) # 建立标示位置信息的字典 pos = dict([people[i], (sol[i * 2], sol[i * 2 + 1]) for i in range(0, len(people))]) # 绘制连线 for (a, b) in links: draw.line((pos[a], pos[b]), fill = (255, 0, 0)) # 绘制代表人的节点 for n, p in pos.items(): draw.text(p, n (0, 0, 0)) img.show()
def draw_cross(draw: ImageDraw, center: complex, size: complex = 25 + 25j, angle: float = 0, color: str = "#FF0000"): pnt1 = (size.imag * 0.5 * 1j) * exp(1j * angle) + center pnt2 = -(size.imag * 0.5 * 1j) * exp(1j * angle) + center draw.line([pnt1.real, pnt1.imag, pnt2.real, pnt2.imag], fill=color, width=1) pnt1 = (size.real * 0.5) * exp(1j * angle) + center pnt2 = -(size.real * 0.5) * exp(1j * angle) + center draw.line([pnt1.real, pnt1.imag, pnt2.real, pnt2.imag], fill=color, width=1)
def draw(self, draw: ImageDraw) -> None: super().draw(draw) if not self.show: return horizontal_pad = self.width // 25 bottom_pad = self.height // 4 draw.line((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad, self.abs_col + self.width - horizontal_pad, self.abs_row + self.height - bottom_pad), fill=self.foreground) text_w, text_h = self.font.getsize(' ') # How many character's size the tab will take tab_width_char = 14 polygon_pts = ((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad), (self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), (self.abs_col + horizontal_pad + text_w * (tab_width_char - 1), self.abs_row + self.height - bottom_pad - text_h), (self.abs_col + horizontal_pad + text_w * tab_width_char, self.abs_row + self.height - bottom_pad)) week_day_str = WEEK_DAYS[self.date.weekday()] date_str = '%s, %s' % (datetime.datetime.strftime( self.date, ' %b %d'), week_day_str) draw.polygon(polygon_pts, fill=self.foreground) draw.text((self.abs_col + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), date_str, fill=self.background, font=self.font) # We save three char's space between tab and event text event_max_chars = ((self.width - 2 * horizontal_pad) // text_w - tab_width_char - 3) if len(self.event) > event_max_chars: self.event = self.event[:event_max_chars - 3] + '...' draw.text( (self.abs_col + text_w * (tab_width_char + 3) + horizontal_pad, self.abs_row + self.height - bottom_pad - text_h), self.event, fill=self.foreground, font=self.font)
def generate_captcha(request): path = '.' im = Image.new('RGBA', (200, 50), (0, 0, 0, 0)) draw = ImageDraw(im) number = '' margin_left, margin_top = 0, 0 colnum = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') i = 0 while i < 6: font_color = '#' + str(random.randint(0,9)) y = 0 while y < 5: rand = random.choice(colnum) font_color = font_color + rand y += 1 rand_x11 = random.randint(0, 100) rand_x12 = random.randint(100, 200) rand_y11 = random.randint(0, 50) rand_y12 = random.randint(0, 50) draw.line((rand_x11, rand_y11, rand_x12, rand_y12), fill='#a9a6a6') font_rand = str(random.randint(1, 10)) font_size_rand = random.randint(30, 40) font = ImageFont.truetype(path + "fonts/" + font_rand + ".ttf", font_size_rand) a = str(random.randint(0, 9)) draw.text((margin_left, margin_top), a, fill=str(font_color), font=font) rand_x11 = random.randint(0, 100) rand_x12 = random.randint(100, 200) rand_y11 = random.randint(0, 50) rand_y12 = random.randint(0, 50) draw.line((rand_x11, rand_y11, rand_x12, rand_y12), fill="#a9a6a6") margin_left = margin_left + random.randint(20, 35) margin_top = random.randint(0, 20) i += 1 number += a salt = "$@!SAf*$@)ASFfacnq==124-2542SFDQ!@$1512czvaRV" key = md5(str(number + salt)).hexdigest() output = StringIO() im.save(output, format="PNG") contents = output.getvalue().encode("base64").replace("\n", "") img_tag = '<img value="' + key + '" src="data:image/png;base64,{0}">'.format(contents) output.close() return img_tag
def draw_func(draw: ImageDraw): if vacuum_pos.a is None: vacuum_pos.a = 0 point = vacuum_pos.to_img(image.dimensions) r_scaled = r / 16 # main outline coords = [point.x - r, point.y - r, point.x + r, point.y + r] draw.ellipse(coords, outline=outline, fill=fill) if r >= 8: # secondary outline r2 = r_scaled * 14 x = point.x y = point.y coords = [x - r2, y - r2, x + r2, y + r2] draw.ellipse(coords, outline=outline, fill=None) # bin cover a1 = (vacuum_pos.a + 104) / 180 * math.pi a2 = (vacuum_pos.a - 104) / 180 * math.pi r2 = r_scaled * 13 x1 = point.x - r2 * math.cos(a1) y1 = point.y + r2 * math.sin(a1) x2 = point.x - r2 * math.cos(a2) y2 = point.y + r2 * math.sin(a2) draw.line([x1, y1, x2, y2], width=1, fill=outline) # lidar angle = vacuum_pos.a / 180 * math.pi r2 = r_scaled * 3 x = point.x + r2 * math.cos(angle) y = point.y - r2 * math.sin(angle) r2 = r_scaled * 4 coords = [x - r2, y - r2, x + r2, y + r2] draw.ellipse(coords, outline=outline, fill=fill) # button half_color = ((outline[0] + fill[0]) // 2, (outline[1] + fill[1]) // 2, (outline[2] + fill[2]) // 2) r2 = r_scaled * 10 x = point.x + r2 * math.cos(angle) y = point.y - r2 * math.sin(angle) r2 = r_scaled * 2 coords = [x - r2, y - r2, x + r2, y + r2] draw.ellipse(coords, outline=half_color, fill=half_color)
def draw(self, draw: ImageDraw): # top bot if self.pta == top_pt and self.ptb == bot_pt or self.pta == bot_pt and self.ptb == top_pt: xy0 = top_pt xy1 = bot_pt # left right elif self.pta == left_pt and self.ptb == right_pt or self.pta == right_pt and self.ptb == left_pt: xy0 = left_pt xy1 = right_pt else: raise Exception xy0_px = tuple_multiply(xy0, self.canvas_px) xy1_px = tuple_multiply(xy1, self.canvas_px) draw.line((xy0_px, xy1_px), self.color.value, width=int(self.canvas_px * LINE_WIDTH_PCT)) return
def drawnode(draw: ImageDraw, tree: decisionnode, x: int, y: int) -> None: if tree.results == None: # calculate width w1 = getwidth(tree.fb) * 100 w2 = getwidth(tree.tb) * 100 # calculate space left = x - (w1 + w2) / 2 right = x + (w1 + w2) / 2 # lable with condition draw.text((x - 20, y - 10), str(tree.col) + ':' + str(tree.value), (0, 0, 0)) # draw lines draw.line((x, y, left + w1 / 2, y + 100), fill=(255, 0, 0)) draw.line((x, y, right - w2 / 2, y + 100), fill=(255, 0, 0)) # draw nodes drawnode(draw, tree.fb, left + w1 / 2, y + 100) drawnode(draw, tree.tb, right - w2 / 2, y + 100) else: txt = ' \n'.join(['%s:%d' % v for v in tree.results.items()]) draw.text((x - 20, y), txt, (0, 0, 0)) return None
def display_shapefile(name, iwidth=500, iheight=500): import shapefile from PIL import Image, ImageDraw r = shapefile.Reader(name) mleft, mbottom, mright, mtop = r.bbox # map units mwidth = mright - mleft mheight = mtop - mbottom # scale map units to image units hscale = iwidth / mwidth vscale = iheight / mheight img = Image.new("RGB", (iwidth, iheight), "white") draw = ImageDraw(img) for shape in r.shapes(): pixels = [(int(iwidth - ((mright - x) * hscale)), int((mtop - y) * vscale)) for x, y, in shape.points] if shape.shapeType == shapefile.POLYGON: draw.polygon(pixels, outline='black') elif shape.shapeType == shapefile.POLYLINE: draw.line(pixels, fill='black') img.show()
def draw_dotted_line(draw: ImageDraw, start: Tuple[float, float], end: Tuple[float, float], length: int, color: Tuple[int, int, int], width: int) -> None: """ Draws a dotted line between two points. Parameters ---------- draw: ImageDraw The drawing handler to use. start: Tuple[int, int] The first end point of the line. end: Tuple[int, int] The second end point of the line. length: int The length, in pixels, of each dashed line segment along the line. This is also used as the number of pixels between dashes. color: Tuple[int, int, int] The color to render the line segments with. width: int The width of the line in pixels. """ delta = end[0] - start[0], end[1] - start[1] distance = sqrt(delta[0] ** 2 + delta[1] ** 2) steps = floor(distance / length / 2 + 0.5) vel = (delta[0] / steps / 2, delta[1] / steps / 2) pos = start for i in range(steps): p1 = pos[0] + vel[0], pos[1] + vel[1] p2 = p1[0] + vel[0], p1[1] + vel[1] draw.line([p1, p2], fill=color, width=width) pos = p2
def draw_line_triangle(canvas: ImageDraw, vertices: FlatTriangle, weights: list[int], master: int) -> None: """Draw a flat triangle with (individual) lines inside it.""" weights_0 = [max(weight, 0) for weight in weights] sum_weights_0 = sum(weights_0) correction = min(min(sum_weights_0 - 2 * e for e in weights_0), 0) dual_weights = [ bigger.half(sum_weights_0 - 2 * e + correction) for e in weights_0 ] parallel_weights = [max(-weight, 0) for weight in weights] for i in range(3): # Dual arcs: if dual_weights[i] > 0: s_a = 1 - 2 * VERTEX_BUFFER s_b = 1 - 2 * VERTEX_BUFFER for j in range(dual_weights[i]): scale_a = 0.5 if weights_0[i - 2] == 1 else ( 1 - s_a) / 2 + s_a * j / (weights_0[i - 2] - 1) scale_b = 0.5 if weights_0[i - 1] == 1 else ( 1 - s_b) / 2 + s_b * j / (weights_0[i - 1] - 1) S1 = interpolate(vertices[i - 2], vertices[i - 1], scale_a) E1 = interpolate(vertices[i - 0], vertices[i - 1], scale_b) canvas.line([S1, E1], fill=LAMINATION_COLOUR, width=2) elif dual_weights[i] < 0: # Terminal arc. s_0 = 1 - 2 * VERTEX_BUFFER for j in range(-dual_weights[i]): scale_a = 0.5 if weights_0[i] == 1 else ( 1 - s_0) / 2 + s_0 * dual_weights[i - 1] / ( weights_0[i] - 1) + s_0 * j / (weights_0[i] - 1) S1 = interpolate(vertices[i - 0], vertices[i - 2], scale_a) E1 = vertices[i - 1] canvas.line([S1, E1], fill=LAMINATION_COLOUR, width=2) else: # dual_weights[i] == 0: # Nothing to draw. pass # Parallel arcs: if parallel_weights[i]: S, O, E = vertices[i - 2], vertices[i - 1], vertices[i] SS = interpolate(O, S, VERTEX_BUFFER) EE = interpolate(O, E, VERTEX_BUFFER) M = interpolate(S, E) MM = interpolate(SS, EE) for j in range(parallel_weights[i] // 2): s = float(j + 1) / master P = interpolate(MM, M, s) canvas.line([S, P, E], fill=LAMINATION_COLOUR, width=2) if parallel_weights[i] % 2 == 1: canvas.line([S, E], fill=LAMINATION_COLOUR, width=2)
def draw(self, draw: ImageDraw): pen, brush = self._get_pen_brush() if hasattr(self, 'de') and self.de > 0: brush_s1 = aggdraw.Brush(fade_color(self.fill, self.shade)) brush_s2 = aggdraw.Brush(fade_color(self.fill, 2 * self.shade)) draw.line([ self.x1 + self.de, self.y1 - self.de, self.x1 + self.de, self.y2 - self.de ], pen) draw.line([self.x1 + self.de, self.y2 - self.de, self.x1, self.y2], pen) draw.line([ self.x1 + self.de, self.y2 - self.de, self.x2 + self.de, self.y2 - self.de ], pen) draw.polygon([ self.x1, self.y1, self.x1 + self.de, self.y1 - self.de, self.x2 + self.de, self.y1 - self.de, self.x2, self.y1 ], pen, brush_s1) draw.polygon([ self.x2 + self.de, self.y1 - self.de, self.x2, self.y1, self.x2, self.y2, self.x2 + self.de, self.y2 - self.de ], pen, brush_s2) draw.rectangle([self.x1, self.y1, self.x2, self.y2], pen, brush)