boxespy/boxes/parts.py

118 lines
3.4 KiB
Python
Raw Normal View History

from math import *
2017-03-05 12:52:12 +01:00
from boxes import vectors
2016-08-17 15:07:41 +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))
return angle, abs(radius)
2016-08-17 15:07:41 +02:00
class Parts:
def __init__(self, boxes):
self.boxes = boxes
2016-08-17 15:07:41 +02:00
"""
def roundKnob(self, diameter, n=20, callback=None, move=""):
size = diameter+diameter/n
if self.move(size, size, move, before=True):
return
self.moveTo(size/2, size/2)
self.cc(callback, None, 0, 0)
self.move(size, size, move)
"""
def __getattr__(self, name):
return getattr(self.boxes, name)
2016-08-17 15:07:41 +02:00
def disc(self, diameter, hole=0, callback=None, move=""):
size = diameter
2016-08-17 15:07:41 +02:00
r = diameter / 2.0
if self.move(size, size, move, before=True):
return
2016-08-17 15:07:41 +02:00
self.moveTo(size / 2, size / 2)
if hole:
2016-08-17 15:07:41 +02:00
self.hole(0, 0, hole / 2)
self.cc(callback, None, 0, 0)
2016-08-17 15:07:41 +02:00
self.moveTo(r + self.burn, 0, 90)
self.corner(360, r)
2016-07-24 22:28:27 +02:00
self.move(size, size, move)
2016-08-17 15:07:41 +02:00
def waivyKnob(self, diameter, n=20, angle=45, hole=0, callback=None, move=""):
if n < 2:
return
2016-08-17 15:07:41 +02:00
size = diameter + pi * diameter / n
if self.move(size, size, move, before=True):
return
2016-08-17 15:07:41 +02:00
self.moveTo(size / 2, size / 2)
self.cc(callback, None, 0, 0)
2016-08-17 15:07:41 +02:00
if hole:
2016-08-17 15:07:41 +02:00
self.hole(0, 0, hole / 2)
self.moveTo(diameter / 2, 0, 90-angle)
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
for i in range(n):
self.boxes.corner(a, r)
self.boxes.corner(a2, r2)
2016-08-17 15:07:41 +02:00
self.move(size, size, move)
def concaveKnob(self, diameter, n=3, rounded=0.2, angle=70, hole=0,
callback=None, move=""):
size = diameter
2016-08-17 15:07:41 +02:00
if n < 2:
return
if self.move(size, size, move, before=True):
return
2016-08-17 15:07:41 +02:00
self.moveTo(size / 2, size / 2)
if hole:
2016-08-17 15:07:41 +02:00
self.hole(0, 0, hole / 2)
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)
for i in range(n):
self.boxes.corner(a, r)
self.corner(angle)
2016-08-17 15:07:41 +02:00
self.corner(360. / n * rounded, diameter / 2)
self.corner(angle)
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):
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):
self.polyline(0, (angle, r_outside), 0, 90, (r_outside-r_inside),
90, (angle, r_inside), 0, 90, (r_outside-r_inside),
90)
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