/ examples / dragon / mountain_dragon.scad
mountain_dragon.scad
  1  use <helix.scad>
  2  use <along_with.scad>
  3  use <curve.scad>
  4  use <sweep.scad>
  5  use <shape_circle.scad>
  6  use <bezier_curve.scad>
  7  use <path_scaling_sections.scad>
  8  use <experimental/worley_sphere.scad>
  9  use <dragon_head.scad>
 10  use <dragon_scales.scad>
 11  use <dragon_foot.scad>
 12  use <path_extrude.scad>
 13  use <bezier_curve.scad>
 14  
 15  r1 = 25;
 16  r2 = 15;
 17  levels = 3;
 18  level_dist = 20;
 19  
 20  module one_segment(body_r, body_fn, one_scale_data) {
 21      // scales
 22      rotate([-90, 0, 0])
 23          dragon_body_scales(body_r, body_fn, one_scale_data);
 24  
 25      points = [[0, 0, 0], [0, .1, 1], [0, 1, 1.5]] * 4;
 26      path = bezier_curve(0.1, points);
 27  
 28      // dorsal fin
 29      translate([0, 3, -3]) 
 30      rotate([-82.5, 5, 30]) 
 31      path_extrude([[0, -.25], [0.5, 0], [0, .75], [-0.5, 0]] * 4, path, scale = .05);            
 32              
 33      // belly    
 34      translate([0, -2.5, .8]) 
 35      rotate([-5, 0, 0]) 
 36      scale([1, 1, 1.4])  
 37          sphere(body_r * 0.966, $fn = 8); 
 38      
 39  }
 40  
 41  module tail() {
 42      $fn = 4;
 43      tail_scales(75, 2.5, 4.25, -4, 1.25);
 44      tail_scales(100, 1.25, 4.5, -7, 1);
 45      tail_scales(110, 1.25, 3, -9, 1);
 46      tail_scales(120, 2.5, 2, -9, 1);   
 47  
 48      translate([0, -.5, -5])
 49      rotate([-5, -5, 5])
 50      scale([.9, 1, .55])
 51          hair();
 52  
 53      module hair() {
 54          tail_hair = [
 55              [3, -1],
 56              [5, -1.5],
 57              [8, -1],
 58              [9.5, 0],
 59              [8, -0.4],
 60              [6.5, -0.3],
 61              [8, 0],
 62              [10, 1],
 63              [14, 5],
 64              [17, 10],
 65              [14, 8],
 66              [12, 7],
 67              [9, 6],
 68              [11.5, 10],
 69              [13, 12],
 70              [16, 14],
 71              [12, 13],
 72              [8, 11],
 73              [10, 14],
 74              [5, 11],
 75              [3, 8.5],
 76              [-1, 3]
 77          ];
 78  
 79          rotate([-2.5, 0, 0])
 80          translate([-1, .5, 5.5])
 81          scale([1.1, 1, 1.3]) {
 82              translate([2, 0, -3])
 83              scale([2, 1, .8])
 84              rotate([-90, 70, 15])
 85              linear_extrude(.75, center = true)
 86                  polygon(tail_hair);
 87  
 88              scale([.8, .9, .6])
 89              translate([2, 0, -5])
 90              scale([1.75, 1, .8])
 91              rotate([-90, 70, 15]) {
 92                  linear_extrude(1.5, scale = 0.5)
 93                      polygon(tail_hair);
 94                  mirror([0, 0, 1])
 95                  linear_extrude(1.5, scale = 0.5)
 96                      polygon(tail_hair);
 97              }
 98  
 99              scale([.6, .7, .9])
100              translate([2, 0, -4])
101              scale([2, 1, .85])
102              rotate([-90, 70, 15]) {
103                  linear_extrude(3.5, scale = 0.5)
104                      polygon(tail_hair);
105                  mirror([0, 0, 1])
106                  linear_extrude(3.5, scale = 0.5)
107                      polygon(tail_hair);
108              }
109          }    
110      }
111  }
112  
113  module mountain_dragon() {
114      path_pts = helix(
115          radius = [r1, r2], 
116          levels = levels, 
117          level_dist = level_dist, 
118          vt_dir = "SPI_DOWN", 
119          rt_dir = "CLK", 
120          $fn = 32
121      );
122  
123      function __angy_angz(p1, p2) = 
124          let(
125              dx = p2[0] - p1[0],
126              dy = p2[1] - p1[1],
127              dz = p2[2] - p1[2],
128              ya = atan2(dz, sqrt(dx * dx + dy * dy)),
129              za = atan2(dy, dx)
130          ) [ya, za];
131          
132      angy_angz = __angy_angz(path_pts[0], path_pts[1]);
133      
134      body_r = 5.25;
135      body_fn = 12;
136      scale_fn = 4;
137      scale_tilt_a = 6;
138  
139      one_body_scale_data = one_body_scale(body_r, body_fn, scale_fn, scale_tilt_a);
140      scale(1.075) 
141      along_with(path_pts, twist = 45, scale = [0.575, 0.575, 0.85], method = "EULER_ANGLE")    
142          one_segment(body_r, body_fn, one_body_scale_data);
143      
144      translate([27.25, 4, 1])
145      rotate([-78, 0, 0])
146      rotate([0, 0, 125])
147      scale([.5, .725, 1.5])
148          tail();
149  
150      translate([16, 0, 63]) 
151      rotate([95, 5, -5]) 
152      rotate([0, angy_angz[0], angy_angz[1]])
153          dragon_head();
154  
155      rotate([-8, -2, -10])
156      translate([12, 2, 44])
157      rotate([10, -67.5, -200])
158      scale(.7)
159          foot();
160  
161      translate([13, 2.5, 45.5])
162      rotate([-76, -25, -95])
163      rotate([0, -20, 0])
164      mirror([1, 0, 0])
165      scale(.7)
166      translate([2, 0, 1])
167          foot();
168  
169      translate([-13, -13, 13])
170      rotate([54, -72, 30])
171      rotate(-30)
172      scale(.65)
173          foot();
174  
175      translate([-10, -15.5, 12])
176      rotate([-87, -45, 145])
177      mirror([1, 0, 0])
178      scale(.65)
179          foot();
180  }
181  
182  module mountain() {
183      radius = 20;
184      detail = 10;
185      amplitude = .1;
186      dist = "border"; 
187  
188      difference() {
189          union() {
190              translate([0, 0, 12])
191              scale([.925, .85, 2.4])	
192                  worley_sphere(radius, detail, amplitude, dist, seed = 14);
193  
194              translate([4, -4, -15])
195              scale([1.04, 1.04, 1])
196              rotate(10)
197                  worley_sphere(radius * 1.2, detail, amplitude, dist, seed = 1);
198          }
199  
200          translate([0, 0, -102])
201          linear_extrude(100)
202              square(100, center = true);
203      }
204  }
205  
206  rotate(180) {
207      translate([0, 0, 7]) 
208          mountain_dragon($fn = 12);
209      translate([-1, -1, 0])
210      rotate(67.5)
211          mountain();
212  }