cosplay: Touhou/Houjuu Nue #4
|
@ -314,12 +314,12 @@ class TorsionJoint:
|
||||||
l = self.spring_tail_length
|
l = self.spring_tail_length
|
||||||
if self.right_handed:
|
if self.right_handed:
|
||||||
r2 = -r2
|
r2 = -r2
|
||||||
# This is (0, r2) and (l, r2) transformed by rotation matrix
|
|
||||||
# [[c, s], [-s, c]]
|
|
||||||
return [
|
return [
|
||||||
(0, 0, height),
|
(0, 0, height),
|
||||||
(c, s, height)
|
(c, s, height)
|
||||||
]
|
]
|
||||||
|
# This is (0, r2) and (l, r2) transformed by rotation matrix
|
||||||
|
# [[c, s], [-s, c]]
|
||||||
return [
|
return [
|
||||||
(s * r2, -s * l + c * r2, height),
|
(s * r2, -s * l + c * r2, height),
|
||||||
(c * l + s * r2, -s * l + c * r2, height),
|
(c * l + s * r2, -s * l + c * r2, height),
|
||||||
|
@ -332,6 +332,7 @@ class TorsionJoint:
|
||||||
height=self.spring_height,
|
height=self.spring_height,
|
||||||
thickness=self.spring_thickness,
|
thickness=self.spring_thickness,
|
||||||
tail_length=self.spring_tail_length,
|
tail_length=self.spring_tail_length,
|
||||||
|
right_handed=self.right_handed,
|
||||||
)
|
)
|
||||||
|
|
||||||
def track(self):
|
def track(self):
|
||||||
|
|
|
@ -5,11 +5,14 @@ def torsion_spring(radius=12,
|
||||||
height=20,
|
height=20,
|
||||||
thickness=2,
|
thickness=2,
|
||||||
omega=90,
|
omega=90,
|
||||||
tail_length=25):
|
tail_length=25,
|
||||||
|
right_handed: bool = False):
|
||||||
"""
|
"""
|
||||||
Produces a torsion spring with abridged geometry since sweep is very slow in
|
Produces a torsion spring with abridged geometry since sweep is very slow in
|
||||||
cq-editor.
|
cq-editor.
|
||||||
"""
|
"""
|
||||||
|
if right_handed:
|
||||||
|
omega = -omega
|
||||||
base = (
|
base = (
|
||||||
Cq.Workplane('XY')
|
Cq.Workplane('XY')
|
||||||
.cylinder(height=height, radius=radius,
|
.cylinder(height=height, radius=radius,
|
||||||
|
@ -17,12 +20,14 @@ def torsion_spring(radius=12,
|
||||||
)
|
)
|
||||||
base.faces(">Z").tag("top")
|
base.faces(">Z").tag("top")
|
||||||
base.faces("<Z").tag("bot")
|
base.faces("<Z").tag("bot")
|
||||||
|
|
||||||
|
box_shift = -radius if right_handed else radius-thickness
|
||||||
result = (
|
result = (
|
||||||
base
|
base
|
||||||
.cylinder(height=height, radius=radius - thickness, combine='s',
|
.cylinder(height=height, radius=radius - thickness, combine='s',
|
||||||
centered=(True, True, True))
|
centered=(True, True, True))
|
||||||
.transformed(
|
.transformed(
|
||||||
offset=(0, radius-thickness),
|
offset=(0, box_shift),
|
||||||
rotate=(0, 0, 0))
|
rotate=(0, 0, 0))
|
||||||
.box(
|
.box(
|
||||||
length=tail_length,
|
length=tail_length,
|
||||||
|
@ -33,18 +38,19 @@ def torsion_spring(radius=12,
|
||||||
.transformed(
|
.transformed(
|
||||||
offset=(0, 0, height - thickness),
|
offset=(0, 0, height - thickness),
|
||||||
rotate=(0, 0, omega))
|
rotate=(0, 0, omega))
|
||||||
.center(-tail_length, radius-thickness)
|
.center(-tail_length, box_shift)
|
||||||
.box(
|
.box(
|
||||||
length=tail_length,
|
length=tail_length,
|
||||||
width=thickness,
|
width=thickness,
|
||||||
height=thickness,
|
height=thickness,
|
||||||
centered=False)
|
centered=False)
|
||||||
)
|
)
|
||||||
result.polyline([(0, radius, 0), (tail_length, radius, 0)],
|
r = -radius if right_handed else radius
|
||||||
|
result.polyline([(0, r, 0), (tail_length, r, 0)],
|
||||||
forConstruction=True).tag("directrix_bot")
|
forConstruction=True).tag("directrix_bot")
|
||||||
c, s = math.cos(omega * math.pi / 180), math.sin(omega * math.pi / 180)
|
c, s = math.cos(omega * math.pi / 180), math.sin(omega * math.pi / 180)
|
||||||
result.polyline([
|
result.polyline([
|
||||||
(s * tail_length, c * radius - s * tail_length, height),
|
(s * tail_length, c * r - s * tail_length, height),
|
||||||
(c * tail_length + s * radius, c * radius - s * tail_length, height)],
|
(c * tail_length + s * r, c * r - s * tail_length, height)],
|
||||||
forConstruction=True).tag("directrix_top")
|
forConstruction=True).tag("directrix_top")
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -40,6 +40,9 @@ class TestJoints(unittest.TestCase):
|
||||||
for slot in range(j.rider_n_slots):
|
for slot in range(j.rider_n_slots):
|
||||||
with self.subTest(slot=slot):
|
with self.subTest(slot=slot):
|
||||||
self.torsion_joint_collision_case(j, slot)
|
self.torsion_joint_collision_case(j, slot)
|
||||||
|
def test_torsion_joint_collision_right_handed(self):
|
||||||
|
j = joints.TorsionJoint(right_handed=True)
|
||||||
|
self.torsion_joint_collision_case(j, 1)
|
||||||
|
|
||||||
|
|
||||||
class TestHandle(unittest.TestCase):
|
class TestHandle(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue