diff --git a/Hey! JKL/clusters.go b/Hey! JKL/clusters.go new file mode 100644 index 0000000..6e6f9f6 --- /dev/null +++ b/Hey! JKL/clusters.go @@ -0,0 +1,81 @@ +package main + +import ( + "github.com/deadsy/sdfx/sdf" +) + +const ( + KEY_HOLE_SIZE = 14.2 + KEY_SPACING = 4.8 + BUTTON_DIAMETER = 24.0 +) + +func buttonRow() sdf.SDF2 { + keys := make([]sdf.SDF2, 4) + for i := range keys { + keys[i] = sdf.Box2D(sdf.V2{X: KEY_HOLE_SIZE, Y: KEY_HOLE_SIZE}, 0) + keys[i] = sdf.Transform2D(keys[i], sdf.Translate2d(sdf.V2{ + X: (keys[0].BoundingBox().Max.X*2 + KEY_SPACING) * float64(i), + Y: 0})) + } + buttonRow := sdf.Union2D(keys...) + buttonRow = sdf.Transform2D(buttonRow, sdf.Translate2d(sdf.V2{ + X: -((keys[0].BoundingBox().Max.X * 2.0) * float64(len(keys))) / 2, + Y: 0})) + return buttonRow +} + +func hjkl() sdf.SDF2 { + buttonRow := buttonRow() + return sdf.Transform2D(buttonRow, sdf.Rotate2d(sdf.DtoR(30))) +} + +func buttons() sdf.SDF2 { + buttons := make([]sdf.SDF2, 4) + for i := range buttons { + buttons[i], _ = sdf.Circle2D(BUTTON_DIAMETER / 2) + buttons[i] = sdf.Transform2D(buttons[i], sdf.Translate2d(sdf.V2{ + X: (buttons[0].BoundingBox().Max.X*2 + KEY_SPACING) * float64(i), + Y: 0})) + } + buttons[len(buttons)-1] = sdf.Transform2D(buttons[len(buttons)-1], sdf.Translate2d(sdf.V2{ + X: 0, + Y: -buttons[len(buttons)-1].BoundingBox().Max.Y})) + topRow := sdf.Union2D(buttons...) + bottomRow := sdf.Transform2D(topRow, sdf.Translate2d(sdf.V2{ + X: 0, + Y: -(topRow.BoundingBox().Max.Y*2 + KEY_SPACING)})) + rows := sdf.Union2D(topRow, bottomRow) + rows = sdf.Transform2D(rows, sdf.Translate2d(sdf.V2{ + X: -(buttons[0].BoundingBox().Max.X*8 - KEY_SPACING*2) / 2, + Y: topRow.BoundingBox().Max.Y + KEY_SPACING/2})) + return rows +} + +func buttonMounts() sdf.SDF2 { + buttons := make([]sdf.SDF2, 4) + mounts := make([]sdf.SDF2, 4) + for i := range buttons { + buttons[i], _ = sdf.Circle2D(BUTTON_DIAMETER / 2) + mounts[i] = sdf.Box2D(sdf.V2{X: KEY_HOLE_SIZE, Y: KEY_HOLE_SIZE}, 0) + buttons[i] = sdf.Transform2D(buttons[i], sdf.Translate2d(sdf.V2{ + X: (buttons[0].BoundingBox().Max.X*2 + KEY_SPACING) * float64(i), + Y: 0})) + mounts[i] = sdf.Transform2D(mounts[i], sdf.Translate2d(sdf.V2{ + X: (buttons[0].BoundingBox().Max.X*2 + KEY_SPACING) * float64(i), + Y: 0})) + } + mounts[len(mounts)-1] = sdf.Transform2D(mounts[len(mounts)-1], sdf.Translate2d(sdf.V2{ + X: 0, + Y: -buttons[len(buttons)-1].BoundingBox().Max.Y})) + topRow := sdf.Union2D(buttons...) + topRowMounts := sdf.Union2D(mounts...) + bottomRowMounts := sdf.Transform2D(topRowMounts, sdf.Translate2d(sdf.V2{ + X: 0, + Y: -(topRow.BoundingBox().Max.Y*2 + KEY_SPACING)})) + rows := sdf.Union2D(topRowMounts, bottomRowMounts) + rows = sdf.Transform2D(rows, sdf.Translate2d(sdf.V2{ + X: -(buttons[0].BoundingBox().Max.X*8 - KEY_SPACING*2) / 2, + Y: topRow.BoundingBox().Max.Y + KEY_SPACING/2})) + return rows +} diff --git a/Hey! JKL/go.mod b/Hey! JKL/go.mod new file mode 100644 index 0000000..5670600 --- /dev/null +++ b/Hey! JKL/go.mod @@ -0,0 +1,14 @@ +module git.jade.moe/oct2pus/arcade/hjklbox + +go 1.18 + +require github.com/deadsy/sdfx v0.0.0-20220508165057-718104295925 + +require ( + github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e // indirect + github.com/yofu/dxf v0.0.0-20190710012328-5a6d1e83f16c // indirect + golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect + gonum.org/v1/gonum v0.9.3 // indirect +) diff --git a/Hey! JKL/go.sum b/Hey! JKL/go.sum new file mode 100644 index 0000000..1e3789a --- /dev/null +++ b/Hey! JKL/go.sum @@ -0,0 +1,90 @@ +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +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/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deadsy/sdfx v0.0.0-20220508165057-718104295925 h1:CvjyreOQIm7VeHt2U0mq6iP8J0ZcjiXoxpgzLcYNJwo= +github.com/deadsy/sdfx v0.0.0-20220508165057-718104295925/go.mod h1:bjsFZRp7zdb9m29hIDXPN/V5H/AkjJ1AIr5iBuj7FcI= +github.com/dhconnelly/rtreego v1.1.0/go.mod h1:SDozu0Fjy17XH1svEXJgdYq8Tah6Zjfa/4Q33Z80+KM= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +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/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +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/hschendel/stl v1.0.4/go.mod h1:XQFFLKrq9YTaBpmouDui4JSaxMyAYkpD7elGSSj/y3M= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/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/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030 h1:lP9pYkih3DUSC641giIXa2XqfTIbbbRr0w2EOTA7wHA= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3 h1:DnoIG+QAMaF5NvxnGe/oKsgKcAc6PcUyl8q0VetfQ8s= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/Hey! JKL/hjklbox b/Hey! JKL/hjklbox new file mode 100755 index 0000000..226c0ac Binary files /dev/null and b/Hey! JKL/hjklbox differ diff --git a/Hey! JKL/keycap.go b/Hey! JKL/keycap.go new file mode 100644 index 0000000..a365b48 --- /dev/null +++ b/Hey! JKL/keycap.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/deadsy/sdfx/sdf" + v2 "github.com/deadsy/sdfx/vec/v2" +) + +// keycap makes a choc switch cap for use with the HJKL and start/select cluster +func keycap() sdf.SDF3 { + keycapTop2D := sdf.Box2D(sdf.V2{X: 13, Y: 13}, 1) + + keycapBottom2D := sdf.Box2D(sdf.V2{X: 14, Y: 14}, 1) + keycapBottom2D = sdf.Difference2D(keycapBottom2D, keycapTop2D) + + keycapBottom := sdf.Extrude3D(keycapBottom2D, 1) + keycapBottom = sdf.Transform3D(keycapBottom, sdf.Translate3d(sdf.V3{X: 0, Y: 0, Z: 1})) + keycap := sdf.ScaleExtrude3D(keycapTop2D, 1, v2.Vec{X: 1.0775, Y: 1.0775}) + keycap = sdf.Union3D(keycap, keycapBottom) + + stem2D := sdf.Box2D(sdf.V2{X: 1.2, Y: 3}, 0) + stems := make([]sdf.SDF3, 2) + for i := range stems { + stems[i] = sdf.Extrude3D(stem2D, 4) + stems[i] = sdf.Transform3D(stems[i], sdf.Translate3d(sdf.V3{X: 2.85, Y: 0, Z: 2})) + } + stems[1] = sdf.Transform3D(stems[1], sdf.MirrorYZ()) + + keycap = sdf.Union3D(keycap, sdf.Union3D(stems...)) + + return keycap +} diff --git a/Hey! JKL/main.go b/Hey! JKL/main.go new file mode 100644 index 0000000..4509da7 --- /dev/null +++ b/Hey! JKL/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/deadsy/sdfx/render" + "github.com/deadsy/sdfx/render/dc" +) + +func main() { + render.ToSTL(keycap(), 400, "keycap.stl", dc.NewDualContouringDefault()) + render.ToSTL(walls(), 400, "walls.stl", dc.NewDualContouringDefault()) + render.ToSTL(bottom(), 400, "bottom.stl", dc.NewDualContouringDefault()) + render.ToSTL(top(), 400, "top.stl", dc.NewDualContouringDefault()) + render.ToSTL(plate(), 400, "plate.stl", dc.NewDualContouringDefault()) +} diff --git a/Hey! JKL/plate.go b/Hey! JKL/plate.go new file mode 100644 index 0000000..3996fe3 --- /dev/null +++ b/Hey! JKL/plate.go @@ -0,0 +1,173 @@ +package main + +import "github.com/deadsy/sdfx/sdf" + +const ( + PLATE_THICKNESS = 2.825 + TOP_THICKNESS = 3.175 // 1/8th inch for possible thin acrylic top + BOTTOM_THICKNESS = 20 - PLATE_THICKNESS - TOP_THICKNESS + PLATE_WIDTH = 218.0 + PLATE_HEIGHT = 130.0 + TOLERANCE = 8.0 + CABLE_HEAD_HEIGHT = 6.0 + CABLE_HEAD_WIDTH = 10.0 + USB_DAUGHTERBOARD_HEIGHT = 12.6 + USB_DAUGHTERBOARD_LENGTH = 21.4 + USB_DAUGHTERBOARD_THICKNESS = 4.7 // includes usb jack + USB_CONNECTOR_LENGTH = 8.8 // 1.1mm sticks out from daughterboard + USB_CONNECTOR_HEIGHT = 7.2 + USB_CONNECTOR_THICKNESS = 3.2 + PICO_PEG_HEIGHT = 4.0 +) + +func plate() sdf.SDF3 { + plate2D := sdf.Box2D(sdf.V2{X: PLATE_WIDTH, Y: PLATE_HEIGHT}, 5) + + hjkl := hjkl() + hjkl = sdf.Transform2D(hjkl, sdf.Translate2d(sdf.V2{X: plate2D.BoundingBox().Max.X / 2, Y: plate2D.BoundingBox().Max.Y / 6})) + plate2D = sdf.Difference2D(plate2D, hjkl) + + buttonMounts := buttonMounts() + buttonMounts = sdf.Transform2D(buttonMounts, sdf.Translate2d(sdf.V2{X: -plate2D.BoundingBox().Max.X / 2.5, Y: plate2D.BoundingBox().Max.Y / 3})) + plate2D = sdf.Difference2D(plate2D, buttonMounts) + + buttonRow := buttonRow() + buttonRow = sdf.Transform2D(buttonRow, sdf.Translate2d(sdf.V2{X: plate2D.BoundingBox().Max.X / 2, Y: plate2D.BoundingBox().Max.Y / 1.25})) + plate2D = sdf.Difference2D(plate2D, buttonRow) + + corners := cornerHoles(plate2D, M4screwHole()) + plate2D = sdf.Difference2D(plate2D, corners) + + length := lengthHoles(plate2D, M3ScrewHole()) + plate2D = sdf.Difference2D(plate2D, length) + + return sdf.Extrude3D(plate2D, PLATE_THICKNESS) +} + +func top() sdf.SDF3 { + top2D := sdf.Box2D(sdf.V2{X: PLATE_WIDTH, Y: PLATE_HEIGHT}, 5) + + hjkl := buttonRow() + hjkl = sdf.Box2D(sdf.V2{X: hjkl.BoundingBox().Max.X*2 + 2, Y: hjkl.BoundingBox().Max.Y*2 + 2}, 1) + hjkl = sdf.Transform2D(hjkl, sdf.Rotate2d(sdf.DtoR(30))) + hjkl = sdf.Transform2D(hjkl, sdf.Translate2d(sdf.V2{X: top2D.BoundingBox().Max.X / 2, Y: top2D.BoundingBox().Max.Y / 6})) + top2D = sdf.Difference2D(top2D, hjkl) + + buttons := buttons() + buttons = sdf.Transform2D(buttons, sdf.Translate2d(sdf.V2{X: -top2D.BoundingBox().Max.X / 2.5, Y: top2D.BoundingBox().Max.Y / 3})) + top2D = sdf.Difference2D(top2D, buttons) + + buttonRow := buttonRow() + buttonRow = sdf.Box2D(sdf.V2{X: buttonRow.BoundingBox().Max.X*2 + 2, Y: buttonRow.BoundingBox().Max.Y*2 + 2}, 1) + buttonRow = sdf.Transform2D(buttonRow, sdf.Translate2d(sdf.V2{X: top2D.BoundingBox().Max.X / 2, Y: top2D.BoundingBox().Max.Y / 1.25})) + top2D = sdf.Difference2D(top2D, buttonRow) + + corners := cornerHoles(top2D, M4screwHole()) + top2D = sdf.Difference2D(top2D, corners) + + length := lengthHoles(top2D, M3ScrewHole()) + top2D = sdf.Difference2D(top2D, length) + + return sdf.Extrude3D(top2D, TOP_THICKNESS) +} + +func walls() sdf.SDF3 { + cavity2D := sdf.Box2D(sdf.V2{X: PLATE_WIDTH - TOLERANCE, Y: PLATE_HEIGHT - TOLERANCE}, 5) + walls2D := sdf.Box2D(sdf.V2{X: PLATE_WIDTH, Y: PLATE_HEIGHT}, 5) + bottom2D := sdf.Difference2D(walls2D, cavity2D) + + cornerScrewHolder, _ := sdf.Circle2D((M4_SCREW_HOLE_DIAMETER + 8) / 2) + cornerScrewHolders := cornerHoles(bottom2D, cornerScrewHolder) + cornerScrews := cornerHoles(bottom2D, M4screwHole()) + bottom2D = sdf.Union2D(bottom2D, cornerScrewHolders) + bottom2D = sdf.Difference2D(bottom2D, cornerScrews) + cavity2D = sdf.Difference2D(cavity2D, cornerScrewHolders) + bottom := sdf.Extrude3D(bottom2D, BOTTOM_THICKNESS-PLATE_THICKNESS) + + usbCutout, _ := sdf.Box3D(sdf.V3{X: USB_DAUGHTERBOARD_LENGTH + 0.4, Y: USB_DAUGHTERBOARD_HEIGHT + 0.4, Z: USB_DAUGHTERBOARD_THICKNESS + 3}, 0) + usbCutout = sdf.Transform3D(usbCutout, sdf.Translate3d(sdf.V3{X: 0, Y: (cavity2D.BoundingBox().Max.Y + usbCutout.BoundingBox().Max.Y) - usbCutout.BoundingBox().Max.Y*2 + 2.6, Z: -2})) // 5 for m3x5 screw + bottom = sdf.Difference3D(bottom, usbCutout) + + usbPortHole, _ := sdf.Box3D(sdf.V3{X: USB_CONNECTOR_LENGTH + 0.5, Y: USB_CONNECTOR_HEIGHT + 0.5, Z: USB_CONNECTOR_THICKNESS + 0.5}, 0) + usbPortHole = sdf.Transform3D(usbPortHole, sdf.Translate3d(sdf.V3{X: 0, Y: PLATE_HEIGHT / 2, Z: -2})) // Z is thickness of board + + bottom = sdf.Difference3D(bottom, usbPortHole) + + return bottom +} + +func bottom() sdf.SDF3 { + bottom2D := sdf.Box2D(sdf.V2{X: PLATE_WIDTH, Y: PLATE_HEIGHT}, 5) + cornerScrewHolder, _ := sdf.Circle2D((M4_SCREW_HOLE_DIAMETER + 8) / 2) + cornerScrewHolders := cornerHoles(bottom2D, cornerScrewHolder) + cornerScrews := cornerHoles(bottom2D, M4screwHole()) + + bottom2D = sdf.Union2D(bottom2D, cornerScrewHolders) + bottom2D = sdf.Difference2D(bottom2D, cornerScrews) + + usbCutoutPeg2D := M3ScrewHole() + usbCutoutPeg2D = sdf.Transform2D(usbCutoutPeg2D, sdf.Translate2d(sdf.V2{X: 8.3, Y: (bottom2D.BoundingBox().Max.Y + usbCutoutPeg2D.BoundingBox().Max.Y - 3.2) - usbCutoutPeg2D.BoundingBox().Max.Y*2})) + usbCutoutPeg2D = sdf.Union2D(usbCutoutPeg2D, sdf.Transform2D(usbCutoutPeg2D, sdf.Translate2d(sdf.V2{X: -16.6, Y: 0}))) + + bottom2D = sdf.Difference2D(bottom2D, usbCutoutPeg2D) + + bottom := sdf.Extrude3D(bottom2D, PLATE_THICKNESS) + pegCount := 4 + pegWall, _ := sdf.Circle2D(M2_SCREW_HOLE_DIAMETER) + pegHole, _ := sdf.Circle2D(M2_SCREW_HOLE_DIAMETER / 2) + pegHoles := make([]sdf.SDF2, pegCount) + pegWalls := make([]sdf.SDF2, pegCount) + pegs := make([]sdf.SDF3, pegCount) + for i := 0; i < pegCount; i++ { + pegHoles[i] = pegHole + pegWalls[i] = pegWall + pegs[i] = sdf.Extrude3D(sdf.Difference2D(pegWall, pegHole), PICO_PEG_HEIGHT) + } + pegs[0] = sdf.Transform3D(pegs[0], sdf.Translate3d(sdf.V3{X: 47.5 / 2, Y: 11.4 / 2, Z: 0})) // approximate spacing of pico holes + pegs[1] = sdf.Transform3D(pegs[1], sdf.Translate3d(sdf.V3{X: 47.5 / 2, Y: -11.4 / 2, Z: 0})) + pegs[2] = sdf.Transform3D(pegs[2], sdf.Translate3d(sdf.V3{X: -47.5 / 2, Y: -11.4 / 2, Z: 0})) + pegs[3] = sdf.Transform3D(pegs[3], sdf.Translate3d(sdf.V3{X: -47.5 / 2, Y: 11.4 / 2, Z: 0})) + + picoMount := sdf.Union3D(pegs...) + picoMount = sdf.Transform3D(picoMount, sdf.Translate3d(sdf.V3{X: PLATE_WIDTH / 4, Y: -PLATE_HEIGHT / 3, Z: PLATE_THICKNESS})) + + bottom = sdf.Union3D(bottom, picoMount) + + return bottom +} + +func cornerHoles(input, hole sdf.SDF2) sdf.SDF2 { + cornerHoles := make([]sdf.SDF2, 4) + for i := range cornerHoles { + cornerHoles[i] = hole + } + cornerHoles[0] = sdf.Transform2D(cornerHoles[0], sdf.Translate2d(sdf.V2{ + X: input.BoundingBox().Max.X - TOLERANCE, + Y: input.BoundingBox().Max.Y - TOLERANCE})) + cornerHoles[1] = sdf.Transform2D(cornerHoles[1], sdf.Translate2d(sdf.V2{ + X: -(input.BoundingBox().Max.X - TOLERANCE), + Y: input.BoundingBox().Max.Y - TOLERANCE})) + cornerHoles[2] = sdf.Transform2D(cornerHoles[2], sdf.Translate2d(sdf.V2{ + X: -(input.BoundingBox().Max.X - TOLERANCE), + Y: -(input.BoundingBox().Max.Y - TOLERANCE)})) + cornerHoles[3] = sdf.Transform2D(cornerHoles[3], sdf.Translate2d(sdf.V2{ + X: input.BoundingBox().Max.X - TOLERANCE, + Y: -(input.BoundingBox().Max.Y - TOLERANCE)})) + + return sdf.Union2D(cornerHoles...) +} + +func lengthHoles(input, hole sdf.SDF2) sdf.SDF2 { + cornerHoles := make([]sdf.SDF2, 2) + for i := range cornerHoles { + cornerHoles[i] = hole + } + cornerHoles[0] = sdf.Transform2D(cornerHoles[0], sdf.Translate2d(sdf.V2{ + X: 0, + Y: input.BoundingBox().Max.Y - TOLERANCE})) + cornerHoles[1] = sdf.Transform2D(cornerHoles[1], sdf.Translate2d(sdf.V2{ + X: 0, + Y: -(input.BoundingBox().Max.Y - TOLERANCE)})) + + return sdf.Union2D(cornerHoles...) +} diff --git a/Hey! JKL/screw.go b/Hey! JKL/screw.go new file mode 100644 index 0000000..6fd6c36 --- /dev/null +++ b/Hey! JKL/screw.go @@ -0,0 +1,24 @@ +package main + +import "github.com/deadsy/sdfx/sdf" + +const ( + M4_SCREW_HOLE_DIAMETER = 4 //m4 screw + M3_SCREW_HOLE_DIAMETER = 3 //m3 screw + M2_SCREW_HOLE_DIAMETER = 2 //m2 screw +) + +func M4screwHole() sdf.SDF2 { + hole, _ := sdf.Circle2D(M4_SCREW_HOLE_DIAMETER / 2) + return hole +} + +func M3ScrewHole() sdf.SDF2 { + hole, _ := sdf.Circle2D(M3_SCREW_HOLE_DIAMETER / 2) + return hole +} + +func M2ScrewHole() sdf.SDF2 { + hole, _ := sdf.Circle2D(M2_SCREW_HOLE_DIAMETER / 2) + return hole +}