2016-07-15 18:29:14 +02:00
|
|
|
from math import *
|
2022-12-31 15:52:55 +01:00
|
|
|
|
2017-03-05 12:52:12 +01:00
|
|
|
from boxes import vectors
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2022-12-31 15:52:55 +01:00
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
def arcOnCircle(spanning_angle, outgoing_angle, r=1.0):
|
2016-08-17 15:07:41 +02:00
|
|
|
angle = spanning_angle + 2 * outgoing_angle
|
|
|
|
radius = r * sin(radians(0.5 * spanning_angle)) / sin(radians(180 - outgoing_angle - 0.5 * spanning_angle))
|
2016-07-15 18:29:14 +02:00
|
|
|
return angle, abs(radius)
|
|
|
|
|
|
|
|
|
2016-08-17 15:07:41 +02:00
|
|
|
class Parts:
|
2016-07-15 18:29:14 +02:00
|
|
|
def __init__(self, boxes):
|
|
|
|
self.boxes = boxes
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
"""
|
|
|
|
def roundKnob(self, diameter, n=20, callback=None, move=""):
|
2016-07-17 18:02:51 +02:00
|
|
|
size = diameter+diameter/n
|
2016-07-15 18:29:14 +02:00
|
|
|
if self.move(size, size, move, before=True):
|
|
|
|
return
|
|
|
|
self.moveTo(size/2, size/2)
|
|
|
|
self.cc(callback, None, 0, 0)
|
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
self.move(size, size, move)
|
2016-07-15 18:29:14 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
return getattr(self.boxes, name)
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2022-05-14 10:35:58 +02:00
|
|
|
def disc(self, diameter, hole=0, callback=None, move="", label=""):
|
2018-08-23 23:23:12 +02:00
|
|
|
"""Simple disc
|
|
|
|
|
|
|
|
:param diameter: diameter of the disc
|
|
|
|
:param hole: (Default value = 0)
|
|
|
|
:param callback: (Default value = None) called in the center
|
2023-01-02 00:32:42 +01:00
|
|
|
:param move: (Default value = "")
|
|
|
|
:param label: (Default value = "")
|
2018-08-23 23:23:12 +02:00
|
|
|
"""
|
2016-07-27 22:19:32 +02:00
|
|
|
size = diameter
|
2016-08-17 15:07:41 +02:00
|
|
|
r = diameter / 2.0
|
|
|
|
|
2022-05-14 10:35:58 +02:00
|
|
|
if self.move(size, size, move, before=True, label=label):
|
2016-07-15 18:29:14 +02:00
|
|
|
return
|
2016-08-17 15:07:41 +02:00
|
|
|
|
|
|
|
self.moveTo(size / 2, size / 2)
|
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
if hole:
|
2016-08-17 15:07:41 +02:00
|
|
|
self.hole(0, 0, hole / 2)
|
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
self.cc(callback, None, 0, 0)
|
2016-08-17 15:07:41 +02:00
|
|
|
self.moveTo(r + self.burn, 0, 90)
|
2019-02-14 17:34:22 +01:00
|
|
|
self.corner(360, r, tabs=6)
|
2022-05-14 10:35:58 +02:00
|
|
|
self.move(size, size, move, label=label)
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
def waivyKnob(self, diameter, n=20, angle=45, hole=0, callback=None, move=""):
|
2018-08-23 23:23:12 +02:00
|
|
|
"""Disc with a waivy edge to be easier to be gripped
|
|
|
|
|
|
|
|
:param diameter: diameter of the knob
|
|
|
|
:param n: (Default value = 20) number of waves
|
|
|
|
:param angle: (Default value = 45) maximum angle of the wave
|
|
|
|
:param hole: (Default value = 0)
|
|
|
|
:param callback: (Default value = None) called in the center
|
2023-01-02 00:32:42 +01:00
|
|
|
:param move: (Default value = "")
|
2018-08-23 23:23:12 +02:00
|
|
|
"""
|
2017-10-01 21:01:18 +02:00
|
|
|
|
|
|
|
if n < 2:
|
|
|
|
return
|
|
|
|
|
2016-08-17 15:07:41 +02:00
|
|
|
size = diameter + pi * diameter / n
|
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
if self.move(size, size, move, before=True):
|
|
|
|
return
|
2016-08-17 15:07:41 +02:00
|
|
|
|
|
|
|
self.moveTo(size / 2, size / 2)
|
2016-07-15 18:29:14 +02:00
|
|
|
self.cc(callback, None, 0, 0)
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
if hole:
|
2016-08-17 15:07:41 +02:00
|
|
|
self.hole(0, 0, hole / 2)
|
|
|
|
|
2017-10-01 20:18:42 +02:00
|
|
|
self.moveTo(diameter / 2, 0, 90-angle)
|
2017-10-01 20:54:04 +02:00
|
|
|
a, r = arcOnCircle(360. / n / 2, angle, diameter / 2)
|
|
|
|
a2, r2 = arcOnCircle(360. / n / 2, -angle, diameter / 2)
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2017-10-01 20:54:04 +02:00
|
|
|
for i in range(n):
|
2019-02-14 17:34:22 +01:00
|
|
|
self.boxes.corner(a, r, tabs=(i % max(1, (n+1) // 6) == 0))
|
2016-07-15 18:29:14 +02:00
|
|
|
self.boxes.corner(a2, r2)
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
self.move(size, size, move)
|
2016-07-15 18:29:14 +02:00
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
def concaveKnob(self, diameter, n=3, rounded=0.2, angle=70, hole=0,
|
|
|
|
callback=None, move=""):
|
2018-08-23 23:23:12 +02:00
|
|
|
"""Knob with dents to be easier to be gripped
|
|
|
|
|
|
|
|
:param diameter: diameter of the knob
|
|
|
|
:param n: (Default value = 3) number of dents
|
2023-01-02 00:32:42 +01:00
|
|
|
:param rounded: (Default value = 0.2) proportion of circumference remaining
|
2019-02-14 17:34:22 +01:00
|
|
|
:param angle: (Default value = 70) angle the dents meet the circumference
|
2018-08-23 23:23:12 +02:00
|
|
|
:param hole: (Default value = 0)
|
|
|
|
:param callback: (Default value = None) called in the center
|
2023-01-02 00:32:42 +01:00
|
|
|
:param move: (Default value = "")
|
2018-08-23 23:23:12 +02:00
|
|
|
"""
|
2016-07-27 22:19:32 +02:00
|
|
|
size = diameter
|
2016-08-17 15:07:41 +02:00
|
|
|
|
2017-10-01 21:01:18 +02:00
|
|
|
if n < 2:
|
|
|
|
return
|
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
if self.move(size, size, move, before=True):
|
|
|
|
return
|
2016-08-17 15:07:41 +02:00
|
|
|
|
|
|
|
self.moveTo(size / 2, size / 2)
|
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
if hole:
|
2016-08-17 15:07:41 +02:00
|
|
|
self.hole(0, 0, hole / 2)
|
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
self.cc(callback, None, 0, 0)
|
2016-08-17 15:07:41 +02:00
|
|
|
self.moveTo(diameter / 2, 0, 90 + angle)
|
|
|
|
a, r = arcOnCircle(360. / n * (1 - rounded), -angle, diameter / 2)
|
|
|
|
|
|
|
|
if abs(a) < 0.01: # avoid trying to make a straight line as an arc
|
|
|
|
a, r = arcOnCircle(360. / n * (1 - rounded), -angle - 0.01, diameter / 2)
|
|
|
|
|
2016-07-15 18:29:14 +02:00
|
|
|
for i in range(n):
|
|
|
|
self.boxes.corner(a, r)
|
|
|
|
self.corner(angle)
|
2019-02-14 17:34:22 +01:00
|
|
|
self.corner(360. / n * rounded, diameter / 2, tabs=
|
|
|
|
(i % max(1, (n+1) // 6) == 0))
|
2016-07-15 18:29:14 +02:00
|
|
|
self.corner(angle)
|
2016-07-27 22:19:32 +02:00
|
|
|
|
2016-07-17 18:02:51 +02:00
|
|
|
self.move(size, size, move)
|
2017-03-05 12:52:12 +01:00
|
|
|
|
|
|
|
def ringSegment(self, r_outside, r_inside, angle, n=1, move=None):
|
2018-08-23 23:23:12 +02:00
|
|
|
"""Ring Segment
|
|
|
|
|
|
|
|
:param r_outside: outer radius
|
|
|
|
:param r_inside: inner radius
|
2023-01-02 00:32:42 +01:00
|
|
|
:param angle: angle the segment is spanning
|
2018-08-23 23:23:12 +02:00
|
|
|
:param n: (Default value = 1) number of segments
|
2023-01-02 00:32:42 +01:00
|
|
|
:param move: (Default value = "")
|
2018-08-23 23:23:12 +02:00
|
|
|
"""
|
2017-03-05 12:52:12 +01:00
|
|
|
space = 360 * r_inside / self.spacing
|
|
|
|
n = min(n, 360 / (angle+space))
|
|
|
|
|
|
|
|
# XXX be smarter about space
|
|
|
|
if self.move(r_outside, r_outside, move, True):
|
|
|
|
return
|
|
|
|
|
|
|
|
self.moveTo(r_outside)
|
|
|
|
for i in range(n):
|
2019-02-14 17:34:22 +01:00
|
|
|
self.polyline(
|
|
|
|
0, (angle, r_outside), 0, 90, (r_outside-r_inside, 2),
|
|
|
|
90, (angle, r_inside), 0, 90, (r_outside-r_inside, 2),
|
|
|
|
90)
|
2017-03-05 12:52:12 +01:00
|
|
|
x, y = vectors.circlepoint(r_outside, math.radians(angle+space))
|
|
|
|
self.moveTo(y, r_outside-x, angle+space)
|
|
|
|
self.move(r_outside, r_outside)
|
|
|
|
return n
|