{"id":345,"date":"2018-01-13T17:51:31","date_gmt":"2018-01-13T17:51:31","guid":{"rendered":"http:\/\/ceptimus.co.uk\/?p=345"},"modified":"2018-01-13T17:51:31","modified_gmt":"2018-01-13T17:51:31","slug":"solids-of-constant-width-the-meissner-tetrahedron-in-openscad","status":"publish","type":"post","link":"https:\/\/ceptimus.co.uk\/index.php\/2018\/01\/13\/solids-of-constant-width-the-meissner-tetrahedron-in-openscad\/","title":{"rendered":"Solids of constant width &#8211; the Meissner Tetrahedron &#8211; in OpenSCAD"},"content":{"rendered":"<p>Lots of people know about curves of constant width &#8211; for example the UK 50p and 20p coins: despite their apparent non-roundness they have constant width when measured by parallel jawed calipers or the mechanisms inside vending machines.\u00a0 If the shapes of these coins are extruded as prisms they can be used as rollers for moving heavy equipment around on hard floors.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/Reuleaux_triangle_Animation.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-346\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/Reuleaux_triangle_Animation.gif\" alt=\"\" width=\"250\" height=\"250\" \/><\/a>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reuleaux_triangle\">Reuleaux Triangle<\/a>, pictured above is the best known curve of constant width (other than the circle, of course).\u00a0 Notice in the animation above the triangle never quite reaches into the corners of the square, but it does remain in contact with all four sides of the square at all times.<\/p>\n<p><iframe loading=\"lazy\" title=\"Solids of constant width\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/xZL0uoDD2kg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>In terms of three-dimensional solids the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reuleaux_tetrahedron\">Reuleaux Tetrahedron<\/a> is the analogue of the Reuleaux Triangle, but it is NOT a solid of constant width &#8211; it comes close but the edges stick out a bit too much: it&#8217;s about 2.5% wider across the midpoints of two edges than it is from a vertex to the opposite face.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/ReuleauxTetrahedron_Animation.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-347\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/ReuleauxTetrahedron_Animation.gif\" alt=\"\" width=\"240\" height=\"240\" \/><\/a>You can produce solids of constant width fairly easily by rotating a curve of constant width &#8211; imagine spinning a 50p coin on its edge: providing the same point of the edge remains in contact with the surface it is spinning on, the volume swept out by the coin is a solid of constant width.\u00a0 However these kind of solids are fairly boring because cross-sections perpendicular to the axis of rotation are just circles.<\/p>\n<p>Much more interesting are the Meissner Tetrahedra.\u00a0 In 1911 the Swiss mathematician, Ernst Mei\u00dfner demonstrated how the Reuleaux Tetrahedron could be patched by rounding off three of its edges to produce true solids of constant width: there are two ways of doing it: one where the three rounded edges share a common vertex, and the other where the three rounded edges are around one face of the tetrahedron.<\/p>\n<p>I set out to model the tetrahedra using the <a href=\"http:\/\/www.openscad.org\/index.html\">OpenSCAD CAD<\/a> program, so that they could be printed on a 3D printer. OpenSCAD is free software available for Linux\/UNIX, Windows and Mac OS X.\u00a0 I recommend it.<\/p>\n<p>So we start with the Reuleaux Tetrahedron.\u00a0 It&#8217;s fairly easy to model as it&#8217;s formed by the intersection of four spheres with their centres located at the vertices of a regular tetrahedron where all the tetrahedron edges have the same length as the radius of the spheres.\u00a0 As we&#8217;re making solids of constant width we name the radii of the spheres, &#8216;width&#8217;, and the edge lengths of the tetrahedron are also &#8216;width&#8217;.\u00a0 This is a little disorienting at first, but you get used to it.<\/p>\n<p>Wikipedia gives the Cartesian coordinates for the vertices of a tetrahedron falling on the unit sphere with the lower face level as:<\/p>\n<p>v1 = ( sqrt(8\/9), 0 , -1\/3 )<br \/>\nv2 = ( -sqrt(2\/9), sqrt(2\/3), -1\/3 )<br \/>\nv3 = ( -sqrt(2\/9), -sqrt(2\/3), -1\/3 )<br \/>\nv4 = ( 0 , 0 , 1 )<br \/>\nwith the edge length of sqrt(8\/3).<\/p>\n<p>Building that information into an OpenSCAD model and allowing for scaling the resulting Reuleaux Tetrahedron to any desired size gives the code:<\/p>\n<pre>\/\/ Reuleaux Tetrahedron\n\/\/ ceptimus 2018-01-13\n\nwidth = 50; \/\/ width of the object to be printed\n$fn = 50; \/\/ higher numbers give smoother object but (much) longer render times\n\n\/\/ vertices and edge length of Reuleaux Tetrahedron from Wikipedia\nv1 = [sqrt(8\/9), 0, -1\/3];\nv2 = [-sqrt(2\/9), sqrt(2\/3), -1\/3];\nv3 = [-sqrt(2\/9), -sqrt(2\/3), -1\/3];\nv4 = [0, 0, 1];\na = sqrt(8\/3); \/\/ edge length given by above vertices\n\nk = width \/ a; \/\/ scaling constant to generate desired width from standard vertices\n\nreuleauxTetrahedron();\n\nmodule reuleauxTetrahedron() {\n    intersection() {\n        translate(v1 * k)\n            sphere(r = width);\n        translate(v2 * k)\n            sphere(r = width);\n        translate(v3 * k)\n            sphere(r = width);\n        translate(v4 * k)\n            rotate([90, 0, 0]) \/\/ use similar part of sphere for bottom face as other faces - OpenScad renders the parts of 'spheres' near the 'poles' differently\n                sphere(r = width);\n    }\n}\n<\/pre>\n<p>&#8230;which results in this view:<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronCoarse.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-353\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronCoarse-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>If we alter the $fn parameter we can make it much smoother.\u00a0 With $fn = 300; it still previews (F5) almost instantly but rendering (F6) takes a long time unless you have a very fast machine.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmooth.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-354\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmooth-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>Now for the changes necessary to round off some edges to make it a true solid of constant width.\u00a0 If we take one of the faces of the underlying tetrahedron and continue it out till it cuts one of the spherical faces of the Reuleaux Tetrahedron we get this two dimensional shape for the portion of that flat face between the triangle and the curved outer surface.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/curve.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-356\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/curve-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>Here&#8217;s the code that produces that shape:<\/p>\n<pre>intersection() {\n    \/\/ 6 is just an empirical 'big enough' figure so that the arc is contained within the rectangle\n    translate([-width \/ 6, -sqrt(2\/3) * k, 0])\n        square([width \/ 6, width]);\n    translate([(sqrt(2\/9) + sqrt(8\/9)) * k, 0, 0])\n        circle(r = width);\n}\n<\/pre>\n<p>And we can use OpenSCAD&#8217;s rotate_extrude() to spin that shape around and produce the three dimensional shape I call a &#8216;spindle&#8217; &#8211; which is the shape we need to round off three of the Reuleaux Tetrahedron&#8217;s edges so as to make it constant width.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/spindle.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-357\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/spindle-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a><\/p>\n<p>Now we need to lean the spindle over and line its two vertices up with two vertices of the tetrahedron to round off the edges, but first we need to remove some of the edge material of the tetrahedron that would otherwise project out beyond the spindle.\u00a0 To do this we introduce the angle, alpha, which is half the angle formed by any two intersecting regular (not curved) tetrahedron faces.\u00a0 This angle of a tetrahedron is called the &#8216;dihedral angle&#8217; and alpha is half of that &#8211; about 35.2644 degrees.<\/p>\n<p>My sketch makes a wedge shape with the dihedral angle (2 x alpha) for the front edge of the wedge and the wedge long enough to fit against one edge of the underlying tetrahedron and deep enough to &#8216;include&#8217; all the material we need to cut away from one edge of the Reuleaux Tetrahedron before inserting the spindle.\u00a0 Here&#8217;s what the tetrahedron looks like when the wedge is shown in its &#8216;cutting position&#8217;.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothPlusWedge.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-359\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothPlusWedge-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>And here&#8217;s the code that does it:<\/p>\n<pre>alpha = atan(2 * sqrt(2)) \/ 2; \/\/ half 'dihedral angle' (amount the three edges up to the apex lean inwards from the vertical)\n\nreuleauxTetrahedron();\ncolor([1, 0, 0])\n    translate(v1 * k)\n        rotate([0, -alpha, 0])\n            wedge();\n\nmodule wedge() { \/\/ used to subtract three sharp edges of Reuleaux Tetrahedron prior to adding the rounded 'spindle' edges\n    hull() {\n        rotate([0, 0, -alpha])\n            \/\/ 5 is just an empirical 'big enough' figure so that the wedge includes the Reuleaux Tetrahedron edge when placed appropriately\n            cube([width\/5, 0.001, width]);\n        rotate([0, 0, alpha])\n            translate([0, -0.001, 0])\n                cube([width\/5, 0.001, width]);        \n    }\n}\n<\/pre>\n<p>Now we can use OpenSCAD&#8217;s difference() function to subtract the wedge away from the Reuleaux Tetrahedron.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothMinusWedge.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-360\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothMinusWedge-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>And then put the spindle in place to patch the edge.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothPlusSpindle.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-361\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/reuleauxTetrahedronSmoothPlusSpindle-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>Repeat that procedure three times and we&#8217;ve completed one of the two varieties of Meissner Tetrahedron.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/meissnerTetrahedronCommonVertex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-362\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/meissnerTetrahedronCommonVertex-300x229.png\" alt=\"\" width=\"300\" height=\"229\" \/><\/a>Note that only three of the edges are rounded &#8211; the bottom (far) three edges are still sharp &#8211; if you were to round those off as well then the resulting solid WOULDN&#8217;T have constant width &#8211; the distance between opposite &#8216;edges&#8217; would then be too small.<\/p>\n<p>Here&#8217;s the complete code for the finished Meissner Tetrahedron.\u00a0 Remember that you can increase the value of $fn to get a smoother rendering, but that although the preview (F5) will still work fast enough, the rendering (F6) can bring even a fast PC to its knees.<\/p>\n<pre>\/\/ Meissner Tetrahedron (solid of constant width) - common vertex variant\n\/\/ ceptimus 2018-01-13\n\nwidth = 50; \/\/ width of the object to be printed\n$fn = 50; \/\/ higher numbers give smoother object but (much) longer render times\n\n\/\/ vertices and edge length of Reuleaux Tetrahedron from Wikipedia\nv1 = [sqrt(8\/9), 0, -1\/3];\nv2 = [-sqrt(2\/9), sqrt(2\/3), -1\/3];\nv3 = [-sqrt(2\/9), -sqrt(2\/3), -1\/3];\nv4 = [0, 0, 1];\na = sqrt(8\/3); \/\/ edge length given by above vertices\n\nk = width \/ a; \/\/ scaling constant to generate desired width from standard vertices\n\nalpha = atan(2 * sqrt(2)) \/ 2; \/\/ half 'dihedral angle' (amount the three edges up to the apex lean inwards from the vertical)\n\ndifference() {\n    reuleauxTetrahedron();\n    for (angle = [0 : 120 : 240])\n        rotate([0, 0, angle])\n            translate(v1 * k)\n                rotate([0, -alpha, 0])\n                    wedge();\n}\ncolor([1, 0, 0])\n    for (angle = [0 : 120 : 240])\n        rotate([0, 0, angle])\n            translate(v1 * k)\n                rotate([0, -alpha, 0])\n                    spindle();\n\nmodule reuleauxTetrahedron() {\n    intersection() {\n        translate(v1 * k)\n            sphere(r = width);\n        translate(v2 * k)\n            sphere(r = width);\n        translate(v3 * k)\n            sphere(r = width);\n        translate(v4 * k)\n            rotate([90, 0, 0]) \/\/ use similar part of sphere for bottom face as other faces - OpenSCAD renders the parts of 'spheres' near the 'poles' differently\n                sphere(r = width);\n    }\n}\n\nmodule wedge() { \/\/ used to subtract three sharp edges of Reuleaux Tetrahedron prior to adding the rounded 'spindle' edges\n    hull() {\n        rotate([0, 0, -alpha])\n            \/\/ 5 is just an empirical 'big enough' figure so that the wedge includes the Reuleaux Tetrahedron edge when placed appropriately\n            cube([width\/5, 0.001, width]);\n        rotate([0, 0, alpha])\n            translate([0, -0.001, 0])\n                cube([width\/5, 0.001, width]);        \n    }\n}\n\n\/\/ rotate the curve produced where the Reuleaux Tetrahedron surface intersects with the (extended) underlying tetrahedron face\n\/\/ this produces the correct spindle shape for rounding off three edges of the Reuleaux Tetrahedron to produce the Meissner Tetrahedron\nmodule spindle() {\n    translate([0, 0, width\/2])\n        rotate_extrude()\n            intersection() {\n                \/\/ 6 is just an empirical 'big enough' figure so that the arc is contained within the rectangle\n                translate([-width \/ 6, -sqrt(2\/3) * k, 0])\n                    square([width \/ 6, width]);\n                translate([(sqrt(2\/9) + sqrt(8\/9)) * k, 0, 0])\n                    circle(r = width);\n            }\n}<\/pre>\n<p>Here&#8217;s the second variant where the three rounded edges are in a triangle rather than sharing a common vertex.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/meissnerTetrahedronTriangle.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-374\" src=\"https:\/\/ceptimus.co.uk\/wp-content\/uploads\/2018\/01\/meissnerTetrahedronTriangle-300x228.png\" alt=\"\" width=\"300\" height=\"228\" \/><\/a><\/p>\n<p>Here are the OpenSCAD files for the two variants.<\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/meissnerTetrahedronCommonVertex.scad\" target=\"_blank\" rel=\"noopener\">https:\/\/ceptimus.co.uk\/meissnerTetrahedronCommonVertex.scad<\/a><\/p>\n<p><a href=\"https:\/\/ceptimus.co.uk\/meissnerTetrahedronTriangle.scad\" target=\"_blank\" rel=\"noopener\">https:\/\/ceptimus.co.uk\/meissnerTetrahedronTriangle.scad<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lots of people know about curves of constant width &#8211; for example the UK 50p and 20p coins: despite their apparent non-roundness they have constant width when measured by parallel jawed calipers or the mechanisms inside vending machines.\u00a0 If the shapes of these coins are extruded as prisms they can be used as rollers for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,4],"tags":[],"class_list":["post-345","post","type-post","status-publish","format-standard","hentry","category-3d-printing","category-programming"],"_links":{"self":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=345"}],"version-history":[{"count":0,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/345\/revisions"}],"wp:attachment":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/categories?post=345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/tags?post=345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}