From a0c56ceb45626371e81f2f717e4e92604a655d7a Mon Sep 17 00:00:00 2001 From: dakkar Date: Sun, 2 Feb 2020 19:25:56 +0000 Subject: comments --- ambiguous-cylinders.scad | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/ambiguous-cylinders.scad b/ambiguous-cylinders.scad index 9a59522..965942d 100644 --- a/ambiguous-cylinders.scad +++ b/ambiguous-cylinders.scad @@ -1,3 +1,25 @@ +/* + Recreating Sugihara's impossible objects + + Original work: http://www.isc.meiji.ac.jp/~kokichis/Welcomee.html + + PDF Paper with the maths: https://www.mdpi.com/2073-8994/8/4/21 + + Based on Sugihara's work, I've approximated his mathematical model + with OpenSCAD. + */ + +/* let's build it in steps: + + given a 2D object, extrude a `thin` "cylinder" with its shape as + section; this approximates the set of points that would appear + indistinguishable from the given shape to an observer infinitely + distant on the Z axis + + (`height` determines how tall the cylinder is, `shift` determines + how low it is on Z axis) +*/ + module view_cylinder(shift=100/3,height=200,thin=0.1) { translate([0,0,-shift]) { difference() { @@ -11,6 +33,24 @@ module view_cylinder(shift=100/3,height=200,thin=0.1) { } } +/* + given two objects: + + * build they view cylinders + + * rotate them so the two "observers" are opposite each other on the + Y axis, lookin toward the origin with a downward `angle` + + * intersect them + + the result approximates the set of points that would look like the + first object to the first observers, and like the second object to + the second observer + + (`size` should be higher than the diameter of the largest child, + otherwise the shapes may get cut) +*/ + module intersect_view_cylinders(angle=45,size=100,thin=0.1) { shift=size/3; height=size*2; @@ -21,6 +61,21 @@ module intersect_view_cylinders(angle=45,size=100,thin=0.1) { } }; +/* + `intersect_view_cylinders` produces a slightly ugly shape, with two + half-curves for each half-object; to see the problem, render this: + +intersect_view_cylinders() { + circle(d=14); + rotate([0,0,45]) square(size=10,center=true); +} + + therefore, we render it twice, cutting the "wrong half" out each + time. This gives us the curve we want at the top of our ambiguous + cylinder +*/ + + module clip_intersect_view(angle=45,size=100,thin=0.1) { bound=size*2; skip=0; @@ -41,17 +96,30 @@ module clip_intersect_view(angle=45,size=100,thin=0.1) { } }; +/* + finally, we "extrude" the curve; OpenSCAD can't extrude a 3d shape, + but we can "paint" it with a vertical cylinder, and that's close + enough + + (`thick` determines the thickness of the wall, `height` its height) + */ + module ambiguous_cylinder(angle=45,size=100,thin=0.1,thick=1,height=10) { minkowski() { clip_intersect_view(angle,size,thin) { children(0); children(1); } - cylinder(r=thick,h=height*2,center=true); + cylinder(r=thick/2,h=height*2,center=true); } } -/* Arrow that always points right +/* + Some examples: + */ + +/* + Arrow that always points right */ module arrow(length=10) { scale([length/10,length/10,length/10]) @@ -64,7 +132,8 @@ ambiguous_cylinder() { rotate([0,0,-90]) arrow(30); } -/* circle / diamond +/* + circle / diamond */ translate([0,50,0]) ambiguous_cylinder() { -- cgit v1.2.3