/ src / libraries / 3d_surface.scad
3d_surface.scad
 1  // thanks Paul https://github.com/openscad/list-comprehension-demos/
 2  
 3  include <../functions.scad>
 4  
 5  module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
 6    function p(x, y) = [ x, y, max(0,surface_function(x, y)) ];
 7    function p0(x, y) = [ x, y, bottom ];
 8    function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
 9    function face(x, y) = [ p(x, y + step), p(x + step, y + step), p(x + step, y), p(x + step, y), p(x, y), p(x, y + step) ];
10    function fan(a, i) =
11          a == 0 ? [ [ 0, 0, bottom ], [ i, -size, bottom ], [ i + step, -size, bottom ] ]
12        : a == 1 ? [ [ 0, 0, bottom ], [ i + step,  size, bottom ], [ i,  size, bottom ] ]
13        : a == 2 ? [ [ 0, 0, bottom ], [ -size, i + step, bottom ], [ -size, i, bottom ] ]
14        :          [ [ 0, 0, bottom ], [  size, i, bottom ], [  size, i + step, bottom ] ];
15    function sidex(x, y) = [ p0(x, y), p(x, y), p(x + step, y), p0(x + step, y) ];
16    function sidey(x, y) = [ p0(x, y), p(x, y), p(x, y + step), p0(x, y + step) ];
17  
18    points = flatten(concat(
19        // top surface
20        [ for (x = [ -size : step : size - step ], y = [ -size : step : size - step ]) face(x, y) ],
21        // bottom surface as triangle fan
22        [ for (a = [ 0 : 3 ], i = [ -size : step : size - step ]) fan(a, i) ],
23        // sides
24        [ for (x = [ -size : step : size - step ], y = [ -size, size ]) rev(y < 0, sidex(x, y)) ],
25        [ for (y = [ -size : step : size - step ], x = [ -size, size ]) rev(x > 0, sidey(x, y)) ]
26    ));
27  
28    tcount = 2 * pow(2 * size / step, 2) + 8 * size / step;
29    scount = 8 * size / step;
30  
31    tfaces = [ for (a = [ 0 : 3 : 3 * (tcount - 1) ] ) [ a, a + 1, a + 2 ] ];
32    sfaces = [ for (a = [ 3 * tcount : 4 : 3 * tcount + 4 * scount ] ) [ a, a + 1, a + 2, a + 3 ] ];
33    faces = concat(tfaces, sfaces);
34  
35    polyhedron(points, faces, convexity = 8);
36  }
37  
38  module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
39    function to_polar(q, size) = q * (90 / size);
40  
41    function p(x, y) = [
42      surface_distribution_function(to_polar(x, size), size),
43      surface_distribution_function(to_polar(y, size), size),
44      max(0,surface_function(surface_distribution_function(to_polar(x, size), size), surface_distribution_function(to_polar(y, size), size)))
45    ];
46    function p0(x, y) = [ x, y, bottom ];
47    function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
48    function face(x, y) = [ p(x, y + step), p(x + step, y + step), p(x + step, y), p(x + step, y), p(x, y), p(x, y + step) ];
49    function fan(a, i) =
50          a == 0 ? [ [ 0, 0, bottom ], [ i, -size, bottom ], [ i + step, -size, bottom ] ]
51        : a == 1 ? [ [ 0, 0, bottom ], [ i + step,  size, bottom ], [ i,  size, bottom ] ]
52        : a == 2 ? [ [ 0, 0, bottom ], [ -size, i + step, bottom ], [ -size, i, bottom ] ]
53        :          [ [ 0, 0, bottom ], [  size, i, bottom ], [  size, i + step, bottom ] ];
54    function sidex(x, y) = [ p0(x, y), p(x, y), p(x + step, y), p0(x + step, y) ];
55    function sidey(x, y) = [ p0(x, y), p(x, y), p(x, y + step), p0(x, y + step) ];
56  
57    points = flatten(concat(
58        // top surface
59        [ for (x = [ -size : step : size - step ], y = [ -size : step : size - step ]) face(x, y) ],
60        // bottom surface as triangle fan
61        [ for (a = [ 0 : 3 ], i = [ -size : step : size - step ]) fan(a, i) ],
62        // sides
63        [ for (x = [ -size : step : size - step ], y = [ -size, size ]) rev(y < 0, sidex(x, y)) ],
64        [ for (y = [ -size : step : size - step ], x = [ -size, size ]) rev(x > 0, sidey(x, y)) ]
65    ));
66  
67    tcount = 2 * pow(2 * size / step, 2) + 8 * size / step;
68    scount = 8 * size / step;
69  
70    tfaces = [ for (a = [ 0 : 3 : 3 * (tcount - 1) ] ) [ a, a + 1, a + 2 ] ];
71    sfaces = [ for (a = [ 3 * tcount : 4 : 3 * tcount + 4 * scount ] ) [ a, a + 1, a + 2, a + 3 ] ];
72    faces = concat(tfaces, sfaces);
73  
74    polyhedron(points, faces, convexity = 8);
75  }
76  
77  // defaults, overridden in functions.scad
78  function surface_distribution_function(dim, size) = sin(dim) * size;
79  function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));