|
![](/i/fill.gif) |
/*
The following scene is a quick-and-dirty brute force approximation
for Minkowski sums. Two arbitrary shapes are minkowski-added by
chosing many random points in the first given object, then adding
them to the second object, i.e. making a translated copy of the
second object. The number of copies should be high (1000 to 10000),
the objects should be simple, esp. the second object. Inner points
of the first object usually don't contribute anything visible to
the sum because they translate the second object to a place where
it will be surrounded by copies belonging to points in the vicinity
of this inner point. So it's a good idea to remove inner points of
the first object; this will increase parse time (because it's
difficult to find points of a thin object), but will greatly
increase the quality of the surface of the minkowski sum (because
no copies are wasted). Modify the #switch value to see the
examples.
Sputnik
*/
// Minkowski sum
// +SP8 +EP8 +D -F +W320 +H240
#macro Minkowski_sum (Copies, O1, O2)
// preparations for sampling the bounding box of O1
#local Min = min_extent (O1);
#local Size = max_extent (O1)-Min;
#local Rand = seed(123);
union {
#local I = 0; // counts inside-points
#local N = 0; // counts tested points
#while (I<Copies)
// get a random point in the bounding box of O1
#local Point = Min+Size*<rand(Rand),rand(Rand),rand(Rand)>;
#local N = N+1;
// if this point is inside O1 then ...
#if (inside(O1, Point))
// ... minkowski-add it to O2 and count it
object { O2 translate Point }
#local I = I+1;
#end//if
#end//while I
// no "}" for union to allow application of a texture
#debug concat ( str(I*100/N,10,2), "% successful inside tests\n" )
#end//macro Minkowski_sum
#switch (2) // <-- choose an example here (1 .. 3)
#case (1) // rounded box
Minkowski_sum ( 10000,
box { -4, 4 }
sphere { 0, 1 }
)
texture { pigment { color rgb 1 } }
}//the missing "}" for the union
#break//1
#case (2) // rounded box, improved
Minkowski_sum ( 2000,
difference { box { -4, 4 } box { -3.9, 3.9 } }
sphere { 0, 1 }
)
texture { pigment { color rgb 1 } }
}
#break//2
#case (3) // "coned" torus
Minkowski_sum ( 1000,
difference {
torus { 5, 1 }
torus { 5, 0.9 }
}
cone { 0, 2, 3*y, 0.5 }
)
texture { pigment { color rgb 1 } }
}
#break//3
#case (4) // "torused" cone = 1.0*cone + 1.0*torus
Minkowski_sum ( 1000,
difference {
cone { 0 *y, 2 , 3 *y, 0.5 }
cone { 0.1*y, 1.9, 2.9*y, 0.4 }
}
torus { 5, 1 }
)
texture { pigment { color rgb 1 } }
}
#break//4
#case (5) // 1.6*cone + 0.4*torus
Minkowski_sum ( 1000,
difference {
cone { 0 *y, 2 , 3 *y, 0.5 }
cone { 0.1*y, 1.9, 2.9*y, 0.4 }
scale 1.6
}
torus { 5, 1 scale 0.4 }
)
texture { pigment { color rgb 1 } }
}
#break//5
#case (6) // 0.4*cone + 1.6*torus
Minkowski_sum ( 1000,
difference {
cone { 0 *y, 2 , 3 *y, 0.5 }
cone { 0.1*y, 1.9, 2.9*y, 0.4 }
scale 0.4
}
torus { 5, 1 scale 1.6 }
)
texture { pigment { color rgb 1 } }
}
#break//6
#end//switch
light_source { <-100, 150, -50>, rgb 1 }
camera { location <-5, 10, -15> look_at -1.5*y }
Post a reply to this message
|
![](/i/fill.gif) |