Did you know there's a whole class rolling objects that's not spherical or cylindrical and still able to roll in a given direction? I didn't!
As a fun little experiment I wanted to code and print one.
The code to construct an oloid is really super simple, you can construct one by creating a convex hull around two perpendicular circles positioned with the centers at radius distance from each other, like this:
(defn olid [radius] (let [c (m/cylinder radius 0.1) a (m/translate [0 (/ radius -2)] c) b (->> c (m/rotate [0 (/ Math/PI 2) 0]) (m/translate [0 (/ radius 2) 0] ))] (m/hull a b)))
And let it roll!
If i were to print it again, I would probably use a higher in-fill percentage to make it a bit heavier. You can also buy these made in metal, which probably feels amazing!
Some people have asked how I use Clojure and OpenSCAD, how to set up the live reloading, etc, as the documentation is a bit lacking.
(defn render [model] (spit "render.scad" (scad-clj.scad/write-scad model)))
I have this simple helper defined that writes a model to a file. Open the file using OpenSCAD. OpenSCAD will watch the file, and every time you call render on something, it will update the display. You can hide all UI elements other than the display in OpenSCAD, put it side by side with the editor, and even set them up to use the same theme - creating the illusion that your editor and OpenSCAD is the same program.
(render (m/union (m/cylinder 10 10) (m/cube 10 20 20)))
I usually leave a call to render at the bottom of the file I'm working on, and evaluate it as needed. That way a quick call to
cider-eval-buffer will update the display.
Adereth got some great tips on how to get started over at his blog. Be sure to check out his amazing keyboard!
The y-split function
I got asked about the y-split function used in the video. It's a simple axis split with a hollowed out cube to make it easier to print, no supports required. I didn't want to make the video more complex than necessary, so I simply used it like magic.
It was custom made for this oloid and looked like this. Quick and dirty, and a bit repetitious.
(defn y-split [obj] (let [box (m/cube 10 10 10) holed-obj (m/difference obj (m/scale [1.005 1.2 1.005] box)) a (->> (m/cube 100 100 100) (m/translate [0 -50 0]) (m/intersection holed-obj) (m/rotate [(/ Math/PI -2) 0 0]) (m/translate [35 0 0])) b (->> (m/cube 100 100 100) (m/translate [0 50 0]) (m/intersection holed-obj) (m/rotate [(/ Math/PI 2) 0 0]) (m/translate [-35 0 0]))] (m/union a b (m/translate [0 -20 5] box))))
I just guessed at the tolerances needed, and it worked perfectly, no glue needed. It seems like a useful function for 3D-printing with Clojure, so I think I'll make a general one later.