diff --git a/nhf/touhou/houjuu_nue/joints.py b/nhf/touhou/houjuu_nue/joints.py index 8411313..e9951ec 100644 --- a/nhf/touhou/houjuu_nue/joints.py +++ b/nhf/touhou/houjuu_nue/joints.py @@ -63,6 +63,7 @@ class ShoulderJoint(Model): axis_rotate_top: float = -225.0 directrix_id: int = 0 + angle_neutral: float = 10.0 def __post_init__(self): assert self.parent_lip_length * 2 < self.height @@ -189,8 +190,8 @@ class ShoulderJoint(Model): ) theta = self.torsion_joint.spring.angle_neutral - self.torsion_joint.rider_slot_span loc_rotate = Cq.Location((0, 0, 0), (1, 0, 0), 180) - loc_axis_rotate_bot = Cq.Location((0, 0, 0), (0, 0, 1), self.axis_rotate_bot) - loc_axis_rotate_top = Cq.Location((0, 0, 0), (0, 0, 1), self.axis_rotate_top) + loc_axis_rotate_bot = Cq.Location((0, 0, 0), (0, 0, 1), self.axis_rotate_bot + self.angle_neutral) + loc_axis_rotate_top = Cq.Location((0, 0, 0), (0, 0, 1), self.axis_rotate_top + self.angle_neutral) result = ( Cq.Assembly() .add(core, name="core", loc=Cq.Location()) diff --git a/nhf/touhou/houjuu_nue/wing.py b/nhf/touhou/houjuu_nue/wing.py index b029bec..e21edf2 100644 --- a/nhf/touhou/houjuu_nue/wing.py +++ b/nhf/touhou/houjuu_nue/wing.py @@ -93,6 +93,8 @@ class WingProfile(Model): self.wrist_s = math.sin(self.wrist_theta) self.wrist_top_x, self.wrist_top_y = self.wrist_to_abs(0, self.wrist_height) + self.shoulder_joint.angle_neutral = -self.shoulder_angle_neutral + @submodel(name="shoulder-joint") def submodel_shoulder_joint(self) -> Model: return self.shoulder_joint @@ -180,6 +182,17 @@ class WingProfile(Model): #) ) + @property + def shoulder_angle_neutral(self) -> float: + """ + Returns the neutral angle of the shoulder + """ + dx = self.shoulder_mid_x - self.shoulder_tip_x + dy = -(self.shoulder_mid_y - (self.shoulder_tip_y - self.shoulder_width)) + result = math.degrees(math.atan2(dy, dx)) + assert result >= 0 + return result + @target(name="profile-s0", kind=TargetKind.DXF) def profile_s0(self) -> Cq.Sketch: tip_x = self.shoulder_tip_x @@ -270,10 +283,17 @@ class WingProfile(Model): def surface_s0(self, top: bool = False) -> Cq.Workplane: base_dx = -(self.base_width - self.base_plate_width) / 2 base_dy = self.base_joint.joint_height + sw = self.shoulder_width axle_dist = self.shoulder_joint.parent_lip_ext + theta = math.radians(self.shoulder_joint.angle_neutral) + c, s = math.cos(-theta), math.sin(-theta) tags = [ - ("shoulder", (self.shoulder_tip_x + axle_dist, self.shoulder_tip_y - self.shoulder_width), 0), + # transforms [axle_dist, -sw/2] about the centre (tip_x, tip_y - sw/2) + ("shoulder", ( + self.shoulder_tip_x + axle_dist * c + (-sw/2) * s, + self.shoulder_tip_y - sw / 2 - axle_dist * s + (-sw/2) * c), + self.shoulder_joint.angle_neutral), ("base", (base_dx, base_dy), 90), ] result = nhf.utils.extrude_with_markers(