bundle: update (2026-01-16)
This commit is contained in:
190
extensions/km-living-hinge/shapes.py
Normal file
190
extensions/km-living-hinge/shapes.py
Normal file
@@ -0,0 +1,190 @@
|
||||
# Functions that return segments to draw each shape based on height/width
|
||||
# Configs that are highly opinionated to calculate some parameters
|
||||
|
||||
def line_shape(height, width):
|
||||
return [
|
||||
[(0, 0), (0, height)]
|
||||
]
|
||||
|
||||
|
||||
def fishbone_shape(height, width):
|
||||
mid_x = width / 2
|
||||
return [
|
||||
[(0, 0), (mid_x, height), (width, 0)]
|
||||
]
|
||||
|
||||
|
||||
def cross_shape(height, width):
|
||||
dx = width * 0.1
|
||||
mid_y = height / 2
|
||||
left_inner = width * 0.25 + dx
|
||||
right_inner = width * 0.75 - dx
|
||||
|
||||
return [
|
||||
[(0, 0), (left_inner, mid_y), (0, height)],
|
||||
[(left_inner, mid_y), (right_inner, mid_y)],
|
||||
[(width, 0), (right_inner, mid_y), (width, height)],
|
||||
]
|
||||
|
||||
|
||||
def bezier_shape(height, width, anchor_tip=0.2, anchor_center=0.3):
|
||||
return [
|
||||
('C', [
|
||||
(0, 0),
|
||||
(width * anchor_tip, 0),
|
||||
(width * (0.5 - anchor_center), height),
|
||||
(width * 0.5, height)
|
||||
]),
|
||||
('C', [
|
||||
(width * 0.5, height),
|
||||
(width * (0.5 + anchor_center), height),
|
||||
(width * (1 - anchor_tip), 0),
|
||||
(width, 0)
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def wave_shape(height, width, param_a=0.0, param_b=0.0):
|
||||
mid_y = height / 2
|
||||
|
||||
return [
|
||||
('L', [(0, 0), (width * 0.25, 0)]),
|
||||
('Q', [(width * 0.25, 0), (width * (0.5 + param_a), height * param_b), (width * 0.5, mid_y)]),
|
||||
('Q', [(width * 0.5, mid_y), (width * (0.5 - param_a), height * (1 - param_b)), (width * 0.75, height)]),
|
||||
('L', [(width * 0.75, height), (width, height)]),
|
||||
]
|
||||
|
||||
|
||||
def fabric_shape(height, width):
|
||||
line1 = [
|
||||
(width * 0.25, height * 0.25),
|
||||
(width * 0.0, height * 0.25),
|
||||
(width * 0.0, height * 0.0),
|
||||
(width * 0.5, height * 0.0),
|
||||
(width * 0.5, height * 1.0),
|
||||
(width * 1.0, height * 1.0),
|
||||
(width * 1.0, height * 0.75),
|
||||
(width * 0.75, height * 0.75),
|
||||
]
|
||||
|
||||
line2 = [
|
||||
(width * 0.75, height * 0.25),
|
||||
(width * 0.75, height * 0.0),
|
||||
(width * 1.0, height * 0.0),
|
||||
(width * 1.0, height * 0.5),
|
||||
(width * 0.0, height * 0.5),
|
||||
(width * 0.0, height * 1.0),
|
||||
(width * 0.25, height * 1.0),
|
||||
(width * 0.25, height * 0.75),
|
||||
]
|
||||
|
||||
return [line1, line2]
|
||||
|
||||
|
||||
def circle_shape(height, width):
|
||||
kappa = 0.5522847498
|
||||
rx = width / 2
|
||||
ry = height / 2
|
||||
cx = rx
|
||||
cy = ry
|
||||
kx = rx * kappa
|
||||
ky = ry * kappa
|
||||
|
||||
return [
|
||||
('C', [
|
||||
(cx + rx, cy),
|
||||
(cx + rx, cy + ky),
|
||||
(cx + kx, cy + ry),
|
||||
(cx, cy + ry)
|
||||
]),
|
||||
('C', [
|
||||
(cx, cy + ry),
|
||||
(cx - kx, cy + ry),
|
||||
(cx - rx, cy + ky),
|
||||
(cx - rx, cy)
|
||||
]),
|
||||
('C', [
|
||||
(cx - rx, cy),
|
||||
(cx - rx, cy - ky),
|
||||
(cx - kx, cy - ry),
|
||||
(cx, cy - ry)
|
||||
]),
|
||||
('C', [
|
||||
(cx, cy - ry),
|
||||
(cx + kx, cy - ry),
|
||||
(cx + rx, cy - ky),
|
||||
(cx + rx, cy)
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def line_config(height, width, x_spacing, y_spacing, bbox):
|
||||
_, _, _, bbox_height = bbox
|
||||
height = height * bbox_height
|
||||
y_offset = (height + y_spacing) / 2
|
||||
return (height, 0, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def fishbone_config(height, width, x_spacing, y_spacing, bbox):
|
||||
y_offset = (height + y_spacing) / 2
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def cross_config(height, width, x_spacing, y_spacing, bbox):
|
||||
x_spacing = -0.4 * width
|
||||
y_spacing = height
|
||||
y_offset = height
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def bezier_config(height, width, x_spacing, y_spacing, bbox):
|
||||
y_offset = (height + y_spacing) / 2
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def wave_config(height, width, x_spacing, y_spacing, bbox):
|
||||
x_spacing = -0.2 * width
|
||||
y_spacing = 0
|
||||
y_offset = 0.5 * height
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def fabric_config(height, width, x_spacing, y_spacing, bbox):
|
||||
x_spacing = -0.375 * width
|
||||
y_spacing = 0.25 * height
|
||||
y_offset = 0.625 * height
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
def circle_config(height, width, x_spacing, y_spacing, bbox):
|
||||
y_offset = (height + y_spacing) / 2
|
||||
return (height, width, x_spacing, y_spacing, y_offset)
|
||||
|
||||
|
||||
SHAPES = {
|
||||
'line': line_shape,
|
||||
'fishbone': fishbone_shape,
|
||||
'cross': cross_shape,
|
||||
'bezier': bezier_shape,
|
||||
'wave': wave_shape,
|
||||
'fabric': fabric_shape,
|
||||
'circle': circle_shape,
|
||||
}
|
||||
|
||||
CONFIGS = {
|
||||
'line': line_config,
|
||||
'fishbone': fishbone_config,
|
||||
'cross': cross_config,
|
||||
'bezier': bezier_config,
|
||||
'wave': wave_config,
|
||||
'fabric': fabric_config,
|
||||
'circle': circle_config,
|
||||
}
|
||||
|
||||
|
||||
def get_shape(shape_type):
|
||||
return SHAPES.get(shape_type, line_shape)
|
||||
|
||||
|
||||
def get_config(shape_type):
|
||||
return CONFIGS.get(shape_type, line_config)
|
||||
Reference in New Issue
Block a user