From 48cfd52455ed9da1b1206b73beb040ba478f5092 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Tue, 9 Jul 2024 19:57:54 -0700 Subject: [PATCH] refactor: Wing profile class --- nhf/touhou/houjuu_nue/__init__.py | 77 ++++++++++++++++++++----------- nhf/touhou/houjuu_nue/wing.py | 77 +++++++++++++++++++------------ 2 files changed, 97 insertions(+), 57 deletions(-) diff --git a/nhf/touhou/houjuu_nue/__init__.py b/nhf/touhou/houjuu_nue/__init__.py index 774be88..64c248b 100644 --- a/nhf/touhou/houjuu_nue/__init__.py +++ b/nhf/touhou/houjuu_nue/__init__.py @@ -87,6 +87,11 @@ class Parameters(Model): hs_joint_axis_cbore_diam: float = 20 hs_joint_axis_cbore_depth: float = 3 + wing_profile: MW.WingProfile = field(default_factory=lambda: MW.WingProfile( + shoulder_height = 100, + elbow_height = 120, + )) + # Exterior radius of the wing root assembly wing_root_radius: float = 40 wing_root_wall_thickness: float = 8 @@ -347,6 +352,15 @@ class Parameters(Model): result.moveTo(0, self.shoulder_attach_dist).tagPlane('conn1') return result + @property + def shoulder_joint_child_height(self) -> float: + """ + Calculates the y distance between two joint surfaces on the child side + of the shoulder joint. + """ + joint = self.shoulder_torsion_joint + return self.wing_s0_height - 2 * joint.total_height + 2 * joint.rider_disk_height + @target(name="shoulder_joint_child") def shoulder_joint_child(self) -> Cq.Assembly: """ @@ -470,18 +484,18 @@ class Parameters(Model): .finalize() .extrude(self.wing_s1_spacer_thickness) ) - result.faces("Z").tag("mate2") + result.faces("Z").tag("weld2") result.faces(">Y").tag("dir") return result @target(name="wing/s1-shoulder-spacer", kind=TargetKind.DXF) - def wing_s1_shoulder_spacer(self, flipped=False) -> Cq.Workplane: + def wing_s1_shoulder_spacer(self) -> Cq.Workplane: """ - if `flipped = True`, tag on the bottom face. This does not change the - geometry. + The mate tags are on the side closer to the holes. """ dx = self.wing_s1_shoulder_spacer_hole_dist + h = self.wing_s1_spacer_thickness result = ( Cq.Workplane('XZ') .sketch() @@ -493,33 +507,35 @@ class Parameters(Model): ]) .circle(self.wing_s1_spacer_hole_diam / 2, mode='s') .finalize() - .extrude(self.wing_s1_spacer_thickness) + .extrude(h) ) # Tag the mating surfaces to be glued - result.faces("Z").tag("mate2") + result.faces("Z").workplane().moveTo(0, -h).tagPlane("weld2") # Tag the directrix result.faces("Y").workplane() + plane = result.faces(">Y").workplane() # Side closer to the parent is 0 - plane.moveTo(dx if flipped else -dx, 0).tagPlane("conn0") + plane.moveTo(-dx, 0).tagPlane("conn0") plane.tagPlane("conn1") return result @target(name="wing/r1s1", kind=TargetKind.DXF) def wing_r1s1_profile(self) -> Cq.Sketch: - return MW.wing_r1s1_profile() + return self.wing_profile.wing_r1s1_profile() def wing_r1s1_panel(self, front=True) -> Cq.Workplane: profile = self.wing_r1s1_profile() + w = self.wing_s1_shoulder_spacer_width / 2 + h = (self.wing_profile.shoulder_height - self.shoulder_joint_child_height) / 2 anchors = [ - ("shoulder_top", 10, 55), - ("shoulder_bot", 10, 5), + ("shoulder_top", w, h + self.shoulder_joint_child_height), + ("shoulder_bot", w, h), ("middle", 50, -20), - ("tip", 390, -150), + ("tip", 270, 50), ] result = ( Cq.Workplane("XY") @@ -543,25 +559,30 @@ class Parameters(Model): color=self.material_panel.color) .constrain("panel_front@faces@>Z", "panel_back@faces@ Cq.Sketch: - """ - Generates the first wing segment profile, with the wing root pointing in - the positive x axis. - """ - # Depression of the wing middle - h = 100 - w = 400 - bend = 200 - factor = 0.7 - result = ( - Cq.Sketch() - .segment((0, 0), (0, h)) - .spline([ - (0, h), - (0.5 * w, h - factor * bend), - (w, h - bend), - ]) - .segment( - (w, h - bend), - (w, -bend), + +@dataclass +class WingProfile: + + shoulder_height: float = 100 + elbow_height: float = 120 + + def wing_r1s1_profile(self) -> Cq.Sketch: + """ + Generates the first wing segment profile, with the wing root pointing in + the positive x axis. + """ + + + w = 270 + # Depression of the wing middle, measured + h = 0 + # spline curve easing extension + theta = math.radians(30) + c_th, s_th = math.cos(theta), math.sin(theta) + bend = 30 + ext = 40 + ext_dh = -5 + assert ext * 2 < w + + factor = 0.7 + + result = ( + Cq.Sketch() + .segment((0, 0), (0, self.shoulder_height)) + .spline([ + (0, self.shoulder_height), + ((w - s_th * self.elbow_height) / 2, self.shoulder_height / 2 + (self.elbow_height * c_th - h) / 2 - bend), + (w - s_th * self.elbow_height, self.elbow_height * c_th - h), + ]) + .segment( + (w - s_th * self.elbow_height, self.elbow_height * c_th -h), + (w, -h), + ) + .spline([ + (0, 0), + (w / 2, -h / 2 - bend), + (w, -h), + ]) + .assemble() ) - .spline([ - (w, - bend), - (0.5 * w, - factor * bend), - (0, 0), - ]) - .assemble() - ) - return result + return result