use ; use ; use ; use ; use ; r1 = 25; r2 = 15; levels = 3; level_dist = 20; module scales(ang, leng, radius, height, thickness) { module one_scale() { rotate([0, ang, 0]) shear(sx = [0, -1.5]) linear_extrude(thickness, center = true) scale([leng, 1]) circle(1, $fn = 4); } for(a = [0:30:330]) { hull() { rotate(a) translate([radius, 0, height]) one_scale(); rotate(a + 15) translate([radius, 0, height + 1.75]) one_scale(); } } } module one_segment() { // scales scale([1,0.85,1]) union() { scales(60, 4, 5, 0, 1.5); scales(75, 2.5, 5, -4, 1.25); scales(100, 1.25, 4.5, -7, 1); scales(110, 1.25, 3, -9, 1); scales(120, 2.5, 2, -9, 1); } // dorsal fin translate([0, 3, -3]) rotate([-75, 0, 0]) shear(sy = [0, 3.5]) linear_extrude(2.25, scale = 0.2) square([2, 12], center = true); // belly translate([0, -2.5, 1]) rotate([-10, 0, 0]) scale([1.1, 0.8, 1.25]) sphere(5.8, $fn = 8); translate([0, 0, -1.65]) rotate([-5, 0, 0]) scale([1, 0.8, 1.6]) sphere(5.5, $fn = 8); } module head(angy_angz) { module hair() { for(i = [18:35]) { rotate(i * 10) translate([0, -14, 0]) rotate([9, 0, 0]) linear_extrude(15, scale = 0.05, twist = 30) translate([0, 10, 0]) circle(3, $fn = 4); } for(i = [0:35]) { rotate(i * 10) translate([0, -12, 0]) rotate([5, 0, 0]) linear_extrude(20, scale = 0.05, twist = 30) translate([0, 10, 0]) circle(2, $fn = 4); } for(i = [0:35]) { rotate(i * 10) translate([0, -10, 0]) rotate([2, 0, 0]) linear_extrude(22, scale = 0.05, twist = -30) translate([0, 10, 0]) circle(3, $fn = 4); } } module one_horn() { translate([-10, -4, -1]) rotate([40, -25, 0]) linear_extrude(30, scale = 0.1, twist = -90) translate([7.5, 0, 0]) circle(3, $fn = 4); } module mouth() { translate([0, 0, -2]) rotate([90, 0, -90]) ellipse_extrude(8, slices = 2) polygon( shape_trapezium([4, 15], h = 22, corner_r = 0) ); translate([0, 0, -3]) rotate([90, 0, -90]) ellipse_extrude(6, slices = 4) polygon( shape_trapezium([6, 20], h = 20, corner_r = 0) ); mirror([1, 0, 0]) translate([0, 0, -3]) rotate([85, 0, -90]) ellipse_extrude(4, slices = 2) polygon( shape_trapezium([6, 19], h = 20, corner_r = 0) ); } module one_eye() { translate([-5, 3, -2]) rotate([-15, 0, 75]) scale([1, 1, 1.5]) sphere(1.5, $fn = 5); translate([-5.5, 3.5, -2.5]) rotate([-15, 0, 75]) sphere(0.5, $fn = 8); } module one_beard() { translate([-11, -12, -11]) rotate(180) linear_extrude(8, scale = 0.2, twist = 90) translate([-10, -10, 0]) circle(1.25, $fn = 6); } rotate([0, angy_angz[0] + 15, angy_angz[1]]) translate([0, 0, -25 / 2]) scale(1.15) { scale([0.8, 0.9, 1]) hair(); translate([0, 0, 2]) { rotate(-90) { one_horn(); mirror([-1, 0, 0]) one_horn(); } mouth(); one_eye(); mirror([0, 1, 0]) one_eye(); one_beard(); mirror([0, 1, 0]) one_beard(); } } } module dragon() { path_pts = helix( radius = [r1, r2], levels = levels, level_dist = level_dist, vt_dir = "SPI_DOWN", rt_dir = "CLK", $fn = 36 ); function __angy_angz(p1, p2) = let( dx = p2[0] - p1[0], dy = p2[1] - p1[1], dz = p2[2] - p1[2], ya = atan2(dz, sqrt(dx * dx + dy * dy)), za = atan2(dy, dx) ) [ya, za]; angy_angz = __angy_angz(path_pts[0], path_pts[1]); scale(1.1) along_with(path_pts, scale = 0.85, method = "EULER_ANGLE") one_segment(); translate([19, 0, 65]) rotate([95, 0, 0]) head(angy_angz); } translate([0, 0, 7]) dragon($fn = 12); linear_extrude(65, scale = 0.4) circle(30); translate([0, 0, 65]) linear_extrude(15, scale = 0.01) circle(30 * 0.4);