Compare commits

...

1 Commits

Author SHA1 Message Date
c6e7b4111b more gears
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-11 17:35:50 -07:00
9 changed files with 23879 additions and 0 deletions

View File

@ -0,0 +1,129 @@
// Set Units
@settings(defaultLengthUnit = mm)
fn inv(angle: number(rad)) {
tanResult = tan(angle): number(rad)
return tanResult - angle
}
nTeeth = 32
module = 2.0
pressureAngle = 20deg
profileShift = 0
gearHeight = 10
shaftHeight = 10
shaftOuterRadius = 7
shaftInnerRadius = 4
nCutout = 5
cutoutAngle = 360 / nCutout
pitchDiameter = module * nTeeth
baseDiameter = pitchDiameter * cos(pressureAngle)
fn gear(nTeeth, module, pressureAngle, profileShift) {
// Define constants
pitchAngle = (2 * PI / nTeeth): number(rad)
pitchDiameter = module * nTeeth
baseDiameter = pitchDiameter * cos(pressureAngle)
baseToPitchAngle = sqrt(pitchDiameter * pitchDiameter - (baseDiameter * baseDiameter)) / baseDiameter - acos(baseDiameter / pitchDiameter)
toothPitch = 360 / nTeeth
tipDiameter = module * (nTeeth + 2)
pitchThickness = module * (0.5 * PI + 2 * profileShift * tan(pressureAngle))
fn toothThickness(radius) {
operatingPressureAngle = acos(pitchDiameter / radius * cos(pressureAngle)): number(deg)
return radius * (pitchThickness / pitchDiameter + inv(angle = pressureAngle) - inv(angle = operatingPressureAngle))
}
tipThickness = toothThickness(radius = tipDiameter): number(rad)
baseThickness = toothThickness(radius = baseDiameter): number(rad)
tipAngle = (tipThickness / tipDiameter): number(deg)
baseAngle = (2 * baseThickness / baseDiameter): number(deg)
toothAngle = 360 / nTeeth / 1.5
fn tooth(i, sg) {
leftAngle = (-baseToPitchAngle - (pitchAngle / 4) + i * toothPitch): number(rad)
rightAngle = (-baseToPitchAngle - (pitchAngle / 4) - (i * toothPitch)): number(rad)
startProfile = involuteCircular(
startRadius = 0.5 * baseDiameter,
endRadius = 0.5 * tipDiameter,
angle = leftAngle: number(deg),
tag = $leftInv,
)
angleMath = atan2(y = lastSegY(startProfile), x = lastSegX(startProfile)): number(rad): number(deg)
return arc(startProfile, endAbsolute = polar(angle = -angleMath + i * toothPitch, length = 0.5 * tipDiameter), interiorAbsolute = polar(angle = i * toothPitch, length = 0.5 * tipDiameter))
|> involuteCircular(
startRadius = 0.5 * baseDiameter,
endRadius = 0.5 * pitchDiameter + module,
angle = rightAngle: number(deg),
reverse = true,
)
|> arc(endAbsolute = polar(angle = -0.5 * baseAngle + (i + 1) * toothPitch, length = 0.5 * baseDiameter), interiorAbsolute = polar(angle = 0.5 * (i + 1) * toothPitch, length = 0.5 * baseDiameter))
}
return startSketchOn(XY)
|> startProfile(at = polar(angle = -0.5 * baseAngle, length = 0.5 * baseDiameter), %)
|> tooth(i = 0, sg = 0)
|> patternCircular2d(
instances = nTeeth,
center = [0, 0],
arcDegrees = 360,
rotateDuplicates = true,
)
}
g = gear(
nTeeth = nTeeth,
module = module,
pressureAngle = pressureAngle,
profileShift = profileShift,
)
|> close()
g2 = gear(
nTeeth = nTeeth,
module = module,
pressureAngle = pressureAngle,
profileShift = profileShift,
)
|> rotate(angle = -2 * 360 / nTeeth, axis = [0, 0, 1])
|> close()
|> translate(x = 0, y = 0, z = gearHeight)
// g3 = gear(nTeeth, module, pressureAngle, profileShift)
// |> close()
// |> translate(translate = [0, 0, gearHeight])
ll = loft([g, g2], vDegree = 1)
// ll = extrude(g, length = gearHeight)
base = startSketchOn(ll, face = END)
|> circle(center = [0, 0], radius = 0.5 * baseDiameter - 5)
|> extrude(length = -0.3 * gearHeight)
startSketchOn(ll, face = START)
|> circle(center = [0, 0], radius = 0.5 * baseDiameter - 5)
|> extrude(length = -0.3 * gearHeight)
sketch001 = startSketchOn(base, face = START)
|> circle(center = [0, 0], radius = shaftOuterRadius)
|> extrude(length = shaftHeight)
sketch002 = startSketchOn(sketch001, face = END)
|> circle(center = [0, 0], radius = shaftInnerRadius)
|> extrude(length = -shaftHeight - 4)
sketch003 = startSketchOn(base, face = START)
profile001 = startProfile(sketch003, at = polar(angle = -0.5 * cutoutAngle + 10, length = 10))
|> arc(interiorAbsolute = polar(angle = 0, length = 10), endAbsolute = polar(angle = 0.5 * cutoutAngle - 10, length = 10))
|> line(endAbsolute = polar(angle = 0.5 * cutoutAngle - 10, length = 0.5 * baseDiameter - 7), tag = $seg01)
|> arc(interiorAbsolute = polar(angle = 0, length = 0.5 * baseDiameter - 7), endAbsolute = polar(angle = -0.5 * cutoutAngle + 10, length = 0.5 * baseDiameter - 7))
|> close()
|> patternCircular2d(
instances = nCutout,
center = [0, 0],
arcDegrees = 360,
rotateDuplicates = true,
)
|> extrude(length = -0.4 * gearHeight)

View File

@ -0,0 +1,199 @@
// Set Units
@settings(defaultLengthUnit = mm)
fn involute(radius, angle) {
return [
radius * (cos(angle) + angle * sin(angle)),
radius * (sin(angle) - (angle * cos(angle)))
]
}
fn rot(point, angle) {
return [
point[0] * cos(angle) - (point[1] * sin(angle)),
point[0] * sin(angle) + point[1] * cos(angle)
]
}
fn cartesian(radius, angle) {
return [
radius * cos(angle),
radius * sin(angle)
]
}
fn circleInterior(point1, point2, radius, first) {
x1 = point1[0]
x2 = point2[0]
y1 = point1[1]
y2 = point2[1]
dist = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
x = 0.5 * (x1 + x2)
y = 0.5 * (y1 + y2)
excessLength = sqrt(radius * radius - (dist / 2 * dist / 2))
return if first {
[
x - ((radius - excessLength) * (y1 - y2) / dist),
y - ((radius - excessLength) * (x2 - x1) / dist)
]
} else {
[
x + (radius - excessLength) * (y1 - y2) / dist,
y + (radius - excessLength) * (x2 - x1) / dist
]
}
}
fn circleInteriorSketch(sketch, point2, radius, first) {
x1 = lastSegX(sketch)
x2 = point2[0]
y1 = lastSegY(sketch)
y2 = point2[1]
dist = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
x = 0.5 * (x1 + x2)
y = 0.5 * (y1 + y2)
excessLength = sqrt(radius * radius - (dist / 2 * dist / 2))
return if first {
[
x - ((radius - excessLength) * (y1 - y2) / dist),
y - ((radius - excessLength) * (x2 - x1) / dist)
]
} else {
[
x + (radius - excessLength) * (y1 - y2) / dist,
y + (radius - excessLength) * (x2 - x1) / dist
]
}
}
fn invPolar(baseRadius, R) {
return sqrt(R * R - (baseRadius * baseRadius)) / baseRadius - acos(baseRadius / R)
}
nTeeth = 52
module = 5.0
pressureAngle = 20
gearHeight = 15
fn gearTooth(nTeeth, module, pressureAngle, profileShift) {
addendum = 0.6 * module
dedendum = 1.25 * module
clearance = 0.25 * module
pitchRadius = 0.5 * module * nTeeth
baseRadius = pitchRadius * cos(toRadians(pressureAngle))
addendumRadius = pitchRadius - addendum
rootRadius = pitchRadius + dedendum
fRad = 1.5 * clearance
pitchAngle = 2 * PI / nTeeth: number(rad)
filletRadius = rootRadius - clearance
baseToPitchAngle = invPolar(baseRadius, pitchRadius): number(rad)
filletAngle = 1.414 * clearance / filletRadius: number(rad)
tipToPitchAngle = if addendumRadius > baseRadius {
baseToPitchAngle - invPolar(baseRadius, addendumRadius)
} else {
baseToPitchAngle
}: number(rad)
pitchToFilletAngle = invPolar(baseRadius, filletRadius) - baseToPitchAngle: number(rad)
leftAngle = toDegrees(-baseToPitchAngle + pitchAngle / 4)
Ra = pitchRadius + module
invol = rot( involute(baseRadius, sqrt(Ra * Ra - (baseRadius * baseRadius)) / baseRadius), -baseToPitchAngle + pitchAngle / 4)
tip = cartesian(addendumRadius, -pitchAngle / 4 + tipToPitchAngle)
tipR = [tip[0], -tip[1]]
fillet = [invol[0], -invol[1]]
involuteStart = cartesian(baseRadius, -baseToPitchAngle + pitchAngle / 4)
fillet2 = if addendumRadius > baseRadius {
[
invol[0] - (baseRadius * cos(toRadians(leftAngle))) + tip[0],
-invol[1] + baseRadius * sin(toRadians(leftAngle)) + tip[1]
]
} else {
[
invol[0] - (baseRadius * cos(toRadians(leftAngle))) + involuteStart[0],
-invol[1] - (baseRadius * sin(toRadians(leftAngle))) + involuteStart[1]
]
}
filletNext = rot(fillet2, pitchAngle)
rootR = cartesian(rootRadius, pitchAngle / 4 + pitchToFilletAngle + filletAngle)
rootNext = cartesian(rootRadius, 3 * pitchAngle / 4 - pitchToFilletAngle - filletAngle)
tipInterior = circleInterior(tip, tipR, addendumRadius, true)
sketch = startSketchOn(XY)
|> startProfileAt(fillet2, %)
|> involuteCircular(
startRadius = baseRadius,
endRadius = pitchRadius + module,
angle = leftAngle,
reverse = true,
)
// |> line(endAbsolute = tip)
newSketch = if addendumRadius < baseRadius {
line(sketch, endAbsolute = tip)
} else {
sketch
}
// newSketch = sketch
|> arc(endAbsolute = tipR, interiorAbsolute = circleInteriorSketch(%, tipR, addendumRadius, true))
newnewSketch = if addendumRadius < baseRadius {
line(newSketch, endAbsolute = rot([baseRadius, 0], pitchAngle / 4 - baseToPitchAngle))
} else {
newSketch
}
|> involuteCircular(
%,
startRadius = baseRadius,
endRadius = pitchRadius + module,
angle = leftAngle,
)
newnewnewSketch = if rootR[1] > rootNext[1] {
rootInterior = circleInteriorSketch(newnewSketch, rootR, fRad, true)
arc(newnewSketch, endAbsolute = rootR, interiorAbsolute = rootInterior)
|> arc(endAbsolute = rootNext, interiorAbsolute = circleInteriorSketch(%, rootNext, rootRadius, true))
} else {
newnewSketch
}
nextP = circleInteriorSketch(newnewnewSketch, filletNext, fRad, true)
// h = startSketchOn(XY)
// |> startProfileAt(tip, %)
// |> involuteCircular(
// %,
// startRadius = baseRadius,
// endRadius = pitchRadius + module,
// angle = leftAngle,
// reverse = false
// )
// |> line(endAbsolute = fillet2)
return arc(newnewnewSketch, endAbsolute = filletNext, interiorAbsolute = nextP)
}
g = gearTooth(nTeeth, module, pressureAngle, 0)
|> patternCircular2d(
instances = nTeeth,
center = [0, 0],
arcDegrees = 360,
rotateDuplicates = true,
)
gg = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> circle(center = profileStart(%), radius = 0.5 * module * nTeeth + module + 10)
|> hole(g, %)
|> extrude(length = gearHeight)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart helical-gear.kcl
extension: md
snapshot_kind: binary
---

View File

@ -0,0 +1,279 @@
```mermaid
flowchart LR
subgraph path8 [Path]
8["Path<br>[2601, 2683, 0]"]
15["Segment<br>[1656, 1843, 0]"]
16["Segment<br>[1968, 2149, 0]"]
17["Segment<br>[2159, 2358, 0]"]
18["Segment<br>[2368, 2561, 0]"]
19["Segment<br>[2966, 2973, 0]"]
32[Solid2d]
end
subgraph path9 [Path]
9["Path<br>[2601, 2683, 0]"]
20["Segment<br>[3132, 3139, 0]"]
35[Solid2d]
end
subgraph path10 [Path]
10["Path<br>[3426, 3482, 0]"]
21["Segment<br>[3426, 3482, 0]"]
31[Solid2d]
end
subgraph path11 [Path]
11["Path<br>[3562, 3618, 0]"]
22["Segment<br>[3562, 3618, 0]"]
29[Solid2d]
end
subgraph path12 [Path]
12["Path<br>[3712, 3762, 0]"]
23["Segment<br>[3712, 3762, 0]"]
30[Solid2d]
end
subgraph path13 [Path]
13["Path<br>[3852, 3902, 0]"]
24["Segment<br>[3852, 3902, 0]"]
34[Solid2d]
end
subgraph path14 [Path]
14["Path<br>[4003, 4084, 0]"]
25["Segment<br>[4090, 4209, 0]"]
26["Segment<br>[4215, 4319, 0]"]
27["Segment<br>[4325, 4485, 0]"]
28["Segment<br>[4491, 4498, 0]"]
33[Solid2d]
end
1["Plane<br>[2576, 2593, 0]"]
2["Plane<br>[2576, 2593, 0]"]
3["StartSketchOnFace<br>[3956, 3989, 0]"]
4["StartSketchOnFace<br>[3525, 3556, 0]"]
5["StartSketchOnFace<br>[3810, 3846, 0]"]
6["StartSketchOnFace<br>[3391, 3420, 0]"]
7["StartSketchOnFace<br>[3673, 3706, 0]"]
36["Sweep Loft<br>[3317, 3343, 0]"]
37["Sweep Extrusion<br>[3488, 3523, 0]"]
38["Sweep Extrusion<br>[3624, 3659, 0]"]
39["Sweep Extrusion<br>[3768, 3797, 0]"]
40["Sweep Extrusion<br>[3908, 3942, 0]"]
41["Sweep Extrusion<br>[4644, 4679, 0]"]
42["Sweep Extrusion<br>[4644, 4679, 0]"]
43["Sweep Extrusion<br>[4644, 4679, 0]"]
44["Sweep Extrusion<br>[4644, 4679, 0]"]
45["Sweep Extrusion<br>[4644, 4679, 0]"]
46[Wall]
47[Wall]
48[Wall]
49[Wall]
50[Wall]
51[Wall]
52[Wall]
53[Wall]
54[Wall]
55[Wall]
56[Wall]
57[Wall]
58["Cap Start"]
59["Cap Start"]
60["Cap Start"]
61["Cap End"]
62["Cap End"]
63["SweepEdge Opposite"]
64["SweepEdge Opposite"]
65["SweepEdge Opposite"]
66["SweepEdge Opposite"]
67["SweepEdge Opposite"]
68["SweepEdge Opposite"]
69["SweepEdge Opposite"]
70["SweepEdge Opposite"]
71["SweepEdge Opposite"]
72["SweepEdge Opposite"]
73["SweepEdge Opposite"]
74["SweepEdge Opposite"]
75["SweepEdge Adjacent"]
76["SweepEdge Adjacent"]
77["SweepEdge Adjacent"]
78["SweepEdge Adjacent"]
79["SweepEdge Adjacent"]
80["SweepEdge Adjacent"]
81["SweepEdge Adjacent"]
82["SweepEdge Adjacent"]
83["SweepEdge Adjacent"]
84["SweepEdge Adjacent"]
85["SweepEdge Adjacent"]
86["SweepEdge Adjacent"]
1 --- 9
2 --- 8
60 x--> 3
59 x--> 4
61 x--> 5
62 x--> 6
60 x--> 7
8 --- 15
8 --- 16
8 --- 17
8 --- 18
8 --- 19
8 --- 32
8 ---- 36
9 --- 20
9 --- 35
9 x---> 36
9 x--> 68
9 x--> 69
9 x--> 70
9 x--> 71
10 --- 21
10 --- 31
10 ---- 37
62 --- 10
11 --- 22
11 --- 29
11 ---- 38
59 --- 11
12 --- 23
12 --- 30
12 ---- 39
60 --- 12
13 --- 24
13 --- 34
13 ---- 40
61 --- 13
14 --- 25
14 --- 26
14 --- 27
14 --- 28
14 --- 33
14 ---- 41
60 --- 14
15 --- 54
15 x--> 59
15 --- 69
15 --- 82
16 --- 52
16 x--> 59
16 --- 71
16 --- 80
17 --- 51
17 x--> 59
17 --- 70
17 --- 81
18 --- 53
18 x--> 59
18 --- 68
18 --- 83
21 --- 56
21 x--> 62
21 --- 73
21 --- 85
22 --- 50
22 x--> 59
22 --- 67
22 --- 79
23 --- 55
23 x--> 60
23 --- 72
23 --- 84
24 --- 57
24 x--> 61
24 --- 74
24 --- 86
25 --- 46
25 x--> 60
25 --- 63
25 --- 78
26 --- 48
26 x--> 60
26 --- 64
26 --- 76
27 --- 47
27 x--> 60
27 --- 66
27 --- 75
28 --- 49
28 x--> 60
28 --- 65
28 --- 77
36 --- 51
36 --- 52
36 --- 53
36 --- 54
36 --- 59
36 --- 62
36 --- 68
36 --- 69
36 --- 70
36 --- 71
36 --- 80
36 --- 81
36 --- 82
36 --- 83
37 --- 56
37 --- 60
37 --- 73
37 --- 85
38 --- 50
38 --- 58
38 --- 67
38 --- 79
39 --- 55
39 --- 61
39 --- 72
39 --- 84
40 --- 57
40 --- 74
40 --- 86
41 --- 46
41 --- 47
41 --- 48
41 --- 49
41 --- 63
41 --- 64
41 --- 65
41 --- 66
41 --- 75
41 --- 76
41 --- 77
41 --- 78
63 <--x 46
77 <--x 46
78 <--x 46
66 <--x 47
75 <--x 47
76 <--x 47
64 <--x 48
76 <--x 48
78 <--x 48
65 <--x 49
75 <--x 49
77 <--x 49
67 <--x 50
79 <--x 50
70 <--x 51
81 <--x 51
83 <--x 51
71 <--x 52
80 <--x 52
81 <--x 52
68 <--x 53
83 <--x 53
69 <--x 54
80 <--x 54
82 <--x 54
72 <--x 55
84 <--x 55
73 <--x 56
85 <--x 56
74 <--x 57
86 <--x 57
63 <--x 58
64 <--x 58
65 <--x 58
66 <--x 58
67 <--x 58
74 <--x 58
73 <--x 60
72 <--x 61
68 <--x 62
69 <--x 62
70 <--x 62
71 <--x 62
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB