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.
This commit is contained in:
Jesse Millwood 2023-09-12 19:56:18 -04:00
parent 28f126df71
commit 13f513e4b8

View File

@ -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