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));