/ examples / dragon / hilbert_dragon.scad
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]);