diff options
author | Matt Adereth <adereth@gmail.com> | 2015-12-01 21:19:52 -0800 |
---|---|---|
committer | Matt Adereth <adereth@gmail.com> | 2015-12-01 21:19:52 -0800 |
commit | ac0ff9c4862ed6249cd160decee2d2e219e79b80 (patch) | |
tree | 6149a357b9cf088ba60292d0e74e8acc9f559215 /src | |
parent | 33669c9ad7a6033ddf729d8ff68748dd87b8dd86 (diff) |
New model!
Diffstat (limited to 'src')
-rw-r--r-- | src/dactyl_cave/alternathumb.clj | 149 | ||||
-rw-r--r-- | src/dactyl_cave/cave.clj | 337 | ||||
-rw-r--r-- | src/dactyl_cave/core.clj | 6 | ||||
-rw-r--r-- | src/dactyl_cave/key.clj | 81 | ||||
-rw-r--r-- | src/dactyl_cave/text.clj | 134 | ||||
-rw-r--r-- | src/dactyl_cave/thumb.clj | 173 | ||||
-rw-r--r-- | src/dactyl_keyboard/dactyl.clj | 1240 |
7 files changed, 1240 insertions, 880 deletions
diff --git a/src/dactyl_cave/alternathumb.clj b/src/dactyl_cave/alternathumb.clj deleted file mode 100644 index ddfb42a..0000000 --- a/src/dactyl_cave/alternathumb.clj +++ /dev/null @@ -1,149 +0,0 @@ -(ns dactyl-cave.alternathumb - (:use [scad-clj.scad]) - (:use [scad-clj.model]) - (:use [unicode-math.core]) - (:require [dactyl-cave.key :as key]) - (:require [dactyl-cave.cave :as cave])) - -(defn- scoop [angle radius [x y :as direction] shape] - (->> shape - (translate [0 0 radius]))) - -(defn thumb-x+x-column [shape] - (let [α (/ π 12) - radius (/ (/ key/pillar-depth 2) - (Math/sin (/ α 2))) - spin-shape (->> shape - (translate [0 0 (+ (- key/full-height) - (- radius))]))] - (translate - [0 0 (+ radius key/full-height)] - (union - spin-shape - - (->> spin-shape - (rotate (- α) [1 0 0])))))) - -(defn thumb-2x-column [shape] - (let [α (/ π 12) - radius (/ (/ key/pillar-depth 2) - (Math/sin (/ α 2))) - spin-shape (->> shape - (translate [0 0 (+ (- key/full-height) - (- radius))]))] - (translate - [0 0 (+ radius key/full-height)] - (union - (->> spin-shape - (rotate (* α -1/2) [1 0 0])))))) - -(defn thumb-2x-row [shape] - (let [α (/ π 12) - radius (/ (/ key/pillar-depth 2) - (Math/sin (/ α 2))) - spin-shape (->> shape - (translate [0 0 (+ (- key/full-height) - (- radius))]))] - (translate - [0 0 (+ radius key/full-height)] - (union - (->> spin-shape - (rotate (* α 1) [1 0 0])))))) - - -(defn spin-thumb [column shape] - (let [β (/ π 36) - radius (/ (/ (+ key/pillar-width 5) 2) - (Math/sin (/ β 2)))] - (->> - (translate - [0 0 (- (- radius key/full-height))] - (->> shape - (translate [0 0 (- radius key/full-height)]) - (rotate (* column β) [0 1 0]))) - (translate [key/pillar-width 0 0]) - (rotate (/ π 12) [0 0 1]) - #_(rotate (/ π -12) [0 1 0]) - #_(rotate (/ π 6) [0 0 1]) - (translate [-7 -47 35])))) - -(defn thumb-layout [shape] - (union - (spin-thumb 2 (thumb-x+x-column shape)) - (spin-thumb 1 (thumb-x+x-column shape)) - (spin-thumb 0 (thumb-2x-column shape)) - (spin-thumb 1/2 (thumb-2x-row shape)))) - -(defn support [shape] - (hull - shape - (extrude-linear {:height 10 :twist 0 :convexity 0} - (project (hull shape))))) - -(defn thumb-support [shape] - (union - (support (union - (spin-thumb 2 (thumb-x+x-column shape)) - (spin-thumb 1 (thumb-x+x-column shape)) - (spin-thumb 0 (thumb-2x-column shape)))) - (support (union - (spin-thumb 0 (thumb-2x-column shape)) - (spin-thumb 1/2 (thumb-2x-row shape)))) - -)) - -(def bottom - (translate [0 0 -100] - (cube 2000 2000 200)) - ) - - -#_(def thumb-base - (difference - (hull - (thumb-layout (translate [0 0 (/ key/pillar-height -2)] - (scale [1 1 1/10] key/full-pillar))) - (extrude-linear {:height 10 :twist 0 :convexity 0} - (project (hull (thumb-layout key/full-pillar))))) - bottom - (thumb-layout key/keyswitch-full-hole))) - -(def thumb-base - (union - (thumb-support (scale [1 1 1/10] key/full-pillar)) - #_(->> (cube 150 150 50) - (translate [150 75 25]))) - - ) - -(defn move-to-corner [shape] - (translate [-265 -215 0] shape)) - -(def thumb-cluster - (difference - (translate [0 0 -20] - (difference - (union - (thumb-layout key/pillar) - thumb-base) - (thumb-layout key/keyswitch-full-hole))) - bottom)) - -(spit "alternathumb.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - #_thumb-cluster - (union - (mirror [1 0 0] (move-to-corner thumb-cluster)) - #_(->> (move-to-corner thumb-cluster) - (mirror [1 0 0])) - #_cave/base - #_cave/fingers - ) - - #_(mirror [1 0 0] - (difference - (move-to-corner thumb-cluster) - cave/base - )) - ))) - diff --git a/src/dactyl_cave/cave.clj b/src/dactyl_cave/cave.clj deleted file mode 100644 index 05bfaed..0000000 --- a/src/dactyl_cave/cave.clj +++ /dev/null @@ -1,337 +0,0 @@ -(ns dactyl-cave.cave - (:use [scad-clj.scad]) - (:use [scad-clj.model]) - (:use [unicode-math.core]) - (:use [dactyl-cave.key])) - -(defn key-place [column row shape] - (let [α (/ π 12) - row-radius (+ (/ (/ pillar-depth 2) - (Math/sin (/ α 2))) - full-height) - row-placed-shape (->> shape - (translate [0 0 (- row-radius)]) - (rotate (* α (- 2 row)) [1 0 0]) - (translate [0 0 row-radius])) - β (/ π 36) - column-radius (+ (/ (/ (+ pillar-width 127/90) 2) - (Math/sin (/ β 2))) - full-height) - column-offset (condp = column - 2 [0 127/45 -254/45] - 4 [0 (/ pillar-depth -3) 254/45] - 5 [0 (/ pillar-depth -4) 254/45] - [0 0 0]) - column-angle (if (<= column 4) - (* β (- 2 column)) - (* β -3.25)) - placed-shape (->> row-placed-shape - (translate [0 0 (- column-radius)]) - (rotate column-angle [0 1 0]) - (translate [0 0 column-radius]) - (translate column-offset))] - (translate [0 0 127/18] - (rotate (/ π 12) [0 1 0] - placed-shape)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Limits -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def bottom-limit - (->> (cube (* pillar-width 17.75) - (* pillar-depth 17) - 508/9) - (translate [(+ (/ pillar-width 2) 127/45) - 0 -254/9]))) - -(def back-limit - (->> (cube (* pillar-width 9) - (* pillar-depth 2) - 254/3) - (translate [pillar-width - (+ (* pillar-depth 4.1)) - 254/9]))) - -(def front-right-limit - (->> (cube (* pillar-width 2) - (* pillar-depth 2) - 254/3) - (translate [(+ (* pillar-width 4.125)) - (+ (* pillar-depth -3.25))]))) - -(def front-left-limit - (->> (cube (* pillar-width 2.5) - (* pillar-depth 2) - 254/3) - (translate [(+ (* pillar-width -3)) - (+ (* pillar-depth -3)) - 254/9]))) - -(def front-limit - (->> (cube (* pillar-width 9) - (* pillar-depth 2) - 254/3) - (translate [(* pillar-width 1/2) (+ (* pillar-depth -4.25)) 254/9]))) - - (* (/ 25.4 90) pillar-depth (- 3.1 -3.2)) - - -(def left-limit - (->> (cube (* pillar-width 1) - (* pillar-depth 8) - 254/3) - (translate [(+ (* pillar-depth -3.25)) 0 254/9]))) - -(def right-limit - (->> (cube (* pillar-width ) - (* pillar-depth 8) - 1016/9) - (translate [(+ (* pillar-depth 5.5)) 0 254/9])) ) - -(* (/ 25.4 90) (- (- (* pillar-depth 5.4) (* pillar-width 1/2)) - (+ (* pillar-depth -3.25) (* pillar-width 1/2)) - )) - -(def limits - (union - #_front-right-limit - front-left-limit - front-limit - left-limit - right-limit - bottom-limit - back-limit)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Base -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def main-sphere - (let [radius (/ (/ pillar-depth 2) - (Math/sin (/ (/ π 36) 2)))] - (->> (sphere radius) - (translate [(* pillar-width 2.5) 0 (+ radius 127/90)]))) ) - -(def base-cube - (->> (cube (* pillar-width 7.75) - (* pillar-depth 7) - 508/9) - (translate [(+ (/ pillar-width 2) 2921/450) - 0 254/9]))) - -(def base - (difference - base-cube - main-sphere - limits)) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Walls -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -#_(def wall-sphere - (let [radius (/ (/ pillar-depth 2) - (Math/sin (/ (/ π 36) 2)))] - (->> (sphere radius) - (scale [1 2/3 1]) - (translate [(* pillar-width 2.5) 0 (+ radius 5 (* pillar-depth ))])))) - -(def wall-sphere - (let [radius (/ (/ pillar-depth 2) - (Math/sin (/ (/ π 36) 2)))] - (->> (sphere radius) - (scale [1 2/3 1]) - (translate [0 0 radius]) - (translate [0 0 127/18]) - (rotate (/ π 12) [0 1 0]) - (translate [0 0 (* pillar-depth 3/4)])))) - -(def wall-thickness 127/30) - -(def back-wall - (difference - (translate [0 (- wall-thickness) 0] back-limit) - back-limit - right-limit - left-limit - bottom-limit - wall-sphere)) - -(def walls - (difference - (union - (translate [0 (- wall-thickness) 0] back-limit) - (translate [(- wall-thickness) 0 0] right-limit) - (translate [0 wall-thickness 0] front-limit) - (translate [wall-thickness 0 0] left-limit) - ) - wall-sphere - limits)) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Wire holes -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def teensy-center [(* -1.6 pillar-width) - (* 2.8 pillar-depth) - 254/45]) - -(def teensy-tray-slot - (->> (cube (* 1.125 pillar-width) - 40 - 508/45) - (translate teensy-center))) - -(def hole-destination - (->> (cube 5.7 5.7 5.7) - (translate [(first teensy-center) - (second teensy-center) - 2.8 #_3.1]))) - -(defn bottom-cube [column row] - (->> (cube 6 6 6) - (key-place column row) - (project) - (extrude-linear {:height 5.7 :twist 0 :convexity 0}) - (translate [0 0 2.8]))) - -(defn wire-hole [column row] - (union - (hull - (key-place column row (cube 6 6 keyswitch-height)) - (bottom-cube column row)) - (hull - hole-destination - (bottom-cube column row)))) - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Full Model -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def fingers - (let [all-key-coords (for [column (range 0 6) - row (range 0 5) - ;; Removing bottom left key - :when (or (not= column 0) - (not= row 4))] - [column row]) - middle-key-coords (for [column (range 0 6) - row (range 1 4) - ;; Removing bottom left key - :when (or (not= column 0) - (not= row 4))] - [column row]) - top-key-coords (for [column (range 0 6)] - [column 0]) - bottom-key-coords (conj (for [column (range 1 6)] - [column 4]) - [0 3]) - - ] - (difference - (union base - #_walls - (apply union - (map #(key-place (first %) (second %) - (->> (cube pillar-width pillar-depth - (* 3 pillar-height)) - (translate [0 0 (/ pillar-height -2)]))) - all-key-coords))) - (apply union - (concat - (map #(key-place (first %) (second %) keyswitch-full-hole) - middle-key-coords) - (map #(key-place (first %) (second %) keyswitch-bottom-hole) - top-key-coords) - (map #(key-place (first %) (second %) (mirror [0 -1 0] keyswitch-bottom-hole)) - bottom-key-coords) - )) - limits - teensy-tray-slot))) - - -(def wire-network - (union - (wire-hole 0 0) - (wire-hole 1 0) - (wire-hole 2 0) - (wire-hole 3 0) - (wire-hole 4 0) - (wire-hole 5 0) - (wire-hole 0 1) - (wire-hole 0 2) - (wire-hole 0 3) - (wire-hole 0 4) - (wire-hole 1 4))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Actual Output -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -#_(spit "key.scad" - (write-scad (difference - pillar - ))) - -(spit "key.scad" - (write-scad (difference - (union - #_walls - #_wall-sphere - #_fingers - (difference fingers wire-network) - #_(mirror [-1 0 0] - (difference fingers wire-network)) - ) - #_(cube 400 800 800) - ))) - -#_(spit "key.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (difference - (union - #_walls - #_wall-sphere - #_fingers - (difference fingers wire-network) - #_(mirror [-1 0 0] - (difference fingers wire-network)) - ) - #_(cube 400 800 800) - )))) - - -#_(spit "key.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (difference - fingers - wire-hole-1 - wire-hole-2)))) - -#_(spit "key.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (differe - #_wall - #_base - #_rim - #_(mirror [1 0 0] fingers) - fingers - wire-hole-1)))) - -#_(spit "key.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (union - fingers - (->> fingers - project - (extrude-linear {:height 1 :twist 0 :convexity 0}) - (scale [1.5 1.15 1]) - ) - ) - ))) - diff --git a/src/dactyl_cave/core.clj b/src/dactyl_cave/core.clj deleted file mode 100644 index d07faa6..0000000 --- a/src/dactyl_cave/core.clj +++ /dev/null @@ -1,6 +0,0 @@ -(ns dactyl-cave.core) - -(defn foo - "I don't do a whole lot." - [x] - (println x "Hello, World!")) diff --git a/src/dactyl_cave/key.clj b/src/dactyl_cave/key.clj deleted file mode 100644 index 13c46fd..0000000 --- a/src/dactyl_cave/key.clj +++ /dev/null @@ -1,81 +0,0 @@ -(ns dactyl-cave.key - (:use [scad-clj.scad]) - (:use [scad-clj.model]) - (:use [unicode-math.core])) - - -(def tw 13.969999999999999) ;; Top width -(def smh 0.98044) ;; Side margin height -(def pw 0.8128) ;; Peg width -(def ph 3.5001199999999995) ;; Peg height -(def pgh 5.00888) ;; Peg gap height - -(def keyswitch-height (+ smh ph pgh ph smh)) -(def keyswitch-width (+ pw tw pw)) -(def plate-height 254/45) - -(defn- flip-path [points] (map (partial map -) points)) - -(def keyswitch-plate-hole-shape - (polygon [[0.8128 0] [0.8128 0.98044] [0.0 0.98044] [0.0 4.48056] [0.8128 4.48056] [0.8128 9.48944] [0.0 9.48944] [0.0 12.98956] [0.8128 12.98956] [0.8128 13.969999999999999] [14.7828 13.969999999999999] [14.7828 12.98956] [15.5956 12.98956] [15.5956 9.48944] [14.7828 9.48944] [14.7828 4.48056] [15.5956 4.48056] [15.5956 0.98044] [14.7828 0.98044] [14.7828 0]])) - -(def keyswitch-plate-hole - (->> keyswitch-plate-hole-shape - (extrude-linear {:height plate-height :twist 0 :convexity 0}) - (translate (map #(/ (- %) 2) [keyswitch-width keyswitch-height 0])) - (translate [0 0 1]))) - -(def hole-height 127/18) - -(def pillar-width (+ keyswitch-width 127/45)) -(def pillar-height (+ hole-height (/ plate-height 2))) -(def pillar-depth (+ keyswitch-height 127/30)) - -(def keyswitch-full-hole - (->> - (union - keyswitch-plate-hole - (->> (cube (/ ph 2) pillar-depth (* plate-height 2)) - (translate [(* tw -1/4) 0 0])) - (->> (cube (/ ph 2) pillar-depth (* plate-height 2)) - (translate [(* tw 1/4) 0 0])) - (translate - [0 0 (/ hole-height -2)] - (cube keyswitch-width - keyswitch-height - hole-height))) - (translate [0 0 hole-height]))) - -(def keyswitch-bottom-hole - (->> - (union - keyswitch-plate-hole - (->> (cube (/ ph 2) (/ pillar-depth 2) (* plate-height 2)) - (translate [(* tw -1/4) (/ pillar-depth -2) 0])) - (->> (cube (/ ph 2) (/ pillar-depth 2) (* plate-height 2)) - (translate [(* tw 1/4) (/ pillar-depth -2) 0])) - (translate - [0 0 (/ hole-height -2)] - (cube keyswitch-width - keyswitch-height - hole-height))) - (translate [0 0 hole-height]))) - -(def full-pillar - (->> (cube pillar-width pillar-depth - pillar-height) - (translate [0 0 (/ pillar-height 2)]))) - -(def pillar - (difference - full-pillar - keyswitch-full-hole)) - -(def key-height 127/10) - -(def pillar-with-fake-key - (union pillar - (->> (cube (+ -0 pillar-width) (+ -0 pillar-depth) key-height) - (translate [0 0 (+ (/ key-height 2) pillar-height 127/450)])))) - -(def full-height (+ pillar-height key-height 127/450)) diff --git a/src/dactyl_cave/text.clj b/src/dactyl_cave/text.clj deleted file mode 100644 index db37bfd..0000000 --- a/src/dactyl_cave/text.clj +++ /dev/null @@ -1,134 +0,0 @@ -(ns dactyl-cave.text - (:use [scad-clj.scad]) - (:use [scad-clj.model]) - (:import (java.awt Font RenderingHints) - (java.awt.font FontRenderContext) - (java.awt.geom PathIterator))) - -(def segment-type - {PathIterator/SEG_CLOSE :close - PathIterator/SEG_CUBICTO :cubic-to - PathIterator/SEG_LINETO :line-to - PathIterator/SEG_MOVETO :move-to - PathIterator/SEG_QUADTO :quad-to}) - -;; How many points are specified for each segment type -(def segment-length - {PathIterator/SEG_CLOSE 0 - PathIterator/SEG_CUBICTO 3 - PathIterator/SEG_LINETO 1 - PathIterator/SEG_MOVETO 1 - PathIterator/SEG_QUADTO 2}) - -(defn path-iterator->segments - "Converts a PathIterator into a sequence of segments of the form [segment-type [& points]]" - [^PathIterator path-iterator] - (if (not (.isDone path-iterator)) - (let [coords (double-array (* 2 (apply max (vals segment-length)))) - segment-code (.currentSegment path-iterator coords)] - (cons [(segment-type segment-code) - (take (segment-length segment-code) (partition 2 coords))] - (lazy-seq (path-iterator->segments (doto path-iterator (.next)))))))) - -(defn quad->fn - "Returns the parametric control equation f(t), 0 <= t <= 1 -for the quadratic interpolation of 3 points." - [cp p1 p2] - (fn [t] - (letfn [(interp [a b c] (+ (* (Math/pow (- 1 t) 2) a) - (* 2 t (- 1 t) b) - (* (Math/pow t 2) c)))] - [(apply interp (map first [cp p1 p2])) - (apply interp (map second [cp p1 p2]))]))) - -(defn cubic->fn - "Returns the parametric control equation f(t), 0 <= t <= 1 -for the cubic interpolation of 4 points." - [cp p1 p2 p3] - (fn [t] - (letfn [(interp [a b c d] - (+ (* (Math/pow (- 1 t) 3) a) - (* 3 t (Math/pow (- 1 t) 2) b) - (* 3 (Math/pow t 2) (- 1 t) c) - (* (Math/pow t 3) d)))] - [(apply interp (map first [cp p1 p2 p3])) - (apply interp (map second [cp p1 p2 p3]))]))) - -(defn segments->lines - "Takes a sequence of segments of the form [segment-type [& points]] -and transforms each segment into a sequence of interpolated points" - [segments] - (reductions (fn [prev-line-points [segment-type control-points]] - #_(println segment-type) - (condp = segment-type - :move-to control-points - :line-to control-points - :quad-to (map (apply quad->fn - (last prev-line-points) - control-points) - (range 1/10 11/10 1/10)) - :cubic-to (map (apply cubic->fn - (last prev-line-points) - control-points) - (range 1/10 11/10 1/10)))) - (last (rest (first segments))) - (rest segments))) - - -(defn path2d [points] - (let [path (doto (java.awt.geom.Path2D$Double.) - (.moveTo (-> points first first) - (-> points first second)))] - (doseq [point (rest points)] - (.lineTo path (first point) (second point))) - path)) - -(defn split-intersecting [paths] - (let [polygons (map path2d paths) - starting-points (map first paths)] - (reduce (fn [acc path] - (let [polygon (path2d path)] - (if (some #(.contains % (-> path first first) (-> path first second)) - (:polygons acc)) - (merge-with concat acc - {:difference [path]}) - (merge-with concat acc - {:polygons [polygon] - :union [path]})))) - {:polygons [] - :union [] - :difference []} - paths))) - -(defn text-polygon [font size text] - (let [frc (FontRenderContext. nil - RenderingHints/VALUE_TEXT_ANTIALIAS_DEFAULT - RenderingHints/VALUE_FRACTIONALMETRICS_DEFAULT) - path-iter (-> (Font. font Font/PLAIN size) - (.createGlyphVector frc text) - (.getOutline) - (.getPathIterator nil)) - paths (->> (path-iterator->segments path-iter) - (partition-by #(= (first %) :close)) - (take-nth 2) - (map segments->lines) - (map flatten) - (map (partial partition 2))) - split-paths (split-intersecting paths)] - (difference - (apply union (map polygon (:union split-paths))) - (apply union (map polygon (:difference split-paths)))))) - -(spit "/Users/madereth/text.scad" - (write-scad - (->> "Anonymous Pro" #_(str (java.util.Date.)) - (text-polygon "Anonymous Pro" 12) - (extrude-linear {:height 50 :twist 0 :convexity 0})))) - - - -(spit "/Users/madereth/text.scad" - (write-scad - (->> "Anonymous Pro" #_(str (java.util.Date.)) - (text-polygon "Anonymous Pro" 12) - (extrude-linear {:height 12 :twist 0 :convexity 0}))))
\ No newline at end of file diff --git a/src/dactyl_cave/thumb.clj b/src/dactyl_cave/thumb.clj deleted file mode 100644 index 0dfce97..0000000 --- a/src/dactyl_cave/thumb.clj +++ /dev/null @@ -1,173 +0,0 @@ -(ns dactyl-cave.thumb - (:use [scad-clj.scad]) - (:use [scad-clj.model]) - (:use [unicode-math.core]) - (:require [dactyl-cave.key :as key]) - (:require [dactyl-cave.cave :as cave])) - -(defn thumb-place [column row shape] - (let [α (/ π 12) - row-radius (+ (/ (/ key/pillar-depth 2) - (Math/sin (/ α 2))) - key/full-height) - β (/ π 36) - column-radius (+ (/ (/ (+ key/pillar-width 5) 2) - (Math/sin (/ β 2))) - key/full-height)] - (->> shape - (translate [0 0 (- row-radius)]) - (rotate (* α row) [1 0 0]) - (translate [0 0 row-radius]) - (translate [0 0 (- column-radius)]) - (rotate (* column β) [0 1 0]) - (translate [0 0 column-radius]) - (translate [key/pillar-width 0 0]) - (rotate (/ π 12) [0 1 0]) - (rotate (* π (- 1/4 1/16)) [0 0 1]) - (rotate (/ π 12) [1 1 0]) - (translate [254/45 127/15 1778/45])))) - -(defn thumb-2x-column [shape] - (thumb-place 0 -1/2 shape)) - -(defn thumb-2x+1-column [shape] - (union (thumb-place 1 -1/2 shape) - (thumb-place 1 1 shape))) - -(defn thumb-1x-column [shape] - (union (thumb-place 2 -1 shape) - (thumb-place 2 0 shape) - (thumb-place 2 1 shape))) - -(defn thumb-layout [shape] - (union - (thumb-2x-column shape) - (thumb-2x+1-column shape) - (thumb-1x-column shape))) - -(defn support [shape] - (hull - shape - (extrude-linear {:height 127/45 :twist 0 :convexity 0} - (project (hull shape))))) - -(defn thumb-support [shape] - (let [column-supports - (union - (support (thumb-2x-column shape)) - (support (thumb-2x+1-column shape)) - (support (thumb-1x-column shape)))] - (union column-supports - (support column-supports)))) -(fn []) -(def bottom - (translate [0 0 -254/9] (cube 5080/9 5080/9 508/9))) - -(def thumb-base - (thumb-support (scale [1 1 1/10] key/full-pillar))) - -#_(defn move-to-corner [shape] - (translate [-6731/90 -5461/90 0] shape)) - -(defn move-to-corner [shape] - (translate [(+ -6731/90 10) (- -5461/90 10) 0] shape)) - -(/ -6731 90.0) -74.78888888888889 -(double -5461/90) -60.67777777777778 - -(def thumb-cluster - (difference - (translate [0 0 -254/45] - (difference - (union - (thumb-layout key/pillar) - thumb-base) - (thumb-layout key/keyswitch-full-hole))) - bottom)) - -(def connection-stems - (difference - (hull (union - (->> (cylinder 127/90 508/9) - (translate [-0 -2413/45 0])) - (->> (cylinder 127/90 508/9) - (translate [-127/3 -0 0])) - (->> (cylinder 127/90 508/9) - (translate [-2159/30 -127/5 0])) - (->> (cylinder 127/90 508/9) - (translate [-508/9 -381/5 0])))) - bottom - cave/main-sphere - (translate [0 0 -254/45] - (thumb-layout key/keyswitch-full-hole)))) - -(def wire-network - (apply union - (for [[column row] [[0 -1/2] - [1 -1/2] - [1 1] - [2 -1] - [2 0] - [2 1]]] - (let [middle-hole (->> (thumb-place column row (cube 6 6 6)) - (translate [0 0 -127/9]) - move-to-corner)] - #_(thumb-place column row (sphere 127/9)) - (union (hull (->> (cube 254/45 254/45 key/keyswitch-height) - (thumb-place column row) - move-to-corner) - middle-hole) - (hull middle-hole (cave/bottom-cube 0 4)) - (hull (cave/bottom-cube 0 4) cave/hole-destination)))))) - - -(spit "thumb.scad" - (write-scad (difference - (union - (move-to-corner thumb-cluster) - connection-stems - - #_cave/base - #_cave/fingers) - cave/base - wire-network))) - -#_(spit "thumb.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (mirror [-1 0 0] - (difference - (union - (move-to-corner thumb-cluster) - connection-stems - - #_cave/base - #_cave/fingers) - cave/base - wire-network))))) - -#_(spit "thumb.scad" - (write-scad (scale [(/ 25.4 90) (/ 25.4 90) (/ 25.4 90)] - (mirror [-1 0 0] - (difference - (union - (move-to-corner thumb-cluster) - connection-stems - - #_cave/base - #_cave/fingers) - cave/base - wire-network))))) - - - - -(spit "one-piece.scad" - (write-scad - (mirror [-1 0 0] - (union (difference cave/fingers cave/wire-network) - (difference - (union - (move-to-corner thumb-cluster) - connection-stems) - cave/base - wire-network))))) diff --git a/src/dactyl_keyboard/dactyl.clj b/src/dactyl_keyboard/dactyl.clj new file mode 100644 index 0000000..2e26ed2 --- /dev/null +++ b/src/dactyl_keyboard/dactyl.clj @@ -0,0 +1,1240 @@ +(ns dactyl-keyboard.dactyl + (:refer-clojure :exclude [use import]) + (:require [scad-clj.scad :refer :all] + [scad-clj.model :refer :all] + [unicode-math.core :refer :all])) + +;;;;;;;;;;;;;;;;; +;; Switch Hole ;; +;;;;;;;;;;;;;;;;; + +(def keyswitch-height 14.4) ;; Was 14.1, then 14.25 +(def keyswitch-width 14.4) + +(def sa-profile-key-height 12.7) + +(def plate-thickness 4) +(def mount-width (+ keyswitch-width 3)) +(def mount-height (+ keyswitch-height 3)) + +(def single-plate + (let [top-wall (->> (cube (+ keyswitch-width 3) 1.5 plate-thickness) + (translate [0 + (+ (/ 1.5 2) (/ keyswitch-height 2)) + (/ plate-thickness 2)])) + left-wall (->> (cube 1.5 (+ keyswitch-height 3) plate-thickness) + (translate [(+ (/ 1.5 2) (/ keyswitch-width 2)) + 0 + (/ plate-thickness 2)])) + side-nub (->> (binding [*fn* 30] (cylinder 1 2.75)) + (rotate (/ π 2) [1 0 0]) + (translate [(+ (/ keyswitch-width 2)) 0 1]) + (hull (->> (cube 1.5 2.75 plate-thickness) + (translate [(+ (/ 1.5 2) (/ keyswitch-width 2)) + 0 + (/ plate-thickness 2)])))) + plate-half (union top-wall left-wall (with-fn 100 side-nub))] + (union plate-half + (->> plate-half + (mirror [1 0 0]) + (mirror [0 1 0]))))) + +;;;;;;;;;;;;;;;; +;; SA Keycaps ;; +;;;;;;;;;;;;;;;; + +(def sa-length 18.25) +(def sa-double-length 37.5) +(def sa-cap {1 (let [bl2 (/ 18.5 2) + m (/ 17 2) + key-cap (hull (->> (polygon [[bl2 bl2] [bl2 (- bl2)] [(- bl2) (- bl2)] [(- bl2) bl2]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 0.05])) + (->> (polygon [[m m] [m (- m)] [(- m) (- m)] [(- m) m]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 6])) + (->> (polygon [[6 6] [6 -6] [-6 -6] [-6 6]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 12])))] + (->> key-cap + (translate [0 0 (+ 5 plate-thickness)]) + (color [220/255 163/255 163/255 1]))) + 2 (let [bl2 (/ sa-double-length 2) + bw2 (/ 18.25 2) + key-cap (hull (->> (polygon [[bw2 bl2] [bw2 (- bl2)] [(- bw2) (- bl2)] [(- bw2) bl2]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 0.05])) + (->> (polygon [[6 16] [6 -16] [-6 -16] [-6 16]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 12])))] + (->> key-cap + (translate [0 0 (+ 5 plate-thickness)]) + (color [127/255 159/255 127/255 1]))) + 1.5 (let [bl2 (/ 18.25 2) + bw2 (/ 28 2) + key-cap (hull (->> (polygon [[bw2 bl2] [bw2 (- bl2)] [(- bw2) (- bl2)] [(- bw2) bl2]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 0.05])) + (->> (polygon [[11 6] [-11 6] [-11 -6] [11 -6]]) + (extrude-linear {:height 0.1 :twist 0 :convexity 0}) + (translate [0 0 12])))] + (->> key-cap + (translate [0 0 (+ 5 plate-thickness)]) + (color [240/255 223/255 175/255 1])))}) + +;;;;;;;;;;;;;;;;;;;;;;;;; +;; Placement Functions ;; +;;;;;;;;;;;;;;;;;;;;;;;;; + +(def columns (range 0 6)) +(def rows (range 0 5)) + +(def α (/ π 12)) +(def β (/ π 36)) +(def cap-top-height (+ plate-thickness sa-profile-key-height)) +(def row-radius (+ (/ (/ (+ mount-height 1/2) 2) + (Math/sin (/ α 2))) + cap-top-height)) +(def column-radius (+ (/ (/ (+ mount-width 2.0) 2) + (Math/sin (/ β 2))) + cap-top-height)) + +(defn key-place [column row shape] + (let [row-placed-shape (->> shape + (translate [0 0 (- row-radius)]) + (rotate (* α (- 2 row)) [1 0 0]) + (translate [0 0 row-radius])) + column-offset (cond + (= column 2) [0 2.82 -4.5] + (>= column 4) [0 -5.8 5.64] + :else [0 0 0]) + column-angle (* β (- 2 column)) + placed-shape (->> row-placed-shape + (translate [0 0 (- column-radius)]) + (rotate column-angle [0 1 0]) + (translate [0 0 column-radius]) + (translate column-offset))] + (->> placed-shape + (rotate (/ π 12) [0 1 0]) + (translate [0 0 13])))) + +(defn case-place [column row shape] + (let [row-placed-shape (->> shape + (translate [0 0 (- row-radius)]) + (rotate (* α (- 2 row)) [1 0 0]) + (translate [0 0 row-radius])) + column-offset [0 -4.35 5.64] + column-angle (* β (- 2 column)) + placed-shape (->> row-placed-shape + (translate [0 0 (- column-radius)]) + (rotate column-angle [0 1 0]) + (translate [0 0 column-radius]) + (translate column-offset))] + (->> placed-shape + (rotate (/ π 12) [0 1 0]) + (translate [0 0 13])))) + +(def key-holes + (apply union + (for [column columns + row rows + :when (or (not= column 0) + (not= row 4))] + (->> single-plate + (key-place column row))))) + +(def caps + (apply union + (for [column columns + row rows + :when (or (not= column 0) + (not= row 4))] + (->> (sa-cap (if (= column 5) 1 1)) + (key-place column row))))) + +;;;;;;;;;;;;;;;;;;;; +;; Web Connectors ;; +;;;;;;;;;;;;;;;;;;;; + +(def web-thickness 3.5) +(def post-size 0.1) +(def web-post (->> (cube post-size post-size web-thickness) + (translate [0 0 (+ (/ web-thickness -2) + plate-thickness)]))) + +(def post-adj (/ post-size 2)) +(def web-post-tr (translate [(- (/ mount-width 2) post-adj) (- (/ mount-height 2) post-adj) 0] web-post)) +(def web-post-tl (translate [(+ (/ mount-width -2) post-adj) (- (/ mount-height 2) post-adj) 0] web-post)) +(def web-post-bl (translate [(+ (/ mount-width -2) post-adj) (+ (/ mount-height -2) post-adj) 0] web-post)) +(def web-post-br (translate [(- (/ mount-width 2) post-adj) (+ (/ mount-height -2) post-adj) 0] web-post)) + +(defn triangle-hulls [& shapes] + (apply union + (map (partial apply hull) + (partition 3 1 shapes)))) + +(def connectors + (apply union + (concat + ;; Row connections + (for [column (drop-last columns) + row rows + :when (or (not= column 0) + (not= row 4))] + (triangle-hulls + (key-place (inc column) row web-post-tl) + (key-place column row web-post-tr) + (key-place (inc column) row web-post-bl) + (key-place column row web-post-br))) + + ;; Column connections + (for [column columns + row (drop-last rows) + :when (or (not= column 0) + (not= row 3))] + (triangle-hulls + (key-place column row web-post-bl) + (key-place column row web-post-br) + (key-place column (inc row) web-post-tl) + (key-place column (inc row) web-post-tr))) + + ;; Diagonal connections + (for [column (drop-last columns) + row (drop-last rows) + :when (or (not= column 0) + (not= row 3))] + (triangle-hulls + (key-place column row web-post-br) + (key-place column (inc row) web-post-tr) + (key-place (inc column) row web-post-bl) + (key-place (inc column) (inc row) web-post-tl)))))) + +;;;;;;;;;;;; +;; Thumbs ;; +;;;;;;;;;;;; + +(defn thumb-place [column row shape] + (let [cap-top-height (+ plate-thickness sa-profile-key-height) + α (/ π 12) + row-radius (+ (/ (/ (+ mount-height 1) 2) + (Math/sin (/ α 2))) + cap-top-height) + β (/ π 36) + column-radius (+ (/ (/ (+ mount-width 2) 2) + (Math/sin (/ β 2))) + cap-top-height) + #_(+ (/ (/ (+ pillar-width 5) 2) + (Math/sin (/ β 2))) + cap-top-height)] + (->> shape + (translate [0 0 (- row-radius)]) + (rotate (* α row) [1 0 0]) + (translate [0 0 row-radius]) + (translate [0 0 (- column-radius)]) + (rotate (* column β) [0 1 0]) + (translate [0 0 column-radius]) + (translate [mount-width 0 0]) + (rotate (* π (- 1/4 3/16)) [0 0 1]) + (rotate (/ π 12) [1 1 0]) + (translate [-52 -45 40])))) + +(defn thumb-2x-column [shape] + (thumb-place 0 -1/2 shape)) + +(defn thumb-2x+1-column [shape] + (union (thumb-place 1 -1/2 shape) + (thumb-place 1 1 shape))) + +(defn thumb-1x-column [shape] + (union (thumb-place 2 -1 shape) + (thumb-place 2 0 shape) + (thumb-place 2 1 shape))) + +(defn thumb-layout [shape] + (union + (thumb-2x-column shape) + (thumb-2x+1-column shape) + (thumb-1x-column shape))) + +(def double-plates + (let [plate-height (/ (- sa-double-length mount-height) 2) + top-plate (->> (cube mount-width plate-height web-thickness) + (translate [0 (/ (+ plate-height mount-height) 2) + (- plate-thickness (/ web-thickness 2))])) + stabilizer-cutout (union (->> (cube 14.2 3.5 web-thickness) + (translate [0.5 12 (- plate-thickness (/ web-thickness 2))]) + (color [1 0 0 1/2])) + (->> (cube 16 3.5 web-thickness) + (translate [0.5 12 (- plate-thickness (/ web-thickness 2) 1.4)]) + (color [1 0 0 1/2]))) + top-plate (difference top-plate stabilizer-cutout)] + (union top-plate (mirror [0 1 0] top-plate)))) + +(def thumbcaps + (union + (thumb-2x-column (sa-cap 2)) + (thumb-place 1 -1/2 (sa-cap 2)) + (thumb-place 1 1 (sa-cap 1)) + (thumb-1x-column (sa-cap 1)))) + +(def thumb-connectors + (union + (apply union + (concat + (for [column [2] row [1]] + (triangle-hulls (thumb-place column row web-post-br) + (thumb-place column row web-post-tr) + (thumb-place (dec column) row web-post-bl) + (thumb-place (dec column) row web-post-tl))) + (for [column [2] row [0 1]] + (triangle-hulls + (thumb-place column row web-post-bl) + (thumb-place column row web-post-br) + (thumb-place column (dec row) web-post-tl) + (thumb-place column (dec row) web-post-tr))))) + (let [plate-height (/ (- sa-double-length mount-height) 2) + thumb-tl (->> web-post-tl + (translate [0 plate-height 0])) + thumb-bl (->> web-post-bl + (translate [0 (- plate-height) 0])) + thumb-tr (->> web-post-tr + (translate [0 plate-height 0])) + thumb-br (->> web-post-br + (translate [0 (- plate-height) 0]))] + (union + + ;;Connecting the two doubles + (triangle-hulls (thumb-place 0 -1/2 thumb-tl) + (thumb-place 0 -1/2 thumb-bl) + (thumb-place 1 -1/2 thumb-tr) + (thumb-place 1 -1/2 thumb-br)) + + ;;Connecting the double to the one above it + (triangle-hulls (thumb-place 1 -1/2 thumb-tr) + (thumb-place 1 -1/2 thumb-tl) + (thumb-place 1 1 web-post-br) + (thumb-place 1 1 web-post-bl)) + + ;;Connecting the 4 with the double in the bottom left + (triangle-hulls (thumb-place 1 1 web-post-bl) + (thumb-place 1 -1/2 thumb-tl) + (thumb-place 2 1 web-post-br) + (thumb-place 2 0 web-post-tr)) + + ;;Connecting the two singles with the middle double + (hull (thumb-place 1 -1/2 thumb-tl) + (thumb-place 1 -1/2 thumb-bl) + (thumb-place 2 0 web-post-br) + (thumb-place 2 -1 web-post-tr)) + (hull (thumb-place 1 -1/2 thumb-tl) + (thumb-place 2 0 web-post-tr) + (thumb-place 2 0 web-post-br)) + (hull (thumb-place 1 -1/2 thumb-bl) + (thumb-place 2 -1 web-post-tr) + (thumb-place 2 -1 web-post-br)) + + ;;Connecting the thumb to everything + (triangle-hulls (thumb-place 0 -1/2 thumb-br) + (key-place 1 4 web-post-bl) + (thumb-place 0 -1/2 thumb-tr) + (key-place 1 4 web-post-tl) + (key-place 1 3 web-post-bl) + (thumb-place 0 -1/2 thumb-tr) + (key-place 0 3 web-post-br) + (key-place 0 3 web-post-bl) + (thumb-place 0 -1/2 thumb-tr) + (thumb-place 0 -1/2 thumb-tl) + (key-place 0 3 web-post-bl) + (thumb-place 1 -1/2 thumb-tr) + (thumb-place 1 1 web-post-br) + (key-place 0 3 web-post-bl) + (key-place 0 3 web-post-tl) + (thumb-place 1 1 web-post-br) + (thumb-place 1 1 web-post-tr)) + (hull (thumb-place 0 -1/2 web-post-tr) + (thumb-place 0 -1/2 thumb-tr) + (key-place 1 4 web-post-bl) + (key-place 1 4 web-post-tl)))))) + +(def thumb + (union + thumb-connectors + (thumb-layout (rotate (/ π 2) [0 0 1] single-plate)) + (thumb-place 0 -1/2 double-plates) + (thumb-place 1 -1/2 double-plates))) + +;;;;;;;;;; +;; Case ;; +;;;;;;;;;; + +;; In column units +(def right-wall-column (+ (last columns) 0.55)) +(def left-wall-column (- (first columns) 1/2)) +(def thumb-back-y 0.93) +(def thumb-right-wall (- -1/2 0.05)) +(def thumb-front-row (+ -1 0.07)) +(def thumb-left-wall-column (+ 5/2 0.05)) +(def back-y 0.02) + +(defn range-inclusive [start end step] + (concat (range start end step) [end])) + +(def wall-step 0.2) +(def wall-sphere-n 20) ;;Sphere resolution, lower for faster renders + +(defn wall-sphere-at [coords] + (->> (sphere 1) + (translate coords) + (with-fn wall-sphere-n))) + +(defn scale-to-range [start end x] + (+ start (* (- end start) x))) + +(defn wall-sphere-bottom [front-to-back-scale] + (wall-sphere-at [0 + (scale-to-range + (+ (/ mount-height -2) -3.5) + (+ (/ mount-height 2) 5.0) + front-to-back-scale) + -6])) + +(defn wall-sphere-top [front-to-back-scale] + (wall-sphere-at [0 + (scale-to-range + (+ (/ mount-height -2) -3.5) + (+ (/ mount-height 2) 3.5) + front-to-back-scale) + 10])) + +(def wall-sphere-top-back (wall-sphere-top 1)) +(def wall-sphere-bottom-back (wall-sphere-bottom 1)) +(def wall-sphere-bottom-front (wall-sphere-bottom 0)) +(def wall-sphere-top-front (wall-sphere-top 0)) + +(defn top-case-cover [place-fn sphere + x-start x-end + y-start y-end + step] + (apply union + (for [x (range-inclusive x-start (- x-end step) step) + y (range-inclusive y-start (- y-end step) step)] + (hull (place-fn x y sphere) + (place-fn (+ x step) y sphere) + (place-fn x (+ y step) sphere) + (place-fn (+ x step) (+ y step) sphere))))) + +(def front-wall + (let [step wall-step ;;0.1 + wall-step 0.05 ;;0.05 + place case-place + top-cover (fn [x-start x-end y-start y-end] + (top-case-cover place wall-sphere-top-front + x-start x-end y-start y-end + wall-step))] + (union + (apply union + (for [x (range-inclusive 0.7 (- right-wall-column step) step)] + (hull (place x 4 wall-sphere-top-front) + (place (+ x step) 4 wall-sphere-top-front) + (place x 4 wall-sphere-bottom-front) + (place (+ x step) 4 wall-sphere-bottom-front)))) + (apply union + (for [x (range-inclusive 0.5 0.7 0.01)] + (hull (place x 4 wall-sphere-top-front) + (place (+ x step) 4 wall-sphere-top-front) + (place 0.7 4 wall-sphere-bottom-front)))) + (top-cover 0.5 1.7 3.6 4) + (top-cover 1.59 2.41 3.35 4) ;; was 3.32 + (top-cover 2.39 3.41 3.6 4) + (apply union + (for [x (range 2 5)] + (union + (hull (place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (place (+ x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place x 4 web-post-bl) + (key-place x 4 web-post-br)) + (hull (place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place x 4 web-post-bl) + (key-place (- x 1) 4 web-post-br))))) + (hull (place right-wall-column 4 (translate [0 1 1] wall-sphere-bottom-front)) + (place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place 5 4 web-post-bl) + (key-place 5 4 web-post-br)) + (hull (place (+ 4 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place 4 4 web-post-br) + (key-place 5 4 web-post-bl)) + (hull (place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front)) + (place 1.7 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place 1 4 web-post-bl) + (key-place 1 4 web-post-br))))) + +(def back-wall + (let [step wall-step + wall-sphere-top-backtep 0.05 + place case-place + front-top-cover (fn [x-start x-end y-start y-end] + (apply union + (for [x (range-inclusive x-start (- x-end wall-sphere-top-backtep) wall-sphere-top-backtep) + y (range-inclusive y-start (- y-end wall-sphere-top-backtep) wall-sphere-top-backtep)] + (hull (place x y wall-sphere-top-back) + (place (+ x wall-sphere-top-backtep) y wall-sphere-top-back) + (place x (+ y wall-sphere-top-backtep) wall-sphere-top-back) + (place (+ x wall-sphere-top-backtep) (+ y wall-sphere-top-backtep) wall-sphere-top-back)))))] + (union + (apply union + (for [x (range-inclusive left-wall-column (- right-wall-column step) step)] + (hull (place x back-y wall-sphere-top-back) + (place (+ x step) back-y wall-sphere-top-back) + (place x back-y wall-sphere-bottom-back) + (place (+ x step) back-y wall-sphere-bottom-back)))) + (front-top-cover 1.56 2.44 back-y 0.1) + (front-top-cover 3.56 4.44 back-y 0.13) + (front-top-cover 4.3 right-wall-column back-y 0.13) + + + (hull (place left-wall-column 0 (translate [1 -1 1] wall-sphere-bottom-back)) + (place (+ left-wall-column 1) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-tl) + (key-place 0 0 web-post-tr)) + + (hull (place 5 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (place right-wall-column 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place 5 0 web-post-tl) + (key-place 5 0 web-post-tr)) + + (apply union + (for [x (range 1 5)] + (union + (hull (place (- x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (place (+ x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place x 0 web-post-tl) + (key-place x 0 web-post-tr)) + (hull (place (- x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place x 0 web-post-tl) + (key-place (- x 1) 0 web-post-tr))))) + (hull (place (- 5 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (place 5 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place 4 0 web-post-tr) + (key-place 5 0 web-post-tl))))) + +(def right-wall + (let [place case-place] + (union + (apply union + (map (partial apply hull) + (partition 2 1 + (for [scale (range-inclusive 0 1 0.01)] + (let [x (scale-to-range 4 0.02 scale)] + (hull (place right-wall-column x (wall-sphere-top scale)) + (place right-wall-column x (wall-sphere-bottom scale)))))))) + + (apply union + (concat + (for [x (range 0 5)] + (union + (hull (place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (key-place 5 x web-post-br) + (key-place 5 x web-post-tr)))) + (for [x (range 0 4)] + (union + (hull (place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (place right-wall-column (inc x) (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (key-place 5 x web-post-br) + (key-place 5 (inc x) web-post-tr)))) + [(union + (hull (place right-wall-column 0 (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (place right-wall-column 0.02 (translate [-1 -1 1] (wall-sphere-bottom 1))) + (key-place 5 0 web-post-tr)) + (hull (place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (place right-wall-column 4 (translate [-1 1 1] (wall-sphere-bottom 0))) + (key-place 5 4 web-post-br)))]))))) + +(def left-wall + (let [place case-place] + (union + (apply union + (for [x (range-inclusive -1 (- 1.6666 wall-step) wall-step)] + (hull (place left-wall-column x wall-sphere-top-front) + (place left-wall-column (+ x wall-step) wall-sphere-top-front) + (place left-wall-column x wall-sphere-bottom-front) + (place left-wall-column (+ x wall-step) wall-sphere-bottom-front)))) + (hull (place left-wall-column -1 wall-sphere-top-front) + (place left-wall-column -1 wall-sphere-bottom-front) + (place left-wall-column 0.02 wall-sphere-top-back) + (place left-wall-column 0.02 wall-sphere-bottom-back)) + (hull (place left-wall-column 0 (translate [1 -1 1] wall-sphere-bottom-back)) + (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-tl) + (key-place 0 0 web-post-bl)) + (hull (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back)) + (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-bl) + (key-place 0 1 web-post-bl)) + (hull (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back)) + (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (key-place 0 1 web-post-bl) + (key-place 0 2 web-post-bl)) + (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (key-place 0 2 web-post-bl) + (key-place 0 3 web-post-tl)) + (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (thumb-place 1 1 web-post-tr) + (key-place 0 3 web-post-tl)) + (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (thumb-place 1 1 web-post-tr) + (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)))))) + +(def thumb-back-wall + (let [step wall-step + top-step 0.05 + front-top-cover (fn [x-start x-end y-start y-end] + (apply union + (for [x (range-inclusive x-start (- x-end top-step) top-step) + y (range-inclusive y-start (- y-end top-step) top-step)] + (hull (thumb-place x y wall-sphere-top-back) + (thumb-place (+ x top-step) y wall-sphere-top-back) + (thumb-place x (+ y top-step) wall-sphere-top-back) + (thumb-place (+ x top-step) (+ y top-step) wall-sphere-top-back))))) + back-y thumb-back-y] + (union + (apply union + (for [x (range-inclusive 1/2 (- (+ 5/2 0.05) step) step)] + (hull (thumb-place x back-y wall-sphere-top-back) + (thumb-place (+ x step) back-y wall-sphere-top-back) + (thumb-place x back-y wall-sphere-bottom-back) + (thumb-place (+ x step) back-y wall-sphere-bottom-back)))) + (hull (thumb-place 1/2 back-y wall-sphere-top-back) + (thumb-place 1/2 back-y wall-sphere-bottom-back) + (case-place left-wall-column 1.6666 wall-sphere-top-front)) + (hull (thumb-place 1/2 back-y wall-sphere-bottom-back) + (case-place left-wall-column 1.6666 wall-sphere-top-front) + (case-place left-wall-column 1.6666 wall-sphere-bottom-front)) + (hull + (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tr) + (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tl)) + (hull + (thumb-place (+ 5/2 0.05) thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back)) + (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tl) + (thumb-place 2 1 web-post-tl))))) + +(def thumb-left-wall + (let [step wall-step + place thumb-place] + (union + (apply union + (for [x (range-inclusive (+ -1 0.07) (- 1.95 step) step)] + (hull (place thumb-left-wall-column x wall-sphere-top-front) + (place thumb-left-wall-column (+ x step) wall-sphere-top-front) + (place thumb-left-wall-column x wall-sphere-bottom-front) + (place thumb-left-wall-column (+ x step) wall-sphere-bottom-front)))) + (hull (place thumb-left-wall-column 1.95 wall-sphere-top-front) + (place thumb-left-wall-column 1.95 wall-sphere-bottom-front) + (place thumb-left-wall-column thumb-back-y wall-sphere-top-back) + (place thumb-left-wall-column thumb-back-y wall-sphere-bottom-back)) + + (hull + (thumb-place thumb-left-wall-column thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 1 web-post-tl) + (thumb-place 2 1 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 0 web-post-tl) + (thumb-place 2 1 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 0 web-post-tl) + (thumb-place 2 0 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 -1 web-post-tl) + (thumb-place 2 0 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column (+ -1 0.07) (translate [1 1 1] wall-sphere-bottom-front)) + (thumb-place 2 -1 web-post-tl) + (thumb-place 2 -1 web-post-bl))))) + +(def thumb-front-wall + (let [step wall-step ;;0.1 + wall-sphere-top-fronttep 0.05 ;;0.05 + place thumb-place + plate-height (/ (- sa-double-length mount-height) 2) + thumb-tl (->> web-post-tl + (translate [0 plate-height 0])) + thumb-bl (->> web-post-bl + (translate [0 (- plate-height) 0])) + thumb-tr (->> web-post-tr + (translate [-0 plate-height 0])) + thumb-br (->> web-post-br + (translate [-0 (- plate-height) 0]))] + (union + (apply union + (for [x (range-inclusive thumb-right-wall (- (+ 5/2 0.05) step) step)] + (hull (place x thumb-front-row wall-sphere-top-front) + (place (+ x step) thumb-front-row wall-sphere-top-front) + (place x thumb-front-row wall-sphere-bottom-front) + (place (+ x step) thumb-front-row wall-sphere-bottom-front)))) + + (hull (place thumb-right-wall thumb-front-row wall-sphere-top-front) + (place thumb-right-wall thumb-front-row wall-sphere-bottom-front) + (case-place 0.5 4 wall-sphere-top-front)) + (hull (place thumb-right-wall thumb-front-row wall-sphere-bottom-front) + (case-place 0.5 4 wall-sphere-top-front) + (case-place 0.7 4 wall-sphere-bottom-front)) + + (hull (place thumb-right-wall thumb-front-row wall-sphere-bottom-front) + (key-place 1 4 web-post-bl) + (place 0 -1/2 thumb-br) + (place 0 -1/2 web-post-br) + (case-place 0.7 4 wall-sphere-bottom-front)) + + (hull (place (+ 5/2 0.05) thumb-front-row (translate [1 1 1] wall-sphere-bottom-front)) + (place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (place 2 -1 web-post-bl) + (place 2 -1 web-post-br)) + + (hull (place thumb-right-wall thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (place 0 -1/2 thumb-bl) + (place 0 -1/2 thumb-br)) + (hull (place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (place 0 -1/2 thumb-bl) + (place 1 -1/2 thumb-bl) + (place 1 -1/2 thumb-br) + (place 2 -1 web-post-br))))) + +(def new-case + (union front-wall + right-wall + back-wall + left-wall + thumb-back-wall + thumb-left-wall + thumb-front-wall)) + +;;;;;;;;;;;; +;; Bottom ;; +;;;;;;;;;;;; + + +(defn bottom [height p] + (->> (project p) + (extrude-linear {:height height :twist 0 :convexity 0}) + (translate [0 0 (/ height 2)]))) + +(defn bottom-hull [p] + (hull p (bottom 1 p))) + + +(def bottom-key-guard (->> (cube mount-width mount-height web-thickness) + (translate [0 0 (+ (- (/ web-thickness 2)) -4.5)]))) +(def bottom-front-key-guard (->> (cube mount-width (/ mount-height 2) web-thickness) + (translate [0 (/ mount-height 4) (+ (- (/ web-thickness 2)) -4.5)]))) + +(def bottom-plate + (union + (apply union + (for [column columns + row (drop-last rows) ;; + :when (or (not= column 0) + (not= row 4))] + (->> bottom-key-guard + (key-place column row)))) + (thumb-layout (rotate (/ π 2) [0 0 1] bottom-key-guard)) + (apply union + (for [column columns + row [(last rows)] ;; + :when (or (not= column 0) + (not= row 4))] + (->> bottom-front-key-guard + (key-place column row)))) + (let [shift #(translate [0 0 (+ (- web-thickness) -5)] %) + web-post-tl (shift web-post-tl) + web-post-tr (shift web-post-tr) + web-post-br (shift web-post-br) + web-post-bl (shift web-post-bl) + half-shift-correction #(translate [0 (/ mount-height 2) 0] %) + half-post-br (half-shift-correction web-post-br) + half-post-bl (half-shift-correction web-post-bl) + row-connections (concat + (for [column (drop-last columns) + row (drop-last rows) + :when (or (not= column 0) + (not= row 4))] + (triangle-hulls + (key-place (inc column) row web-post-tl) + (key-place column row web-post-tr) + (key-place (inc column) row web-post-bl) + (key-place column row web-post-br))) + (for [column (drop-last columns) + row [(last rows)] + :when (or (not= column 0) + (not= row 4))] + (triangle-hulls + (key-place (inc column) row web-post-tl) + (key-place column row web-post-tr) + (key-place (inc column) row half-post-bl) + (key-place column row half-post-br)))) + column-connections (for [column columns + row (drop-last rows) + :when (or (not= column 0) + (not= row 3))] + (triangle-hulls + (key-place column row web-post-bl) + (key-place column row web-post-br) + (key-place column (inc row) web-post-tl) + (key-place column (inc row) web-post-tr))) + diagonal-connections (for [column (drop-last columns) + row (drop-last rows) + :when (or (not= column 0) + (not= row 3))] + (triangle-hulls + (key-place column row web-post-br) + (key-place column (inc row) web-post-tr) + (key-place (inc column) row web-post-bl) + (key-place (inc column) (inc row) web-post-tl))) + main-keys-bottom (concat row-connections + column-connections + diagonal-connections) + front-wall (concat + (for [x (range 2 5)] + (union + (hull (case-place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (case-place (+ x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place x 4 half-post-bl) + (key-place x 4 half-post-br)) + (hull (case-place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place x 4 half-post-bl) + (key-place (- x 1) 4 half-post-br)))) + [(hull (case-place right-wall-column 4 (translate [0 1 1] wall-sphere-bottom-front)) + (case-place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place 5 4 half-post-bl) + (key-place 5 4 half-post-br)) + (hull (case-place (+ 4 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (case-place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (key-place 4 4 half-post-br) + (key-place 5 4 half-post-bl))]) + right-wall (concat + (for [x (range 0 4)] + (hull (case-place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (key-place 5 x web-post-br) + (key-place 5 x web-post-tr))) + (for [x (range 0 4)] + (hull (case-place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (case-place right-wall-column (inc x) (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (key-place 5 x web-post-br) + (key-place 5 (inc x) web-post-tr))) + [(union + (hull (case-place right-wall-column 0 (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (case-place right-wall-column 0.02 (translate [-1 -1 1] (wall-sphere-bottom 1))) + (key-place 5 0 web-post-tr) + ) + (hull (case-place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (case-place right-wall-column 4 (translate [0 1 1] (wall-sphere-bottom 0))) + (key-place 5 4 half-post-br) + ) + (hull (case-place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2))) + (key-place 5 4 half-post-br) + (key-place 5 4 web-post-tr)))]) + back-wall (concat + (for [x (range 1 6)] + (union + (hull (case-place (- x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (case-place (+ x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place x 0 web-post-tl) + (key-place x 0 web-post-tr)) + (hull (case-place (- x 1/2) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place x 0 web-post-tl) + (key-place (- x 1) 0 web-post-tr)))) + [(hull (case-place left-wall-column 0 (translate [1 -1 1] wall-sphere-bottom-back)) + (case-place (+ left-wall-column 1) 0 (translate [0 -1 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-tl) + (key-place 0 0 web-post-tr))]) + left-wall (let [place case-place] + [(hull (place left-wall-column 0 (translate [1 -1 1] wall-sphere-bottom-back)) + (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-tl) + (key-place 0 0 web-post-bl)) + (hull (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back)) + (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back)) + (key-place 0 0 web-post-bl) + (key-place 0 1 web-post-bl)) + (hull (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back)) + (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (key-place 0 1 web-post-bl) + (key-place 0 2 web-post-bl)) + (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (key-place 0 2 web-post-bl) + (key-place 0 3 web-post-tl))]) + thumbs [(hull (thumb-place 0 -1/2 web-post-bl) + (thumb-place 0 -1/2 web-post-tl) + (thumb-place 1 -1/2 web-post-tr) + (thumb-place 1 -1/2 web-post-br)) + (hull (thumb-place 1 -1/2 web-post-tr) + (thumb-place 1 -1/2 web-post-tl) + (thumb-place 1 1 web-post-bl) + (thumb-place 1 1 web-post-br)) + (hull (thumb-place 2 -1 web-post-tr) + (thumb-place 2 -1 web-post-tl) + (thumb-place 2 0 web-post-bl) + (thumb-place 2 0 web-post-br)) + (hull (thumb-place 2 0 web-post-tr) + (thumb-place 2 0 web-post-tl) + (thumb-place 2 1 web-post-bl) + (thumb-place 2 1 web-post-br)) + (triangle-hulls (thumb-place 2 1 web-post-tr) + (thumb-place 1 1 web-post-tl) + (thumb-place 2 1 web-post-br) + (thumb-place 1 1 web-post-bl) + (thumb-place 2 0 web-post-tr) + (thumb-place 1 -1/2 web-post-tl) + (thumb-place 2 0 web-post-br) + (thumb-place 1 -1/2 web-post-bl) + (thumb-place 2 -1 web-post-tr) + (thumb-place 2 -1 web-post-br)) + (hull (thumb-place 2 -1 web-post-br) + (thumb-place 1 -1/2 web-post-bl) + (thumb-place 1 -1 web-post-bl)) + (hull (thumb-place 1 -1/2 web-post-bl) + (thumb-place 1 -1 web-post-bl) + (thumb-place 1 -1/2 web-post-br) + (thumb-place 1 -1 web-post-br)) + (hull (thumb-place 0 -1/2 web-post-bl) + (thumb-place 0 -1 web-post-bl) + (thumb-place 0 -1/2 web-post-br) + (thumb-place 0 -1 web-post-br)) + (hull (thumb-place 0 -1/2 web-post-bl) + (thumb-place 0 -1 web-post-bl) + (thumb-place 1 -1/2 web-post-br) + (thumb-place 1 -1 web-post-br))] + thumb-back-wall [(hull + (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tr) + (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tl)) + + (hull + (thumb-place (+ 5/2 0.05) thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back)) + (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (thumb-place 1 1 web-post-tl) + (thumb-place 2 1 web-post-tl)) + (hull + (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back)) + (case-place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front)) + (key-place 0 3 web-post-tl) + (thumb-place 1 1 web-post-tr)) + ] + thumb-left-wall [(hull + (thumb-place thumb-left-wall-column thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 1 web-post-tl) + (thumb-place 2 1 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 0 web-post-tl) + (thumb-place 2 1 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 0 web-post-tl) + (thumb-place 2 0 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place 2 -1 web-post-tl) + (thumb-place 2 0 web-post-bl)) + (hull + (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back)) + (thumb-place thumb-left-wall-column (+ -1 0.07) (translate [1 1 1] wall-sphere-bottom-front)) + (thumb-place 2 -1 web-post-tl) + (thumb-place 2 -1 web-post-bl))] + thumb-front-wall [(hull (thumb-place (+ 5/2 0.05) thumb-front-row (translate [1 1 1] wall-sphere-bottom-front)) + (thumb-place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (thumb-place 2 -1 web-post-bl) + (thumb-place 2 -1 web-post-br)) + (hull (thumb-place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (thumb-place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (thumb-place 0 -1 web-post-bl) + (thumb-place 1 -1 web-post-bl) + (thumb-place 1 -1 web-post-br) + (thumb-place 2 -1 web-post-br)) + (hull (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front)) + (thumb-place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front)) + (thumb-place 0 -1 web-post-bl) + (thumb-place 0 -1 web-post-br))] + thumb-inside [(triangle-hulls + (thumb-place 1 1 web-post-tr) + (key-place 0 3 web-post-tl) + (thumb-place 1 1 web-post-br) + (key-place 0 3 web-post-bl) + (thumb-place 1 -1/2 web-post-tr) + (thumb-place 0 -1/2 web-post-tl) + (key-place 0 3 web-post-bl) + (thumb-place 0 -1/2 web-post-tr) + (key-place 0 3 web-post-br) + (key-place 1 3 web-post-bl) + (thumb-place 0 -1/2 web-post-tr) + (key-place 1 4 web-post-tl) + (key-place 1 4 half-post-bl)) + + (hull + (thumb-place 0 -1/2 web-post-tr) + (thumb-place 0 -1/2 web-post-br) + (key-place 1 4 half-post-bl)) + + (hull + (key-place 1 4 half-post-bl) + (key-place 1 4 half-post-br) + (case-place (- 2 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front)) + (case-place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front))) + + (hull + (thumb-place 0 -1 web-post-br) + (thumb-place 0 -1/2 web-post-br) + (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front)) + (key-place 1 4 (translate [0 0 8.5] web-post-bl)) + (key-place 1 4 half-post-bl) + )] + stands (let [bumper-diameter 9.6 + bumper-radius (/ bumper-diameter 2) + stand-diameter (+ bumper-diameter 2) + stand-radius (/ stand-diameter 2) + stand-at #(difference (->> (sphere stand-radius) + (translate [0 0 (+ (/ stand-radius -2) -4.5)]) + % + (bottom-hull)) + (->> (cube stand-diameter stand-diameter stand-radius) + (translate [0 0 (/ stand-radius -2)]) + %) + (->> (sphere bumper-radius) + (translate [0 0 (+ (/ stand-radius -2) -4.5)]) + % + (bottom 1.5)))] + [(stand-at #(key-place 0 1 %)) + (stand-at #(thumb-place 1 -1/2 %)) + (stand-at #(key-place 5 0 %)) + (stand-at #(key-place 5 3 %))])] + (apply union + (concat + main-keys-bottom + front-wall + right-wall + back-wall + left-wall + thumbs + thumb-back-wall + thumb-left-wall + thumb-front-wall + thumb-inside + stands))))) + +(def screw-hole (->> (cylinder 1.5 60) + (translate [0 0 3/2]) + (with-fn wall-sphere-n))) + +(def screw-holes + (union + (key-place (+ 4 1/2) 1/2 screw-hole) + (key-place (+ 4 1/2) (+ 3 1/2) screw-hole) + (thumb-place 2 -1/2 screw-hole))) + +(defn circuit-cover [width length height] + (let [cover-sphere-radius 1 + cover-sphere (->> (sphere cover-sphere-radius) + (with-fn 20)) + cover-sphere-z (+ (- height) (- cover-sphere-radius)) + cover-sphere-x (+ (/ width 2) cover-sphere-radius) + cover-sphere-y (+ (/ length 2) (+ cover-sphere-radius)) + cover-sphere-tl (->> cover-sphere + (translate [(- cover-sphere-x) (- cover-sphere-y) cover-sphere-z]) + (key-place 1/2 3/2)) + cover-sphere-tr (->> cover-sphere + (translate [cover-sphere-x (- cover-sphere-y) cover-sphere-z]) + (key-place 1/2 3/2)) + cover-sphere-br (->> cover-sphere + (translate [cover-sphere-x cover-sphere-y cover-sphere-z]) + (key-place 1/2 3/2)) + cover-sphere-bl (->> cover-sphere + (translate [(- cover-sphere-x) cover-sphere-y cover-sphere-z]) + (key-place 1/2 3/2)) + + lower-to-bottom #(translate [0 0 (+ (- cover-sphere-radius) -5.5)] %) + bl (->> cover-sphere lower-to-bottom (key-place 0 1/2)) + br (->> cover-sphere lower-to-bottom (key-place 1 1/2)) + tl (->> cover-sphere lower-to-bottom (key-place 0 5/2)) + tr (->> cover-sphere lower-to-bottom (key-place 1 5/2)) + + mlb (->> cover-sphere + (translate [(- cover-sphere-x) 0 (+ (- height) -1)]) + (key-place 1/2 3/2)) + mrb (->> cover-sphere + (translate [cover-sphere-x 0 (+ (- height) -1)]) + (key-place 1/2 3/2)) + + mlt (->> cover-sphere + (translate [(+ (- cover-sphere-x) -4) 0 -6]) + (key-place 1/2 3/2)) + mrt (->> cover-sphere + (translate [(+ cover-sphere-x 4) 0 -6]) + (key-place 1/2 3/2))] + (union + (hull cover-sphere-bl cover-sphere-br cover-sphere-tl cover-sphere-tr) + (hull cover-sphere-br cover-sphere-bl bl br) + (hull cover-sphere-tr cover-sphere-tl tl tr) + (hull cover-sphere-tl tl mlb mlt) + (hull cover-sphere-bl bl mlb mlt) + (hull cover-sphere-tr tr mrb mrt) + (hull cover-sphere-br br mrb mrt)))) + +(def io-exp-width 10) +(def io-exp-height 8) +(def io-exp-length 36) + +(def teensy-width 20) +(def teensy-height 12) +(def teensy-length 33) + +(def io-exp-cover (circuit-cover io-exp-width io-exp-length io-exp-height)) +(def teensy-cover (circuit-cover teensy-width teensy-length teensy-height)) + +(def trrs-diameter 6.6) +(def trrs-radius (/ trrs-diameter 2)) +(def trrs-hole-depth 10) + +(def trrs-hole (->> (union (cylinder trrs-radius trrs-hole-depth) + (->> (cube trrs-diameter (+ trrs-radius 5) trrs-hole-depth) + (translate [0 (/ (+ trrs-radius 5) 2) 0]))) + (rotate (/ π 2) [1 0 0]) + (translate [0 (+ (/ mount-height 2) 4) (- trrs-radius)]) + (with-fn 50))) + +(def trrs-hole-just-circle + (->> (cylinder trrs-radius trrs-hole-depth) + (rotate (/ π 2) [1 0 0]) + (translate [0 (+ (/ mount-height 2) 4) (- trrs-radius)]) + (with-fn 50) + (key-place 1/2 0))) + +(def trrs-box-hole (->> (cube 14 14 7 ) + (translate [0 1 -3.5]))) + + +(def trrs-cutout + (->> (union trrs-hole + trrs-box-hole) + (key-place 1/2 0))) + +(def teensy-pcb-thickness 1.6) +(def teensy-offset-height 5) + +(def teensy-pcb (->> (cube 18 30.5 teensy-pcb-thickness) + (translate [0 0 (+ (/ teensy-pcb-thickness -2) (- teensy-offset-height))]) + (key-place 1/2 3/2) + (color [1 0 0]))) + +(def teensy-support + (difference + (union + (->> (cube 3 3 9) + (translate [0 0 -2]) + (key-place 1/2 3/2) + (color [0 1 0])) + (hull (->> (cube 3 6 9) + (translate [0 0 -2]) + (key-place 1/2 2) + (color [0 0 1])) + (->> (cube 3 3 (+ teensy-pcb-thickness 3)) + (translate [0 (/ 30.5 -2) (+ (- teensy-offset-height) + #_(/ (+ teensy-pcb-thickness 3) -2) + )]) + (key-place 1/2 3/2) + (color [0 0 1])))) + teensy-pcb + (->> (cube 18 30.5 teensy-pcb-thickness) + (translate [0 1.5 (+ (/ teensy-pcb-thickness -2) (- teensy-offset-height) -1)]) + (key-place 1/2 3/2) + (color [1 0 0])))) + +(def usb-cutout + (let [hole-height 6.2 + side-radius (/ hole-height 2) + hole-width 10.75 + side-cylinder (->> (cylinder side-radius teensy-length) + (with-fn 20) + (translate [(/ (- hole-width hole-height) 2) 0 0]))] + (->> (hull side-cylinder + (mirror [-1 0 0] side-cylinder)) + (rotate (/ π 2) [1 0 0]) + (translate [0 (/ teensy-length 2) (- side-radius)]) + (translate [0 0 (- 1)]) + (translate [0 0 (- teensy-offset-height)]) + (key-place 1/2 3/2)))) + +;;;;;;;;;;;;;;;;;; +;; Final Export ;; +;;;;;;;;;;;;;;;;;; + +(def dactyl-bottom-right + (difference + (union + teensy-cover + (difference + bottom-plate + (hull teensy-cover) + new-case + teensy-cover + trrs-cutout + (->> (cube 1000 1000 10) (translate [0 0 -5])) + screw-holes)) + usb-cutout)) + +(def dactyl-bottom-left + (mirror [-1 0 0] + (union + io-exp-cover + (difference + bottom-plate + (hull io-exp-cover) + new-case + io-exp-cover + trrs-cutout + (->> (cube 1000 1000 10) (translate [0 0 -5])) + screw-holes)))) + +(def dactyl-top-right + (difference + (union key-holes + connectors + thumb + new-case + teensy-support) + trrs-hole-just-circle + screw-holes)) + +(def dactyl-top-left + (mirror [-1 0 0] + (difference + (union key-holes + connectors + thumb + new-case) + trrs-hole-just-circle + screw-holes))) + +(spit "things/dactyl-top-right.scad" + (write-scad dactyl-top-right)) + +(spit "things/dactyl-bottom-right.scad" + (write-scad dactyl-bottom-right)) + +(spit "things/dactyl-top-left.scad" + (write-scad dactyl-top-left)) + +(spit "things/dactyl-bottom-left.scad" + (write-scad dactyl-bottom-left)) |