In [13]:
import math

import brushcue

CIRCLE_DIAMETER = 1000t
DISTANCE_BETWEEN_CIRCLES = 500
FOREGROUND_RADIUS = CIRCLE_DIAMETER / 2
TRIANGLE_HEIGHT = DISTANCE_BETWEEN_CIRCLES * math.sqrt(3) / 2
VENN_CENTER = brushcue.Point2f.from_components(
    DISTANCE_BETWEEN_CIRCLES / 2,
    TRIANGLE_HEIGHT / 3,
)
BACKGROUND_RADIUS = FOREGROUND_RADIUS + DISTANCE_BETWEEN_CIRCLES / math.sqrt(3)

OUTPUT_FILE = "/Users/dito/dev/graphics-book/writing/graphics/chapters/color-formats/assets/color-venn-diagram.png"

context = brushcue.Context()

def make_circle_composition(center: brushcue.Point2f, rgba: brushcue.RGBAColor) -> brushcue.Composition:
    instances = brushcue.Transform2.to_list(brushcue.Transform2.identity())
    render_style = brushcue.RenderStyle.fill_only(
        brushcue.Fill.solid(
            brushcue.ProfiledColor.from_rgba_srgb(
                rgba
            )
        )
    )
    painter = brushcue.Painter.new()
    painter = painter.add_ellipse_with_render_style(
        center,
        brushcue.Vector2f.from_components(CIRCLE_DIAMETER, CIRCLE_DIAMETER),
        0,
        render_style,
        instances
    )
    return brushcue.Composition.painter(painter)

def make_background_circle() -> brushcue.Composition:
    instances = brushcue.Transform2.to_list(brushcue.Transform2.identity())
    render_style = brushcue.RenderStyle.fill_only(
        brushcue.Fill.solid(
            brushcue.ProfiledColor.from_rgba_srgb(
                brushcue.RGBAColor.from_components(0, 0, 0, 1)
            )
        )
    )
    painter = brushcue.Painter.new()
    diameter = BACKGROUND_RADIUS * 2
    painter = painter.add_ellipse_with_render_style(
        VENN_CENTER,
        brushcue.Vector2f.from_components(diameter, diameter),
        0,
        render_style,
        instances
    )
    return brushcue.Composition.painter(painter)

red_circle = make_circle_composition(brushcue.Point2f.from_components(0, 0), brushcue.RGBAColor.from_components(1, 0, 0, 1))
green_circle = make_circle_composition(brushcue.Point2f.from_components(DISTANCE_BETWEEN_CIRCLES, 0), brushcue.RGBAColor.from_components(0, 1, 0, 1))
blue_circle = make_circle_composition(brushcue.Point2f.from_components(DISTANCE_BETWEEN_CIRCLES / 2, TRIANGLE_HEIGHT), brushcue.RGBAColor.from_components(0, 0, 1, 1))

red_and_green = brushcue.Composition.blend_add(red_circle, green_circle, brushcue.Transform2.identity())
red_and_green_and_blue = brushcue.Composition.blend_add(red_and_green, blue_circle, brushcue.Transform2.identity())

background_circle = make_background_circle()
result = brushcue.Composition.blend_add(background_circle, red_and_green_and_blue, brushcue.Transform2.identity())

bytes = result.execute(context).to_image_bytes(context)

with open(OUTPUT_FILE, "wb") as file:
    file.write(bytes)
In [13]: