hilbert_dragon.scad
1 use <along_with.scad> 2 use <bezier_smooth.scad> 3 use <util/reverse.scad> 4 use <util/dedup.scad> 5 use <turtle/lsystem3.scad> 6 use <curve.scad> 7 use <dragon_head.scad> 8 use <dragon_scales.scad> 9 use <path_extrude.scad> 10 use <bezier_curve.scad> 11 12 hilbert_dragon(); 13 14 module hilbert_dragon() { 15 module one_segment(body_r, body_fn, one_scale_data) { 16 rotate([-90, 0, 0]) 17 dragon_body_scales(body_r, body_fn, one_scale_data); 18 19 points = [[0, 0, 0], [0, .1, 1], [0, 1, 1.5]] * 4.5; 20 path = bezier_curve(0.1, points); 21 22 // dorsal fin 23 translate([0, 3.2, -3]) 24 rotate([-65, 0, 0]) 25 path_extrude([[0, -.25], [0.5, 0], [0, .75], [-0.5, 0]] * 4.5, path, scale = .05); 26 27 translate([0, -2.5, 1]) 28 rotate([-10, 0, 0]) 29 scale([1.1, 0.8, 1.25]) 30 sphere(body_r * 1.075, $fn = 8); 31 } 32 33 body_r = 5; 34 body_fn = 12; 35 scale_fn = 5; 36 scale_tilt_a = -3; 37 38 lines = hilbert_curve(); 39 hilbert_path = dedup([each [for(line = lines) line[0]], lines[len(lines) - 1][1]]); 40 smoothed_hilbert_path = bezier_smooth(hilbert_path, 0.45, t_step = 0.15); 41 42 dragon_body_path = reverse([for(i = [1:len(smoothed_hilbert_path) - 2]) smoothed_hilbert_path[i]]); 43 44 one_body_scale_data = one_body_scale(body_r, body_fn, scale_fn, scale_tilt_a); 45 46 along_with(dragon_body_path, scale = [0.425, 0.6, 0.425]) 47 scale(0.035) 48 one_segment(body_r, body_fn, one_body_scale_data); 49 50 // tail 51 translate([0, -.012, -.54]) 52 scale([0.017, 0.017, 0.025]) 53 rotate([0, 0, -12]) 54 mirror([0, 0, .2]) 55 tail(); 56 57 translate([.06, 0, -2.4]) 58 scale(0.033) 59 rotate([0, -15, 0]) 60 dragon_head(); 61 } 62 63 module tail() { 64 $fn = 4; 65 tail_scales(75, 2.5, 4.25, -4, 1.25); 66 tail_scales(100, 1.25, 4.5, -7, 1); 67 tail_scales(110, 1.25, 3, -9, 1); 68 tail_scales(120, 2.5, 2, -9, 1); 69 70 translate([0, 0, -1.6]) 71 rotate([0, -25, 0]) 72 scale([1.3, 1.2, .9]) 73 hair(); 74 75 module hair() { 76 tail_hair = [ 77 [3, -1], 78 [5, -1.5], 79 [8, -1], 80 [9.5, 0], 81 [8, -0.4], 82 [6.5, -0.3], 83 [8, 0], 84 [12, 1.5], 85 [15, 4], 86 [17, 10], 87 [14, 8], 88 [12, 7], 89 [9, 6], 90 [11.5, 10], 91 [13, 12], 92 [16, 14], 93 [12, 13], 94 [8, 11], 95 [9, 13], 96 [4, 9], 97 [2, 8], 98 [-1, 3] 99 ]; 100 101 rotate([-2.5, 0, 0]) 102 translate([-1, 1, 5.5]) 103 scale([.8, 1, 1.3]) { 104 translate([2, 0, -3]) 105 scale([2, 1, .8]) 106 rotate([-90, 70, 15]) 107 linear_extrude(.75, center = true) 108 polygon(tail_hair); 109 110 scale([.85, .9, .6]) 111 translate([2, 0, -5]) 112 scale([1.75, 1, .8]) 113 rotate([-90, 70, 15]) { 114 linear_extrude(1.5, scale = 0.5) 115 polygon(tail_hair); 116 mirror([0, 0, 1]) 117 linear_extrude(1.5, scale = 0.5) 118 polygon(tail_hair); 119 } 120 121 scale([.6, .7, .9]) 122 translate([2, 0, -4]) 123 scale([2, 1, .85]) 124 rotate([-90, 65, 15]) { 125 linear_extrude(3.5, scale = 0.5) 126 polygon(tail_hair); 127 mirror([0, 0, 1]) 128 linear_extrude(3.5, scale = 0.5) 129 polygon(tail_hair); 130 } 131 } 132 } 133 } 134 135 function hilbert_curve() = 136 let( 137 axiom = "A", 138 rules = [ 139 ["A", "B-F+CFC+F-D&F^D-F+&&CFC+F+B//"], 140 ["B", "A&F^CFB^F^D^^-F-D^|F^B|FC^F^A//"], 141 ["C", "|D^|F^B-F+C^F^A&&FA&F^C+F+B^F^D//"], 142 ["D", "|CFB-F+B|FA&F^A&&FB-F+B|FC//"] 143 ] 144 ) 145 lsystem3(axiom, rules, 2, 90, 1, 0, [0, 0, 0]);