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:
parent
28f126df71
commit
13f513e4b8
85
honeycomb.py
85
honeycomb.py
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
|
import math
|
||||||
|
|
||||||
class HoneyCombExtension(inkex.EffectExtension):
|
class HoneyCombExtension(inkex.EffectExtension):
|
||||||
def add_arguments(self, pars):
|
def add_arguments(self, pars):
|
||||||
@ -38,36 +39,84 @@ class HoneyCombExtension(inkex.EffectExtension):
|
|||||||
|
|
||||||
if target.get("r"):
|
if target.get("r"):
|
||||||
# Selection is a circle
|
# 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)
|
# Draw Honeycomb circles in a bounding box
|
||||||
target_spacing = difference/(self.options.count_x)
|
# +------ ---------------------------------------------------+
|
||||||
|
# | * * |-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):
|
for y_cnt in range(0, self.options.count_y):
|
||||||
y_coord = (bounding_box_y + target_rad)
|
if y_cnt == 0:
|
||||||
y_coord += y_cnt * target_dia
|
y_coord = bounding_box_y + circle_r
|
||||||
if y_cnt % 2 != 0:
|
else:
|
||||||
shift_row = True
|
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
|
num_x = self.options.count_x + 1
|
||||||
else:
|
else:
|
||||||
shift_row = False
|
|
||||||
num_x = self.options.count_x
|
num_x = self.options.count_x
|
||||||
for x_cnt in range(0, num_x):
|
for x_cnt in range(0, num_x):
|
||||||
x_coord = bounding_box_x + target_rad
|
if shift_row is True:
|
||||||
x_coord += x_cnt * (target_spacing + target_dia)
|
x_coord_int = bounding_box_x
|
||||||
if shift_row:
|
|
||||||
x_coord -= target_rad
|
|
||||||
else:
|
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}",
|
circ = inkex.Circle(attrib={"cx": f"{x_coord}",
|
||||||
"cy": f"{y_coord}",
|
"cy": f"{y_coord}",
|
||||||
"r": f"{target_rad}",
|
"r": f"{circle_r}",
|
||||||
"style": target_style})
|
"style": circle_style})
|
||||||
layer = self.svg.get_current_layer()
|
layer = self.svg.get_current_layer()
|
||||||
layer.append(circ)
|
layer.append(circ)
|
||||||
|
y_coord_last = y_coord
|
||||||
|
shift_row ^= True
|
||||||
|
|
||||||
elif target.get("rx"):
|
elif target.get("rx"):
|
||||||
# Selection is an elipse
|
# Selection is an elipse
|
||||||
|
Loading…
x
Reference in New Issue
Block a user