def draw_crown(ctx: cairo.Context, pos_x: float, pos_y: float, radius: float): ctx.arc(pos_x, pos_y, radius, 0, tau) ctx.stroke_preserve() ctx.clip() crown_eclipse = -0.2 eclipse_cy = pos_y + crown_eclipse * 2.0 * radius ctx.arc(pos_x, eclipse_cy, radius, 0, tau) ctx.fill() ctx.reset_clip()
def draw(self, ctx: cairo.Context, eye_radius: float, relative_to=(0, 0)): pos = self.pos - relative_to top_intersection = pos + np.array([0, self.opening / 2]) bottom_intersection = pos - np.array([0, self.opening / 2]) right_point = pos + np.array([self.size, 0]) left_point = pos - np.array([self.size, 0]) center_1, rad_1 = circle_from_3_points(left_point, top_intersection, right_point) center_2, rad_2 = circle_from_3_points(left_point, bottom_intersection, right_point) # Eyelid 1: ctx.push_group() with source(ctx, self.color.to_pattern()): # Restrict drawing area to eyeball: ctx.arc(pos[0], pos[1], eye_radius + 1, 0, math.tau) ctx.clip() ctx.paint() # Sub circle 1: with operator(ctx, cairo.Operator.CLEAR): ctx.arc(center_1[0], center_1[1], rad_1, 0, math.tau) ctx.fill() ctx.reset_clip() with source(ctx, ctx.pop_group()): ctx.paint() # Eyelid 2: ctx.push_group() with source(ctx, self.color.to_pattern()): # Restrict drawing area to eyeball: ctx.arc(pos[0], pos[1], eye_radius + 1, 0, math.tau) ctx.clip() ctx.paint() # Sub circle 2: with operator(ctx, cairo.Operator.CLEAR): ctx.arc(center_2[0], center_2[1], rad_2, 0, math.tau) ctx.fill() ctx.reset_clip() with source(ctx, ctx.pop_group()): ctx.paint()
def draw(self, ctx: cairo.Context, relative_to=(0, 0)): pos = self.pos - relative_to top_intersection = pos + np.array([0, self.size]) bottom_intersection = pos - np.array([0, self.size]) right_edge = pos + np.array([self.width / 2, 0]) left_edge = pos - np.array([self.width / 2, 0]) center_1, rad_1 = circle_from_3_points(top_intersection, right_edge, bottom_intersection) center_2, rad_2 = circle_from_3_points(top_intersection, left_edge, bottom_intersection) ctx.arc(center_1[0], center_1[1], rad_1, 0, math.tau) ctx.clip() ctx.arc(center_2[0], center_2[1], rad_2, 0, math.tau) ctx.clip() ctx.paint() ctx.reset_clip()
def draw_star_band( ctx: cairo.Context, rng: Generator, pos_x: float, pos_y: float, radius_outer: float, radius_inner: float, ): band_center = (radius_outer + radius_inner) / 2 star_size = 0.2 * (radius_outer - radius_inner) n_stars = rng.integers(20, 50) ctx.arc(pos_x, pos_y, radius_outer, 0, tau) ctx.arc_negative(pos_x, pos_y, radius_inner, 0, -tau) ctx.stroke_preserve() ctx.clip_preserve() grad_offset_x = rng.uniform(radius_inner / 3.0, radius_inner) grad_offset_y = rng.uniform(radius_inner / 3.0, radius_inner) grad = PointLinearGradient( [Color(0, 0, 0), Color(1, 1, 1, 0.0)], Pattern.PACKED) grad.fill( ctx, rng, pos_x - grad_offset_x, pos_y - grad_offset_y, pos_x + grad_offset_x, pos_y + grad_offset_y, ) for x, y in jitter_points( points_along_arc(pos_x, pos_y, band_center, 0, tau, n_stars), rng, star_size): draw_star(ctx, rng, x, y, star_size) ctx.reset_clip()
def draw_moon( ctx: cairo.Context, pos_x: float, pos_y: float, radius: float, eclipse_pct: float = -1.0, ): moon_color = Color(0.9, 0.9, 0.9) ctx.arc(pos_x, pos_y, radius, 0, tau) ctx.stroke_preserve() with source( ctx, moon_color.to_pattern(), ): ctx.fill_preserve() ctx.clip() with source(ctx, Color(0.0, 0.0, 0.0).to_pattern()): eclipse_cx = pos_x + eclipse_pct * 2.0 * radius ctx.arc(eclipse_cx, pos_y, radius, 0, tau) ctx.fill() ctx.reset_clip()