-
Notifications
You must be signed in to change notification settings - Fork 12
/
main.go
119 lines (100 loc) · 2.72 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"log"
"math"
"github.com/unixpickle/model3d/render3d"
"github.com/unixpickle/model3d/toolbox3d"
"github.com/unixpickle/model3d/model3d"
)
const (
NotchSize = 0.05
TubeThickness = 0.1
BottomNotchZ = 0.5
OuterRadius = 0.7
OuterHeight = 3.0
GapRadius = TubeThickness + NotchSize*1.5
GapHeight = NotchSize * 2
NumTubes = 3
)
func main() {
radius := OuterRadius
height := OuterHeight
tubes := model3d.JoinedSolid{
// Outer tube.
&Tube{
Radius: radius,
Height: height,
InnerNotches: []float64{height - NotchSize},
},
}
// Create tubes going inward.
for i := 0; i < NumTubes-1; i++ {
radius -= GapRadius
height += GapHeight
tubes = append(tubes, &Tube{
Radius: radius,
Height: height,
// The notch at 0.0 makes things jiggle less, and
// makes the print have more surface area to stick
// to the build plate.
OuterNotches: []float64{0.0, BottomNotchZ, height - NotchSize},
InnerNotches: []float64{height - NotchSize},
})
}
log.Println("Creating mesh...")
ax := &toolbox3d.AxisSqueeze{
Axis: toolbox3d.AxisZ,
Min: BottomNotchZ + NotchSize*2 + 0.1,
Max: OuterHeight - NotchSize*2 - 0.1,
Ratio: 0.1,
}
mesh := model3d.MarchingCubesSearch(model3d.TransformSolid(ax, tubes), 0.01, 16)
mesh = mesh.MapCoords(ax.Inverse().Apply)
log.Println("Simplifying mesh...")
mesh = mesh.EliminateCoplanar(1e-5)
log.Println("Saving mesh...")
mesh.SaveGroupedSTL("telescoping.stl")
log.Println("Rendering...")
render3d.SaveRandomGrid("rendering.png", mesh, 3, 3, 300, nil)
}
type Tube struct {
Radius float64
Height float64
InnerNotches []float64
OuterNotches []float64
}
func (t *Tube) Min() model3d.Coord3D {
mx := -(t.Radius + TubeThickness/2 + NotchSize)
return model3d.XY(mx, mx)
}
func (t *Tube) Max() model3d.Coord3D {
mx := t.Radius + TubeThickness/2 + NotchSize
return model3d.XYZ(mx, mx, t.Height)
}
func (t *Tube) Contains(c model3d.Coord3D) bool {
if !model3d.InBounds(t, c) {
return false
}
cRadius := c.XY().Norm()
// Fast path for most of the volume.
if cRadius < (t.Radius - TubeThickness/2 - NotchSize) {
return false
} else if cRadius > (t.Radius + TubeThickness/2 + NotchSize) {
return false
}
minRadius := t.Radius - TubeThickness/2
maxRadius := t.Radius + TubeThickness/2
for _, notchZ := range t.InnerNotches {
extraRadius := NotchSize - math.Abs(c.Z-notchZ)
if extraRadius > 0 {
minRadius = math.Min(minRadius, t.Radius-TubeThickness/2-extraRadius)
}
}
for _, notchZ := range t.OuterNotches {
extraRadius := NotchSize - math.Abs(c.Z-notchZ)
if extraRadius > 0 {
maxRadius = math.Max(maxRadius, t.Radius+TubeThickness/2+extraRadius)
}
}
return cRadius >= minRadius && cRadius <= maxRadius
}