mightyscape-1.2/extensions/fablabchemnitz/box_maker_t_slot/ink_helper.py

161 lines
4.1 KiB
Python
Raw Normal View History

2022-09-02 18:19:57 +02:00
import math
import inkex
from lxml import etree
def drawS(XYstring, parent): # Draw lines from a list
name='part'
style = { 'stroke': '#000000', 'stroke-width':'0.26458333', 'fill': 'none' }
drw = {'style':str(inkex.Style(style)),inkex.addNS('label','inkscape'):name,'d':XYstring}
etree.SubElement(parent, inkex.addNS('path','svg'), drw )
return
class Vec2:
def __init__(self, x, y=None):
if y is None:
y = x[1]
x = x[0]
self.x = x
self.y = y
def norm(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def __getitem__(self, idx):
return [self.x, self.y][idx]
def __neg__(self):
return Vec2(-self.x, -self.y)
def __add__(self, other):
return Vec2(self.x + other[0], self.y + other[1])
def __sub__(self, other):
return self + [-other[0], -other[1]]
def __mul__(self, scalar):
return Vec2(self.x * scalar, self.y * scalar)
def __truediv__(self, scalar):
return Vec2(self.x / scalar, self.y / scalar)
def dot(self, other):
return self.x * other[0] + self.y * other[1]
def inner(self, other):
return self.dot(other)
def outer(self, other):
return [[self[0] * other[0], self[0] * other[1]],
[self[1] * other[0], self[1] * other[1]]]
def __repr__(self):
return 'Vec2(%s, %s)' % (self.x, self.y)
def toXY(self):
return '%s,%s ' % (self.x, self.y)
def mat_x_vec(mat, vec):
return Vec2(vec.dot(mat[0]), vec.dot(mat[1]))
def sign(x):
return 1 if x > 0 else -1
class Path:
'''
a list of Vec2 points
'''
def __init__(self, path=()):
self.path = [Vec2(p) for p in path]
def append(self, point):
self.path.append(Vec2(point))
def rotate(self, center, angle):
'''
angle in degrees
'''
from math import cos, sin
angle *= math.pi / 180.
R = [[cos(angle), -sin(angle)],
[sin(angle), cos(angle)]]
out = [mat_x_vec(R, p - center) + center for p in self.path]
return Path(out)
def translate(self, vec):
return Path([p + vec for p in self.path])
def append_from_last(self, v):
self.path.append(self.path[-1] + v)
def extend(self, points):
self.path.extend(points)
def __getitem__(self, idx):
return self.path[idx]
def reflect(self, center, orient):
out = self.translate(-center)
R = Vec2(orient).outer(orient)
R = [[1 - 2 * R[0][0], 2 * R[0][1]],
[2 * R[1][0], 1 - 2 * R[1][1]]]
out = Path([mat_x_vec(R, p) for p in out])
out = out.translate(center)
return out
def reverse(self):
return Path(self.path[::-1])
def drawXY(self):
XYstring = 'M ' + 'L '.join([p.toXY() for p in self.path])
return XYstring
def plot(self, lt='-'):
from pylab import plot
xs = [l.x for l in self.path]
ys = [l.y for l in self.path]
plot(xs, ys, lt)
def Vec2__test__():
v1 = Vec2(1, 1)
assert abs(v1.norm() - math.sqrt(2)) < 1e-8
assert abs(-v1[0] + 1) < 1e-8
assert abs((v1 + v1)[0] - 2) < 1e-8
assert abs((v1 - v1)[0] - 0) < 1e-8
assert abs((v1 + [1, 2]).x - 2) < 1e-8
assert abs((v1 - [1, 2]).x - 0) < 1e-8
assert (v1.dot(v1) - v1.norm() ** 2) < 1e-8
Vec2__test__()
if __name__ == '__main__':
from pylab import plot, figure, clf, show, axis
from numpy import array
mm = 1.
center = [0, 30 * mm]
orient = [12. * mm, 0]
screw_diameter = 3 * mm
nut_diameter = 5.5 * mm
nut_w = 2.5 * mm
screw_length = 16 * mm
thickness = 6 * mm
orient = Vec2(orient)
out = orient / math.sqrt(orient[0] ** 2 + orient[1] ** 2)
up = Vec2([-out[1], out[0]])
center = Vec2(center)
screw_r = screw_diameter / 2.
nut_r = nut_diameter / 2.
path = Path([center + up * screw_r])
path.append_from_last(orient)
path.append_from_last(up * (nut_r - screw_r))
path.append_from_last(out * (nut_w))
path.append_from_last(-up * (nut_r - screw_r))
path.append_from_last(out * (screw_length - thickness))
path.append_from_last(-up * screw_r)
rest = path.reflect(center, up).reverse()
path.extend(rest)
path.plot()
rest.plot('o-')
axis('equal')
show()