Connected rhombi

circle_radius = 4 svg_width, svg_height = 740, 550 half_svg_width, half_svg_height = svg_width / 2, svg_height / 2 big_rhombus_side = 400 smaller_rhombi_per_side = 10 half_smaller_rhombi_per_side = smaller_rhombi_per_side / 2 rhombus_side = big_rhombus_side / smaller_rhombi_per_side half_rhombus_side = rhombus_side / 2 rhombus_height = half_rhombus_side * 3 ** 0.5 big_rhombus_height = (big_rhombus_side / 2) * 3 ** 0.5 # Templates for SVG use line_template = "<line x1='%d' y1='%d' x2='%d' y2='%d' />" circle_template = "<circle cx='%d' cy='%d' r='%d' />" # Define big rhombus corner points big_rhombus_point_coords = [ (half_svg_width-big_rhombus_height, half_svg_height), # left (half_svg_width, half_svg_height-big_rhombus_side/2), # top (half_svg_width+big_rhombus_height, half_svg_height), # right (half_svg_width, half_svg_height+big_rhombus_side/2), # bottom (half_svg_width-big_rhombus_height, half_svg_height), # connect to start ] topx, topy = big_rhombus_point_coords[1] leftx, lefty = big_rhombus_point_coords[0] rightx, righty = big_rhombus_point_coords[2] bottomx, bottomy = big_rhombus_point_coords[3] rhombus_html, internal_lines, circles = [], [], [] # Draw border lines for i in range(len(big_rhombus_point_coords) - 1): p1x, p1y = big_rhombus_point_coords[i] p2x, p2y = big_rhombus_point_coords[i+1] rhombus_html.append(line_template % (p1x, p1y, p2x, p2y)) # Draw internal lines for k in range(smaller_rhombi_per_side): k_half_sides = k * half_rhombus_side k_heights = k *rhombus_height # From top to right iter_content = line_template % ( topx - k_heights, topy + k_half_sides, rightx - k_heights, righty + k_half_sides ) # From top to left iter_content += line_template % ( topx + k_heights, topy + k_half_sides, leftx + k_heights, lefty + k_half_sides ) # Vertical lines to left iter_content += line_template % ( topx - k_heights, topy + k_half_sides, bottomx - k_heights, bottomy - k_half_sides ) # Vertical lines to right iter_content += line_template % ( topx + k_heights, topy + k_half_sides, bottomx + k_heights, bottomy - k_half_sides ) internal_lines.append(iter_content) # Draw points c = 0 r = 2*smaller_rhombi_per_side+3 mid = r / 2 point_range = range(r) for i in point_range: x = leftx + i*rhombus_height for j in point_range: if not (i+j) & 1: y = topy + j*half_rhombus_side if not smaller_rhombi_per_side - c <= j <= smaller_rhombi_per_side + c: continue circles.append(circle_template % (x, y, circle_radius)) c += -1 if i > smaller_rhombi_per_side - 1 else 1 # Output (for use within SVG tag) content = "<g stroke-width='4' stroke='black'>%s</g><g stroke-width='1' stroke='black'>%s</g><g>%s</g>" % (''.join(rhombus_html), ''.join(internal_lines), ''.join(circles))