diff --git a/knoopvoet/go.mod b/knoopvoet/go.mod new file mode 100644 index 0000000..04fb769 --- /dev/null +++ b/knoopvoet/go.mod @@ -0,0 +1,8 @@ +module knoopvoet + +go 1.16 + +require ( + git.wtrh.nl/3D-models/objects v0.0.0-20210528131644-78f3aae2fba3 + github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0 +) diff --git a/knoopvoet/go.sum b/knoopvoet/go.sum new file mode 100644 index 0000000..67a92e8 --- /dev/null +++ b/knoopvoet/go.sum @@ -0,0 +1,21 @@ +git.wtrh.nl/3D-models/objects v0.0.0-20210528131644-78f3aae2fba3 h1:drRM0nTPLRIVUwdfxCaUrEBJFDgzIxFsIttW6gGCbr8= +git.wtrh.nl/3D-models/objects v0.0.0-20210528131644-78f3aae2fba3/go.mod h1:YYSLQ70RNqjnLBLk/rimXyxYzMORHlREwok9g2ZQv/c= +github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb h1:EVl3FJLQCzSbgBezKo/1A4ADnJ4mtJZ0RvnNzDJ44nY= +github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0 h1:nCkBC+PowWnmkCMe+3cCOtxpNVw+R1TQI8hzmCmPyKI= +github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0/go.mod h1:abZaCad/jNP8KcO+XMyLX6C/cZOdnwefasReJEva4cE= +github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e h1:YRRazju3DMGuZTSWEj0nE2SCRcK3DW/qdHQ4UQx7sgs= +github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA= +github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb h1:61ndUreYSlWFeCY44JxDDkngVoI7/1MVhEl98Nm0KOk= +github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb/go.mod h1:1l8ky+Ew27CMX29uG+a2hNOKpeNYEQjjtiALiBlFQbY= +github.com/yofu/dxf v0.0.0-20190710012328-5a6d1e83f16c h1:qgsxLgTXCVH8Dxar36HI5af2ZfinVz5vF8erPpyzM+A= +github.com/yofu/dxf v0.0.0-20190710012328-5a6d1e83f16c/go.mod h1:gnT4GQzgKW8+TLI0xheUgdmNV4dsAN0WJUVnztRZkfI= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/knoopvoet/knoopvoet b/knoopvoet/knoopvoet new file mode 100755 index 0000000..a870390 Binary files /dev/null and b/knoopvoet/knoopvoet differ diff --git a/knoopvoet/knoopvoet-18mm.scad b/knoopvoet/knoopvoet-18mm.scad new file mode 100644 index 0000000..622db4b --- /dev/null +++ b/knoopvoet/knoopvoet-18mm.scad @@ -0,0 +1,16 @@ +include ; + +button_d = 18.2; +button_h = 4; +button_offset = 1; + + +outside = 2; +foot_height = button_h+button_offset-0.5; +foot_width = 15; +hole_spacing = 5; +hole_diameter = 3; +hole_clearance = hole_spacing + hole_diameter; +rim_h = 1; + +button_feet(); diff --git a/knoopvoet/knoopvoet-22mm5.scad b/knoopvoet/knoopvoet-22mm5.scad new file mode 100644 index 0000000..3587224 --- /dev/null +++ b/knoopvoet/knoopvoet-22mm5.scad @@ -0,0 +1,14 @@ +include ; + +button_d = 24.5; +button_h = 4; +button_offset = 1; + + +foot_height = button_h+button_offset-0.5; +hole_spacing = 5.5; +hole_diameter = 3; +hole_clearance = hole_spacing + hole_diameter; +rim_h = 1; + +button_feet(); diff --git a/knoopvoet/knoopvoet-multi.scad b/knoopvoet/knoopvoet-multi.scad new file mode 100644 index 0000000..e66939a --- /dev/null +++ b/knoopvoet/knoopvoet-multi.scad @@ -0,0 +1,50 @@ +include +include + +number_of_feet = 8; +small_size = 12; +step_size = 2; +size_list = [for (a = [0:(number_of_feet-1)]) small_size+step_size*a]; +small_height = 2; +step_height = 0.25; +height_list =[for (a = [0:(number_of_feet-1)]) small_height+step_height*a]; +small_hole = 6; +step_hole = 0.2; +hole_list =[for (a = [0:(number_of_feet-1)]) small_hole+step_hole*a]; + +module feet(){ +for (i = [0:7]){ + translate([36*i,0,0])//,small_size+step_size*i/2+10]) + //rotate([-90,0,-90]) + button_foot(height=height_list[i], diameter=size_list[i], hole_width = hole_list[i]); +} +} + +module storage_box() { + box=[60,30,46]; + difference(){ + translate([0,0,8]) + bottom_box(box); + translate([-7*number_of_feet/2,-15*1.1/2,-15]) + for (i = [0:7]){ + translate([7*i,0,0]) + cube([(height_list[i]+0.5)*1.1,15*1.1,16]); + if (i % 2 == 0) { + translate([7*i+2,-2,15]) + linear_extrude(height=0.4,center = true) text(text=str(floor(size_list[i])),size=6,halign="center",valign="top"); + } + } + } + //translate([0,0,60]) + // translate([0,0,8]) +//top_box(box); +} + +//rotate([90,0,0]) +storage_box(); +//rotate([90,0,0]) +//translate([-7*number_of_feet/2,0,-15]) +feet(); + + + diff --git a/knoopvoet/knoopvoet.go b/knoopvoet/knoopvoet.go new file mode 100644 index 0000000..8fddb4e --- /dev/null +++ b/knoopvoet/knoopvoet.go @@ -0,0 +1,128 @@ +package main + +import ( + "git.wtrh.nl/3D-models/objects" + "github.com/deadsy/sdfx/render" + "github.com/deadsy/sdfx/sdf" + "math" +) + +type Button struct { + Size float64 // diameter of button + Thickness float64 // height of button + HoleSpacing float64 // Broadest cross length of thread holes. + Curve float64 // Depth of the curve +} + +type DoveTail struct { + Size sdf.V3 + Angle float64 +} + +var flange_h = 1.0 +var flange_w = 2.0 +var cloth_offset = 1.0 + +var doveTail = DoveTail{ + Size: sdf.V3{X: 10, Y: 8, Z: 2}, + Angle: sdf.Pi/10, +} + +func ButtonHolder3D(b *Button) (holder sdf.SDF3, err error) { + cylinderTickness := flange_h+cloth_offset+b.Curve + holder, err = sdf.Cylinder3D(cylinderTickness,b.Size/2+flange_w,0.0) + if err != nil { + return + } + negative, err := buttonNegative(b) + if err != nil { + return + } + holder = sdf.Transform3D(holder, sdf.Translate3d(sdf.V3{0,0,cylinderTickness/2})) + negative = sdf.Transform3D(negative, sdf.Translate3d(sdf.V3{0,0,cloth_offset})) + negative2, err := wireNegative(b) + if err != nil { + return + } + negative = sdf.Union3D(negative2,negative) + holder = sdf.Difference3D(holder,negative) + return +} + +func buttonNegative(b *Button) (negative sdf.SDF3, err error) { + h := (math.Pow(b.Size/2,2)/b.Curve - b.Curve)/2 + s1, err := sdf.Sphere3D(h) + if err != nil { + return + } + s1 = sdf.Transform3D(s1, sdf.Translate3d(sdf.V3{0,0,h})) + c1, err := sdf.Cylinder3D(h,b.Size/2,0.0) + if err != nil { + return + } + c1 = sdf.Transform3D(c1, sdf.Translate3d(sdf.V3{0,0,h/2})) + negative = sdf.Intersect3D(s1,c1) + return +} + +func wireNegative(b *Button) (negative sdf.SDF3, err error) { + size := sdf.V3{X: b.HoleSpacing/2, Y: b.HoleSpacing/2, Z: 20}.MulScalar(math.Sqrt(2)) + b1, err := sdf.Box3D(size,1.5) + if err != nil { + return + } + b1 = sdf.Transform3D(b1,sdf.RotateZ(sdf.Pi/4)) + b1 = sdf.Elongate3D(b1,sdf.V3{X:b.Size,Y: 0, Z: 0}) + negative = sdf.Transform3D(b1,sdf.Translate3d(sdf.V3{-b.Size/2,0,0})) + return +} + +func dovetail(size sdf.V3, angle float64, offset float64) (tail sdf.SDF3, err error) { + tail, err = sdf.Box3D(size, 0.0) + a1 := sdf.V3{X: 0, Y: size.Y/2+offset, Z:-size.Z/2} + a2 := sdf.V3{X: 0, Y: -size.Y/2+offset, Z:-size.Z/2} + n1 := sdf.V3{Y: -math.Cos(angle), X: 0, Z: -math.Sin(angle)} + n2 := sdf.V3{Y: math.Cos(angle), X: 0, Z: -math.Sin(angle)} + tail = sdf.Cut3D(tail, a1, n1) + tail = sdf.Cut3D(tail, a2, n2) + //bottomSize := sdf.V2{X: doveTail.Size.X, Y: doveTail.Size.Y} + //b2d := sdf.Box2D(bottomSize,0) + //topSize := bottomSize.Add(sdf.V2{X:0, Y: doveTail.Size.Z * math.Tan(doveTail.Angle) * 2}) + //t2d := sdf.Box2D(topSize,0) + //tail, err = sdf.Loft3D(b2d, t2d, doveTail.Size.Z,0) + return +} + +func main() { + k := objects.BoxParams{ + Size: sdf.V3{100,100,100}, + Wall: 3, + BottomTopRatio: 1, + Margin: 0.1, + Taper: 0.1, + ClosingHeight: 4, + CornerRadius: 3, + } + box, err := objects.BottomBox3D(&k) + if err != nil { + return + } + render.RenderSTL(box, 300, "out.stl") + b := Button{ + Size: 18, + Curve: 1.2, + HoleSpacing: 8.5, + } + + holder, err := ButtonHolder3D(&b) + if err != nil { + return + } + render.RenderSTL(holder, 300, "holder.stl") + negative, err := wireNegative(&b) + if err != nil { + return + } + render.RenderSTL(negative, 300, "negative.stl") + return +} \ No newline at end of file diff --git a/knoopvoet/knoopvoet.scad b/knoopvoet/knoopvoet.scad new file mode 100644 index 0000000..e76385e --- /dev/null +++ b/knoopvoet/knoopvoet.scad @@ -0,0 +1,47 @@ +$fn = $preview ? 16 : 72; + +module button_foot(height = 4, diameter = 18, hole_width = 5) { +button_offset = 1; +foot_length = diameter/2+16; +outside = 2; +foot_height = height+button_offset; +foot_width = 15; +hole_diameter = 3; +hole_clearance = hole_width; +hole_spacing = hole_clearance - hole_diameter; +rim_h = 1; +//bottom + difference(){ + union(){ + cylinder(d=diameter+2*outside,h=foot_height); + translate([-foot_width/2,0,0]) + cube([foot_width,foot_length,foot_height]); + } + //slot + translate([-hole_clearance/2,-diameter,-1]) + cube([hole_clearance,diameter,foot_height+2]); + //button insert + translate([0,0,button_offset]) + cylinder(d=diameter,h=foot_height); + //rim + translate([-diameter/2-outside-2,-diameter,button_offset+rim_h]) + cube([diameter+2*outside+4,diameter,foot_height+2]); + //wire slots + hull(){ + translate([hole_spacing/2,0,-1]) + cylinder(d=hole_diameter*1.1,button_offset+2); + translate([-hole_spacing/2,0,-1]) + cylinder(d=hole_diameter*1.1,button_offset+2); + translate([0,hole_spacing/2,-1]) + cylinder(d=hole_diameter*1.1,button_offset+2); + } + + // size indication + translate([0,foot_length-1,foot_height]){ + linear_extrude(height=0.4,center = true) text(text=str(floor(diameter)),size=8,halign="center",valign="top"); + translate([0,-10,0]) + linear_extrude(height=0.4,center = true) text(text=str("mm"),size=5,halign="center",valign="top"); + } + + } +} diff --git a/knoopvoet/knoopvoet_box.scad b/knoopvoet/knoopvoet_box.scad new file mode 100644 index 0000000..884c6fb --- /dev/null +++ b/knoopvoet/knoopvoet_box.scad @@ -0,0 +1,99 @@ +$fn = $preview ? 16 : 72; + +wall_thickness = 3; +//box = [21,21,21]; +box = [195,75,36]; +corner_radius = 2; +cutoff = 0.5; +overlap = 4; +taper = 0.1; + +module outer_box(box) { + minkowski(){ + cube([box.x+wall_thickness,box.y+wall_thickness,box.z+wall_thickness], center=true); + sphere(d=wall_thickness); + } +} + +module box(size, wall=3, taper=0) { +translate([0,0,-size.z/2]) +hull(){ +linear_extrude(height=0.1, scale=0) + offset(r=wall/2) square(size=[(size.x+wall-taper),(size.y+wall-taper)],center=true); + translate([0,0,size.z]) + rotate([0,180,0]) +linear_extrude(height=0.1, scale=0) + offset(r=wall/2) square(size=[size.x+wall+taper,size.y+wall+taper],center=true); + } +} + +module bottom_box(box) { + difference(){ + //box(size=[box.x,box.y,box.z+2*wall_thickness] ,wall=wall_thickness); + outer_box(box); + translate([0,0,box.z*cutoff+wall_thickness]) + cube([box.x+60,box.y+60,box.z],center=true); + //cube(box,center=true); + translate([0,0,box.z*cutoff+overlap-wall_thickness+0.01]) + #box([box.x,box.y,overlap],wall=wall_thickness/2,taper=0.5); + translate([box.x/2+wall_thickness,0,0]) + rotate([90,0,90]) + side_text(); + translate([-box.x/2-wall_thickness,0,0]) + rotate([90,0,-90]) + side_text(); + } +} + +module custom_text() { + linear_extrude(height=0.4,center=true) + text("Wetstone", valign="center", halign="center"); +} + +module side_text(){ + linear_extrude(height=0.4,center=true) + scale(1.2) + text("Wetstone", valign="center", halign="center"); + } + +module top_box(box) { + inner_wall_t = wall_thickness - 0.5; + difference(){ + union(){ + difference(){ + outer_box(box); + //box(size=[box.x,box.y,box.z+2*wall_thickness] ,wall=wall_thickness); + translate([0,0,-box.z*(1-cutoff)+wall_thickness]) + cube([box.x+60,box.y+60,box.z],center=true); + } + translate([0,0,overlap-wall_thickness+0.1]) + box([box.x,box.y,overlap],wall=wall_thickness/2,taper=0.5); + } + translate([0,0,box.z/2+wall_thickness]) + linear_extrude(height=0.4,center=true) + scale(3) + text("Wetstone", valign="center", halign="center"); + cube(box,center=true); + translate([box.x/2+wall_thickness,0,0]) + rotate([90,0,90]) + side_text(); + translate([-box.x/2-wall_thickness,0,0]) + rotate([90,0,-90]) + side_text(); + + } +} + +module top_box_flip() { + rotate([0,180,0]) + top_box(); +} + +* rotate([0,90,0]){ + bottom_box(); + translate([0,0,20]) + top_box(); + } + + + diff --git a/knoopvoet/knoopvoet_test.go b/knoopvoet/knoopvoet_test.go new file mode 100644 index 0000000..7783a98 --- /dev/null +++ b/knoopvoet/knoopvoet_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "github.com/deadsy/sdfx/render" + "github.com/deadsy/sdfx/sdf" + "testing" +) + +//var doveTail = DoveTail{ +// Size: sdf.V3{X: 10, Y: 8, Z: 2}, +// Angle: sdf.Pi/10, +//} +var buttonStruct = Button{ +Size: 18, +Curve: 1.2, +HoleSpacing: 8.5, +Thickness: 1.0, +} + +func TestButtonHolder3D(t *testing.T) { + stl, err := ButtonHolder3D(&buttonStruct) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl,300, "buttonHolder.stl") +} + +func TestButtonNegative(t *testing.T) { + stl, err := buttonNegative(&buttonStruct) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl,300, "buttonNegative.stl") +} + +func TestWireNegative(t *testing.T) { + stl, err := wireNegative(&buttonStruct) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl,300, "wireNegative.stl") +} + +func TestDoveTail(t *testing.T) { + stl, err := dovetail(sdf.V3{X: 10, Y: 8, Z: 2}, sdf.Pi/8, 0) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl,300, "doveTail.stl") +} \ No newline at end of file diff --git a/knoopvoet/test.scad b/knoopvoet/test.scad new file mode 100644 index 0000000..b543c71 --- /dev/null +++ b/knoopvoet/test.scad @@ -0,0 +1,12 @@ +radius = 5; +depth = 2; + +diff_h = (pow(radius,2)/depth - depth)/2; +diff_radius = (pow(radius,2)/depth - depth)/2 + depth; + +difference(){ +translate([0,0,0]) +cylinder(r=radius,h=depth); +translate([0,0,diff_radius]) +sphere(r=diff_radius); +}