Cleanup dovetail geometry
This commit is contained in:
parent
e1893d139f
commit
0991b39d8a
|
@ -1,10 +1,17 @@
|
|||
import math
|
||||
from dataclasses import dataclass, field
|
||||
import cadquery as Cq
|
||||
from nhf import Material, Role
|
||||
from nhf.build import Model, target, assembly, TargetKind
|
||||
import nhf.utils
|
||||
|
||||
import math
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
import cadquery as Cq
|
||||
|
||||
class AttachPoint(Enum):
|
||||
DOVETAIL_IN = 1
|
||||
DOVETAIL_OUT = 2
|
||||
NONE = 3
|
||||
|
||||
@dataclass
|
||||
class Crown(Model):
|
||||
|
||||
|
@ -24,6 +31,7 @@ class Crown(Model):
|
|||
side_guard_channel_height: float = 10
|
||||
side_guard_hole_height: float = 15.0
|
||||
side_guard_hole_diam: float = 1.5
|
||||
side_guard_dovetail_height: float = 30.0
|
||||
|
||||
material: Material = Material.METAL_BRASS
|
||||
material_side: Material = Material.PLASTIC_PLA
|
||||
|
@ -365,36 +373,36 @@ class Crown(Model):
|
|||
dx = self.side_guard_thickness / 2
|
||||
wire = Cq.Wire.makePolygon([
|
||||
(dx * 0.5, 0),
|
||||
(dx * 0.8, dx),
|
||||
(-dx * 0.8, dx),
|
||||
(dx * 0.7, dx),
|
||||
(-dx * 0.7, dx),
|
||||
(-dx * 0.5, 0),
|
||||
], close=True)
|
||||
return Cq.Solid.extrudeLinear(
|
||||
wire,
|
||||
[],
|
||||
(0,0,self.height/3),
|
||||
)
|
||||
(0,0,dx + self.side_guard_dovetail_height),
|
||||
).moved((0, 0, -dx))
|
||||
|
||||
def side_guard(self, attach_left: bool = True, attach_right: bool = False) -> Cq.Workplane:
|
||||
def side_guard(self, attach_left: AttachPoint, attach_right: AttachPoint) -> Cq.Workplane:
|
||||
"""
|
||||
Constructs the side guard using a cone. Via Gauss's Theorema Egregium,
|
||||
the surface of the cone can be deformed into a plane.
|
||||
"""
|
||||
angle = 360 / 5
|
||||
angle_span = 360 / 5
|
||||
outer = Cq.Solid.makeCone(
|
||||
radius1=self.radius_lower + self.side_guard_thickness,
|
||||
radius2=self.radius_upper + self.side_guard_thickness,
|
||||
height=self.height,
|
||||
angleDegrees=angle,
|
||||
angleDegrees=angle_span,
|
||||
)
|
||||
inner = Cq.Solid.makeCone(
|
||||
radius1=self.radius_lower,
|
||||
radius2=self.radius_upper,
|
||||
height=self.height,
|
||||
angleDegrees=angle,
|
||||
angleDegrees=angle_span,
|
||||
)
|
||||
shell = (outer - inner).rotate((0,0,0), (0,0,1), -angle/2)
|
||||
dx = math.sin(math.radians(angle / 2)) * (self.radius_middle + self.side_guard_thickness)
|
||||
shell = (outer - inner).rotate((0,0,0), (0,0,1), -angle_span/2)
|
||||
dx = math.sin(math.radians(angle_span / 2)) * (self.radius_middle + self.side_guard_thickness)
|
||||
profile = (
|
||||
Cq.Workplane('YZ')
|
||||
.polyline([
|
||||
|
@ -408,16 +416,16 @@ class Crown(Model):
|
|||
.extrude(self.radius_upper + self.side_guard_thickness)
|
||||
.val()
|
||||
)
|
||||
channel = (
|
||||
Cq.Solid.makeCylinder(
|
||||
radius=self.side_guard_channel_radius + 1.0,
|
||||
height=self.side_guard_channel_height,
|
||||
) - Cq.Solid.makeCylinder(
|
||||
radius=self.side_guard_channel_radius,
|
||||
height=self.side_guard_channel_height,
|
||||
)
|
||||
)
|
||||
result = shell * profile - channel
|
||||
#channel = (
|
||||
# Cq.Solid.makeCylinder(
|
||||
# radius=self.side_guard_channel_radius + 1.0,
|
||||
# height=self.side_guard_channel_height,
|
||||
# ) - Cq.Solid.makeCylinder(
|
||||
# radius=self.side_guard_channel_radius,
|
||||
# height=self.side_guard_channel_height,
|
||||
# )
|
||||
#)
|
||||
result = shell * profile# - channel
|
||||
for i in [-2, -1, 0, 1, 2]:
|
||||
phi = i * (math.pi / 14)
|
||||
hole = Cq.Solid.makeCylinder(
|
||||
|
@ -431,10 +439,45 @@ class Crown(Model):
|
|||
radius_attach = self.radius_lower + self.side_guard_thickness / 2
|
||||
# tilt the dovetail by radius differential
|
||||
angle_tilt = math.degrees(math.atan2(self.radius_middle - self.radius_lower, self.height / 2))
|
||||
print(angle_tilt)
|
||||
dovetail = self.side_guard_dovetail()
|
||||
loc_dovetail = Cq.Location.rot2d(angle / 2) * Cq.Location(radius_attach, 0, 0, 0, angle_tilt, 0) * Cq.Location.rot2d(180)
|
||||
return result - dovetail.moved(loc_dovetail)
|
||||
loc_dovetail_left = Cq.Location.rot2d(angle_span / 2) * Cq.Location(radius_attach, 0, 0, 0, angle_tilt, 0)
|
||||
loc_dovetail_right = Cq.Location.rot2d(-angle_span / 2) * Cq.Location(radius_attach, 0, 0, 0, angle_tilt, 0)
|
||||
|
||||
match attach_left:
|
||||
case AttachPoint.DOVETAIL_IN:
|
||||
loc_dovetail_left *= Cq.Location.rot2d(180)
|
||||
result = result - dovetail.moved(loc_dovetail_left)
|
||||
case AttachPoint.DOVETAIL_OUT:
|
||||
result = result + dovetail.moved(loc_dovetail_left)
|
||||
case AttachPoint.NONE:
|
||||
pass
|
||||
match attach_right:
|
||||
case AttachPoint.DOVETAIL_IN:
|
||||
result = result - dovetail.moved(loc_dovetail_right)
|
||||
case AttachPoint.DOVETAIL_OUT:
|
||||
loc_dovetail_right *= Cq.Location.rot2d(180)
|
||||
result = result + dovetail.moved(loc_dovetail_right)
|
||||
case AttachPoint.NONE:
|
||||
pass
|
||||
# Remove parts below the horizontal
|
||||
cut_h = self.radius_lower
|
||||
result -= Cq.Solid.makeCylinder(
|
||||
radius=self.radius_lower + self.side_guard_thickness,
|
||||
height=cut_h).moved((0,0,-cut_h))
|
||||
return result
|
||||
|
||||
@target(name="side_guard_2")
|
||||
def side_guard_2(self) -> Cq.Workplane:
|
||||
return self.side_guard(
|
||||
attach_left=AttachPoint.DOVETAIL_OUT,
|
||||
attach_right=AttachPoint.DOVETAIL_IN,
|
||||
)
|
||||
@target(name="side_guard_3")
|
||||
def side_guard_3(self) -> Cq.Workplane:
|
||||
return self.side_guard(
|
||||
attach_left=AttachPoint.DOVETAIL_IN,
|
||||
attach_right=AttachPoint.DOVETAIL_IN,
|
||||
)
|
||||
|
||||
def front_surrogate(self) -> Cq.Workplane:
|
||||
"""
|
||||
|
@ -478,7 +521,7 @@ class Crown(Model):
|
|||
"""
|
||||
New assembly using conformal mapping on the cone.
|
||||
"""
|
||||
side_guard = self.side_guard()
|
||||
side_guard = self.side_guard_2()
|
||||
a = Cq.Assembly()
|
||||
for i in range(1,5):
|
||||
a = a.addS(
|
||||
|
|
Loading…
Reference in New Issue