From 3112240dd9b8b7c922fdeabb0473bb09c5d33204 Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 21 Feb 2020 13:13:44 +0000 Subject: reworked to be more reliable more elaborate shapes should now be possible --- ambiguous-cylinders.scad | 111 +++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 53 deletions(-) (limited to 'ambiguous-cylinders.scad') diff --git a/ambiguous-cylinders.scad b/ambiguous-cylinders.scad index c65352c..21ec446 100644 --- a/ambiguous-cylinders.scad +++ b/ambiguous-cylinders.scad @@ -34,65 +34,66 @@ module view_cylinder(shift=100/3,height=200,thin=0.1) { } /* - given two objects: + given a 2D object: - * build they view cylinders + * build the view cylinder at an angle - * rotate them so the two "observers" are opposite each other on the - Y axis, lookin toward the origin with a downward `angle` + * this means rotating the object, extruding, then rotating the + result the other way: - * 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 + * cut away half the cylinder - (`size` should be higher than the diameter of the largest child, - otherwise the shapes may get cut) + * because otherwise, in intersect_view_cylinders, we would get 4 + arcs (two close to the XZ plane, two close to the XY plane), but + we only want 2 (the XY ones) */ -module intersect_view_cylinders(angle=45,size=100,thin=0.1) { +module clipped_angled_view_cylinder(angle=60,side=1,size=100,thin=0.1) { shift=size/3; height=size*2; intersection() { - rotate([0,angle,0]) view_cylinder(shift,height,thin) children(0); - rotate([0,-angle,0]) view_cylinder(shift,height,thin) children(1); + rotate([angle,0,0]) + view_cylinder(shift,height,thin) + rotate([-angle,0,0]) children(0); + rotate([angle,0,0]) + translate([0,-side*size/2,0]) + cube([size,size,size],center=true); } -}; +} /* - `intersect_view_cylinders` produces a slightly ugly shape, with two - half-curves for each half-object; to see the problem, render this: + given two objects: -intersect_view_cylinders() { - circle(d=14); - rotate([0,0,45]) square(size=10,center=true); -} + * build their view cylinders, rotated so the two "observers" are + opposite each other on the Y axis, lookin toward the origin with a + downward `angle` - 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 -*/ + * intersect half of them at a time (see above, and Sugihara's paper, + for the reason) + 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 -module clip_intersect_view(angle=45,size=100,thin=0.1) { - bound=size*2; - skip=0; + (`size` should be higher than the diameter of the largest child, + otherwise the shapes may get cut) +*/ - intersection() { - intersect_view_cylinders(angle,size,thin) { - children(0); - children(1); - } - translate([0,-size/2,0]) rotate([0,-90-angle,0]) cube([size,size,size]); - } - intersection() { - intersect_view_cylinders(angle,size,thin) { - children(0); - children(1); +module intersect_view_cylinders(angle=60,size=100,thin=0.1) { + union() { + intersection() { + clipped_angled_view_cylinder(angle,1,size,thin) children(0); + clipped_angled_view_cylinder(-angle,1,size,thin) children(1); + } + intersection() { + clipped_angled_view_cylinder(angle,-1,size,thin) children(0); + clipped_angled_view_cylinder(-angle,-1,size,thin) children(1); } - translate([0,-size/2,0]) rotate([0,90-angle,0]) cube([size,size,size]); } }; @@ -104,9 +105,9 @@ module clip_intersect_view(angle=45,size=100,thin=0.1) { (`thick` determines the thickness of the wall, `height` its height) */ -module ambiguous_cylinder(angle=45,size=100,thin=0.1,thick=1,height=10) { +module ambiguous_cylinder(angle=60,size=100,thin=0.1,thick=1,height=10) { minkowski() { - clip_intersect_view(angle,size,thin) { + intersect_view_cylinders(angle,size,thin) { children(0); children(1); } @@ -118,9 +119,6 @@ module ambiguous_cylinder(angle=45,size=100,thin=0.1,thick=1,height=10) { Some examples: */ -/* - Arrow that always points right - */ module arrow(length=10) { scale([length/10,length/10,length/10]) polygon([ [-5, 0], [-4.5, 1], [ 2, 1], [ 2.5, 3], [ 5, 0], @@ -133,16 +131,23 @@ module fat_arrow(length=10) { [ 0.5,-4], [-1,-1.5], [-4,-1.5] ]); } -ambiguous_cylinder() { - rotate([0,0,90]) arrow(30); - rotate([0,0,-90]) arrow(30); +module arrow_always_right() { + ambiguous_cylinder() { + arrow(30); + rotate([0,0,180]) arrow(30); + } } -/* - circle / diamond - */ +module fat_arrow_always_right() { + ambiguous_cylinder() { + fat_arrow(30); + rotate([0,0,180]) fat_arrow(30); + } +} -translate([0,50,0]) ambiguous_cylinder() { - circle(d=14); - rotate([0,0,45]) square(size=10,center=true); +module circle_diamond() { + ambiguous_cylinder() { + circle(d=14); + rotate([0,0,45]) square(size=10,center=true); + } } -- cgit v1.2.3