3 # Draw a circle surrounded by other circles
5 # Copyright (C) 2018 Antonio Ospite <ao2@ao2.it>
6 # SPDX-License-Identifier: WTFPL
8 # Using a formula from:
9 # https://math.stackexchange.com/questions/12166/numbers-of-circles-around-a-circle
11 from math import pi, sin, cos, degrees
15 def calc_inner_circle_radius(outer_circles_radius, number_of_circles):
16 if outer_circles_radius <= 0:
17 raise ValueError("Radius of outer circles cannot be zero")
19 if number_of_circles < 3:
20 raise ValueError("Number of outer circles cannot be smaller than 3")
22 # Ratio between the inner circle and the outer circles
23 ratio = sin(pi / number_of_circles) / (1 - sin(pi / number_of_circles))
25 inner_circle_radius = outer_circles_radius / ratio
27 return inner_circle_radius
30 def write_svg(filename, inner_circle_radius, outer_circles_radius,
31 number_of_circles, unit=""):
34 width = height = (inner_circle_radius + outer_circles_radius + border) * 2
36 svg = svgwrite.Drawing(filename, profile='full',
37 size=(str(width) + unit, str(height) + unit),
38 viewBox=('0 0 %g %g') % (width, height))
40 cx_inner = cy_inner = width / 2
42 inner_circle = svgwrite.shapes.Circle(center=(cx_inner, cy_inner),
43 r=inner_circle_radius,
49 # Add a group for the first outer circle for extra flexibility.
50 outer_circle_group = svgwrite.container.Group()
51 svg.add(outer_circle_group)
53 cx_outer = cx_inner + sin(0) * (inner_circle_radius +
55 cy_outer = cy_inner + cos(0) * (inner_circle_radius +
57 outer_circle = svgwrite.shapes.Circle(center=(cx_outer, cy_outer),
58 r=outer_circles_radius,
62 outer_circle_group.add(outer_circle)
64 # Clone the group for the other outer circles to make it easier to keep
65 # visual symmetry by editing just the first group added above.
66 for i in range(1, number_of_circles):
67 theta = i * 2 * pi / number_of_circles
68 outer_circle_clone = svgwrite.container.Use(outer_circle_group,
70 transform="rotate(%f, %f, %f)" %
74 svg.add(outer_circle_clone)
80 outer_circles_radius = 2.5
81 number_of_circles = 22
83 inner_circle_radius = calc_inner_circle_radius(outer_circles_radius, number_of_circles)
85 write_svg("circle-surrounded-by-circles.svg", inner_circle_radius,
86 outer_circles_radius, number_of_circles, unit="mm")
89 if __name__ == "__main__":