From 13f513e4b83b8f737ffa15cdf3461623c6a58cdb Mon Sep 17 00:00:00 2001 From: Jesse Millwood Date: Tue, 12 Sep 2023 19:56:18 -0400 Subject: [PATCH] Refactored algorithm and documented The new algorithm places circles with more dependencies so that the spacing between kitty corner and circles on the same line are the same. --- honeycomb.py | 85 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/honeycomb.py b/honeycomb.py index b7b75ff..228bfa3 100644 --- a/honeycomb.py +++ b/honeycomb.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import inkex +import math class HoneyCombExtension(inkex.EffectExtension): def add_arguments(self, pars): @@ -38,36 +39,84 @@ class HoneyCombExtension(inkex.EffectExtension): if target.get("r"): # Selection is a circle - target_rad = float(target.get("r")) - target_dia = 2 * float(target_rad) - target_style = target.get("style") - difference = bounding_box_w - (target_dia * self.options.count_x) - target_spacing = difference/(self.options.count_x) + # Draw Honeycomb circles in a bounding box + # +------ ---------------------------------------------------+ + # | * * |-s1-| * * | + # | * * | | * * | + # | * (x1,y1) *| |* (x2,y2) * | + # | * |\ * * * | + # | * | \ * * * | + # | *| *\ c * * | + # | | \ * * | + # | a| * * | + # | | * (x3,y3) * | + # | |___*____ * | + # | b * * | + # | * * | + # | | + # +----------------------------------------------------------+ + # Known values: + # ============= + # Circle centers known: (x1,y1) and (x2,y2) + # Radius of circles known: r1, r2, r3 and r1=r2=r3 + # Therefore, spacing, s1 is known + # Spacing Between circle 1 and 2: s1 = x2-x1-2r + # + # Calculate coordinages for circle 3: + # =================================== + # Triangle to find coordinates of circle 3: + # |\ + # | \ + # a| \c + # | \ + # |____\ + # b + # a^2+b^2=c^2 + # a = (c^2-b^2)^1/2 + # b = (x2-x1)/2 + # c = r1+r3+s1 + # = 2r1+(x1-x2-2r) + # = x1-x2 + # a = ((x2-x1)^2 -((x2-x1)/2)^2)^1/2 + # + # x3 = x1 + ((x2-x1)/2) + # y3 = y2 - sqrt((x2-x1)^2 - ((x2-x1)/2)^2) + circle_r = float(target.get("r")) + circle_d = 2 * circle_r + circle_style = target.get("style") - shift_row = True + # Calculate spacing between circles in a row to fit a + # given bounding box + left_over = bounding_box_w - (circle_d * self.options.count_x) + spacing = left_over/(self.options.count_x) + circ_center_diff = spacing + (2 * circle_r) + + shift_row = False + y_coord_last = 0 for y_cnt in range(0, self.options.count_y): - y_coord = (bounding_box_y + target_rad) - y_coord += y_cnt * target_dia - if y_cnt % 2 != 0: - shift_row = True + if y_cnt == 0: + y_coord = bounding_box_y + circle_r + else: + y_coord = y_coord_last + math.sqrt(pow(circ_center_diff,2)-pow(circ_center_diff/2,2)) + if shift_row: num_x = self.options.count_x + 1 else: - shift_row = False num_x = self.options.count_x for x_cnt in range(0, num_x): - x_coord = bounding_box_x + target_rad - x_coord += x_cnt * (target_spacing + target_dia) - if shift_row: - x_coord -= target_rad + if shift_row is True: + x_coord_int = bounding_box_x else: - x_coord += target_spacing / 2 + x_coord_int = bounding_box_x + (spacing/2) + circle_r + x_coord = x_coord_int + (x_cnt * circ_center_diff) circ = inkex.Circle(attrib={"cx": f"{x_coord}", "cy": f"{y_coord}", - "r": f"{target_rad}", - "style": target_style}) + "r": f"{circle_r}", + "style": circle_style}) layer = self.svg.get_current_layer() layer.append(circ) + y_coord_last = y_coord + shift_row ^= True elif target.get("rx"): # Selection is an elipse