mirror of
https://github.com/Theaninova/Brick-Monorail.git
synced 2026-07-27 07:14:41 +00:00
99 lines
3.0 KiB
Python
99 lines
3.0 KiB
Python
import cadquery as cq
|
|
from params import Params
|
|
import math
|
|
import units as u
|
|
|
|
|
|
def tooth(params: Params, plane: cq.Plane):
|
|
return (
|
|
cq.Workplane(plane)
|
|
.box(params.teeth_width, params.teeth_outer_width, params.teeth_height)
|
|
.edges("|Z")
|
|
.chamfer(
|
|
(params.teeth_outer_width - params.teeth_inner_width) / 2,
|
|
params.teeth_width / 3,
|
|
)
|
|
)
|
|
|
|
|
|
def rail_teeth(params: Params, path: cq.Wire):
|
|
path_wire_length = path.Length()
|
|
teeth_count = math.floor(path_wire_length / params.teeth_spacing)
|
|
t0 = path.tangentAt(0)
|
|
z = params.height - params.tolerance + params.teeth_height / 2
|
|
|
|
workplane = (
|
|
cq.Workplane(cq.Plane(path.positionAt(0), -t0.cross(cq.Vector(0, 0, 1)), t0))
|
|
.center(0, z)
|
|
.rect(params.teeth_inner_width, params.teeth_height)
|
|
.sweep(path)
|
|
)
|
|
|
|
for d in [0, 1]:
|
|
workplane = workplane - (
|
|
cq.Workplane(
|
|
cq.Plane(
|
|
path.positionAt(d) + cq.Vector(0, 0, z),
|
|
path.tangentAt(d),
|
|
),
|
|
).box(params.tolerance * 2, params.teeth_outer_width, params.teeth_height)
|
|
)
|
|
|
|
for i in range(1, teeth_count + 1):
|
|
d = (i - 0.5) / (teeth_count)
|
|
workplane = workplane.add(
|
|
tooth(
|
|
params,
|
|
cq.Plane(
|
|
path.positionAt(d) + cq.Vector(0, 0, z),
|
|
path.tangentAt(d),
|
|
),
|
|
)
|
|
)
|
|
|
|
return workplane.combine()
|
|
|
|
|
|
def compliant_teeth(params: Params, length: float):
|
|
teeth_count = math.floor(length / params.teeth_spacing)
|
|
actual_spacing = length / teeth_count
|
|
z = params.height - params.tolerance
|
|
solid_width = u.ldu(1)
|
|
nozzle_diameter = 0.4
|
|
layer_height = u.ldu(0.5)
|
|
layer_count = math.floor(params.teeth_height / layer_height)
|
|
|
|
workplane = (
|
|
cq.Workplane("XY")
|
|
.pushPoints(
|
|
[
|
|
(0, length * ((i - 0.5) / teeth_count), z + params.teeth_height / 2)
|
|
for i in range(1, teeth_count + 1)
|
|
]
|
|
)
|
|
.box(params.teeth_outer_width, solid_width, params.teeth_height)
|
|
)
|
|
|
|
side_length = math.sqrt(
|
|
(actual_spacing - solid_width * 1.8) ** 2 + params.teeth_outer_width**2
|
|
)
|
|
angle = math.atan2(params.teeth_outer_width, actual_spacing - solid_width * 1.8)
|
|
direction = cq.Vector(math.sin(angle), math.cos(angle), 0)
|
|
direction_b = cq.Vector(math.sin(angle), -math.cos(angle), 0)
|
|
|
|
for i in range(1, teeth_count):
|
|
for j in range(layer_count):
|
|
workplane.add(
|
|
cq.Workplane(
|
|
cq.Plane(
|
|
cq.Vector(
|
|
0, length * i / teeth_count, z + (j + 0.5) * layer_height
|
|
),
|
|
direction if j % 2 == 0 else direction_b,
|
|
cq.Vector(0, 0, 1),
|
|
)
|
|
).box(side_length, nozzle_diameter, layer_height)
|
|
)
|
|
|
|
return workplane.combine()
|