def a_gear(radius, spec):
    mark_length = radius * 0.3
    circle_radius = radius - mark_length
    gear_group_svg, _, _ = a_circle(radius=circle_radius, spec=spec)

    # the inner circle
    inner_circle_radius = radius * 0.1
    inner_circle_svg = Circle(cx=circle_radius,
                              cy=circle_radius,
                              r=inner_circle_radius)
    inner_circle_svg.set_style(StyleBuilder(spec['style']).getStyle())
    gear_group_svg.addElement(inner_circle_svg)

    # the hour marks
    center_point = Point(circle_radius, circle_radius)
    for mark in range(0, 9):
        point_on_circle = center_point.to_point(40 * mark, circle_radius)
        point_outside = center_point.to_point(40 * mark,
                                              circle_radius + mark_length)
        mark_svg = Line(x1=point_on_circle.x,
                        y1=point_on_circle.y,
                        x2=point_outside.x,
                        y2=point_outside.y)
        mark_svg.set_style(StyleBuilder(spec['style']).getStyle())
        gear_group_svg.addElement(mark_svg)

    # add to group
    return gear_group_svg, radius * 2, radius * 2
def a_lightning(width, height, spec):
    diagonal = math.sqrt(width * width + height * height)
    len_mb_mt = (diagonal / 2) * 0.3
    len_mt_tl = (diagonal / 2) * 0.4
    angle_bl_tr = math.atan(height / width)
    angle_mt_tl = math.pi / 2

    bottom_left = Point(0, height)
    mid_top = bottom_left.to_point(math.degrees(angle_bl_tr),
                                   diagonal / 2 + len_mb_mt / 2)
    mid_bottom = bottom_left.to_point(math.degrees(angle_bl_tr),
                                      diagonal / 2 - len_mb_mt / 2)
    top_left = mid_top.to_point(math.degrees(angle_mt_tl + angle_bl_tr),
                                len_mt_tl)

    top_right = Point(width, 0)
    bottom_right = mid_bottom.to_point(
        -math.degrees(angle_mt_tl - angle_bl_tr), len_mt_tl)

    lightning_points = [
        bottom_left, top_left, mid_top, top_right, bottom_right, mid_bottom
    ]
    # lightning_points = [bottom_left, top_left, mid_top]

    lightning_svg = Polygon(points=points_to_str(lightning_points))
    lightning_svg.set_style(StyleBuilder(spec['style']).getStyle())

    return lightning_svg, width, height
def two_gears_inside_a_circular_shape(radius, inner_shape_spec):
    svg_group = G()

    gear_radius = radius * 0.7
    gear1_svg_group, _, _ = a_gear(radius=gear_radius, spec=inner_shape_spec)
    gear2_svg_group, _, _ = a_gear(radius=gear_radius, spec=inner_shape_spec)

    # gear1 is towards top left
    north_west_point_on_circle = Point(radius, radius).to_point(135, radius)
    gear1_center_point = north_west_point_on_circle.to_point(-45, gear_radius)
    gear1_svg_group_xy = '{0},{1}'.format(gear1_center_point.x - gear_radius,
                                          gear1_center_point.y - gear_radius)
    transformer = TransformBuilder()
    transformer.setTranslation(gear1_svg_group_xy)
    gear1_svg_group.set_transform(transformer.getTransform())
    svg_group.addElement(gear1_svg_group)

    # gear2 is towards bottom right
    south_east_point_on_circle = Point(radius, radius).to_point(-45, radius)
    gear2_center_point = south_east_point_on_circle.to_point(135, gear_radius)
    gear2_svg_group_xy = '{0},{1}'.format(gear2_center_point.x - gear_radius,
                                          gear2_center_point.y - gear_radius)
    transformer = TransformBuilder()
    transformer.setTranslation(gear2_svg_group_xy)
    gear2_svg_group.set_transform(transformer.getTransform())
    svg_group.addElement(gear2_svg_group)

    return svg_group, radius * 2, radius * 2
def an_equilateral_triangle_inside_a_circular_shape(radius, inner_shape_spec):
    # in a trangle ABC, A is alwys the top vertex
    svg_group = G()

    pad = radius * 0.4
    center_to_vertex = radius - pad
    center_point = Point(radius, radius)
    point_a = center_point.to_point(90, center_to_vertex)
    point_b = center_point.to_point(210, center_to_vertex)
    point_c = center_point.to_point(330, center_to_vertex)
    points = [point_a, point_b, point_c, point_a]
    triangle_svg = Polygon(points=points_to_str(points))
    triangle_svg.set_style(StyleBuilder(inner_shape_spec['style']).getStyle())

    # add to group
    svg_group.addElement(triangle_svg)
    return svg_group, radius * 2, radius * 2
def an_equilateral_pentagon_inside_a_circular_shape(radius, inner_shape_spec):
    svg_group = G()

    pad = radius * 0.4
    center_to_vertex = radius - pad
    center_point = Point(radius, radius)
    point_a = center_point.to_point(90 - (72 * 0), center_to_vertex)
    point_b = center_point.to_point(90 - (72 * 1), center_to_vertex)
    point_c = center_point.to_point(90 - (72 * 2), center_to_vertex)
    point_d = center_point.to_point(90 - (72 * 3), center_to_vertex)
    point_e = center_point.to_point(90 - (72 * 4), center_to_vertex)
    points = [point_a, point_b, point_c, point_d, point_e, point_a]
    pentagon_svg = Polygon(points=points_to_str(points))
    pentagon_svg.set_style(StyleBuilder(inner_shape_spec['style']).getStyle())

    # add to group
    svg_group.addElement(pentagon_svg)
    return svg_group, radius * 2, radius * 2
def a_clock(radius, spec):
    clock_group_svg, _, _ = a_circle(radius, spec)

    hour_mark_length = radius * 0.3
    minute_hand_length = radius * 0.6
    hour_hand_length = radius * 0.4

    minute_hand_svg = Line(x1=radius,
                           y1=radius,
                           x2=radius,
                           y2=(radius - minute_hand_length))
    minute_hand_svg.set_style(StyleBuilder(spec['style']).getStyle())
    hour_hand_svg = Line(x1=radius,
                         y1=radius,
                         x2=radius + hour_hand_length,
                         y2=radius)
    hour_hand_svg.set_style(StyleBuilder(spec['style']).getStyle())

    clock_group_svg.addElement(minute_hand_svg)
    clock_group_svg.addElement(hour_hand_svg)

    # the hour marks
    center_point = Point(radius, radius)
    for hour in range(0, 12):
        point_on_circle = center_point.to_point(30 * hour, radius)
        point_inside = center_point.to_point(30 * hour,
                                             radius - hour_mark_length)
        hour_mark_svg = Line(x1=point_on_circle.x,
                             y1=point_on_circle.y,
                             x2=point_inside.x,
                             y2=point_inside.y)
        hour_mark_svg.set_style(StyleBuilder(spec['style']).getStyle())
        clock_group_svg.addElement(hour_mark_svg)

    # add to group
    return clock_group_svg, radius * 2, radius * 2