cosplay: Touhou/Houjuu Nue #4
|
@ -6,6 +6,33 @@ def binary_intersection(a: Cq.Assembly) -> Cq.Shape:
|
|||
obj1, obj2 = objs[:2]
|
||||
return obj1.intersect(obj2)
|
||||
|
||||
def visualize_intersection(assembly: Cq.Assembly, tol: float=1e-6) -> Cq.Shape:
|
||||
"""
|
||||
Given an assembly, test the pairwise intersection volume of its components.
|
||||
Return the pairs whose intersection volume exceeds `tol`.
|
||||
"""
|
||||
m = {name: (i, shape.moved(loc))
|
||||
for i, (shape, name, loc, _)
|
||||
in enumerate(assembly)}
|
||||
for name, (i1, sh1) in m.items():
|
||||
for name2, (i2, sh2) in m.items():
|
||||
if name == name2:
|
||||
assert i1 == i2
|
||||
continue
|
||||
if i2 <= i1:
|
||||
# Remove the upper diagonal
|
||||
continue
|
||||
head = name.split('/', 2)[1]
|
||||
head2 = name2.split('/', 2)[1]
|
||||
if head == head2:
|
||||
# Do not test into subassemblies
|
||||
continue
|
||||
|
||||
isect = sh1.intersect(sh2)
|
||||
vol = isect.Volume()
|
||||
if vol > tol:
|
||||
return isect
|
||||
return None
|
||||
|
||||
def pairwise_intersection(assembly: Cq.Assembly, tol: float=1e-6) -> list[(str, str, float)]:
|
||||
"""
|
||||
|
|
|
@ -218,6 +218,7 @@ class TorsionJoint:
|
|||
assert self.radius_rider > self.groove_radius_outer > self.groove_radius_inner + self.groove_inner_gap
|
||||
assert self.groove_radius_inner > self.spring.radius > self.radius_axle
|
||||
assert self.spring.height > self.groove_depth, "Groove is too deep"
|
||||
assert self.groove_depth < self.spring.height - self.spring.thickness * 2
|
||||
|
||||
@property
|
||||
def total_height(self):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import unittest
|
||||
import cadquery as Cq
|
||||
from nhf.checks import binary_intersection, pairwise_intersection
|
||||
from nhf.parts import joints, handle, metric_threads
|
||||
from nhf.parts import joints, handle, metric_threads, springs
|
||||
|
||||
class TestJoints(unittest.TestCase):
|
||||
|
||||
|
@ -36,7 +36,7 @@ class TestJoints(unittest.TestCase):
|
|||
with self.subTest(slot=slot, right_handed=False):
|
||||
self.torsion_joint_case(j, slot)
|
||||
def test_torsion_joint_right_handed(self):
|
||||
j = joints.TorsionJoint(right_handed=True)
|
||||
j = joints.TorsionJoint(springs.TorsionSpring(right_handed=True))
|
||||
for slot in range(j.rider_n_slots):
|
||||
with self.subTest(slot=slot, right_handed=True):
|
||||
self.torsion_joint_case(j, slot)
|
||||
|
|
|
@ -18,6 +18,7 @@ class ShoulderJoint(Model):
|
|||
torsion_joint: TorsionJoint = field(default_factory=lambda: TorsionJoint(
|
||||
radius_track=18,
|
||||
radius_rider=18,
|
||||
groove_depth=4.8,
|
||||
groove_radius_outer=16,
|
||||
groove_radius_inner=13,
|
||||
track_disk_height=5.0,
|
||||
|
|
|
@ -6,6 +6,10 @@ from nhf.checks import pairwise_intersection
|
|||
|
||||
class TestJoints(unittest.TestCase):
|
||||
|
||||
def test_shoulder_collision_of_torsion_joint(self):
|
||||
j = MJ.ShoulderJoint()
|
||||
assembly = j.torsion_joint.rider_track_assembly()
|
||||
self.assertEqual(pairwise_intersection(assembly), [])
|
||||
def test_shoulder_collision_0(self):
|
||||
j = MJ.ShoulderJoint()
|
||||
assembly = j.assembly()
|
||||
|
|
Loading…
Reference in New Issue