summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ambiguous-cylinders.scad111
1 files changed, 58 insertions, 53 deletions
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);
+ }
}