276 lines
7.6 KiB
OpenSCAD
276 lines
7.6 KiB
OpenSCAD
PLOT = "ALL"; // [ALL,FLAPS,FLAP_A,FLAP_B,FLAP_C,SPIKES,SPIKE_A,SPIKE_B,SPIKE_C,SPIKE_D,SKULL]
|
|
MODE = "PREVIW"; // [PREVIW,PLOT]
|
|
|
|
// $fs = (MODE == "PLOT") ? 0.01 : 1;
|
|
$fn = (MODE == "PLOT") ? 35 : 10;
|
|
// $fn = 0;
|
|
|
|
SKIRT_D_BIG = 1100;
|
|
SKIRT_FLAP_NUM = 12;
|
|
SKIRT_FLAP_THIKNES = 0.25;
|
|
SKIRT_FLAP_SLANT_NUMBER = 0.0; // 0 is strait; higer is wider below; lower slimmer below
|
|
SKIRT_FLAP_LENTH = 400;
|
|
SKIRT_FLAP_SPIKE_NUM = 4;
|
|
SKIRT_FLAP_SPIKE_BASE_D_UPPER = 20;
|
|
SKIRT_FLAP_SPIKE_BASE_D_LOWER = 30;
|
|
SKIRT_FLAP_SPIKE_LENGTH_UPPER = 25;
|
|
SKIRT_FLAP_SPIKE_LENGTH_LOWER = 37;
|
|
|
|
SKIRT_FLAP_SPIKE_SEPERATION = SKIRT_FLAP_LENTH/(SKIRT_FLAP_SPIKE_NUM+1);
|
|
|
|
SPIKE_STEP_COUNT = (MODE == "PLOT") ? 25 : 5;
|
|
|
|
include <perlin_noise.scad>
|
|
include <heat_set_inserts.scad>
|
|
|
|
// =================================================
|
|
// === flap ========================================
|
|
// =================================================
|
|
|
|
module skirt_flap_part(endpart, count = 1) {
|
|
difference() {
|
|
union() {
|
|
linear_extrude(height = SKIRT_FLAP_THIKNES)
|
|
hull() {
|
|
skirt_base_d = SKIRT_D_BIG/SKIRT_FLAP_NUM;
|
|
circle(d=skirt_base_d+(skirt_base_d*SKIRT_FLAP_SLANT_NUMBER*count));
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0])
|
|
circle(d=skirt_base_d+(skirt_base_d*SKIRT_FLAP_SLANT_NUMBER*(count+1)));
|
|
}
|
|
|
|
cylinder(h = 1, r1 = 15, r2 = 7);
|
|
if (endpart)
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0])
|
|
cylinder(h = 1, r1 = 15, r2 = 7);
|
|
}
|
|
cylinder(h = 100, d = 3.2);
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0])
|
|
cylinder(h = 100, d = 3.2);
|
|
}
|
|
}
|
|
|
|
module flap_a() {
|
|
skirt_flap_part(endpart = false, count = 1);
|
|
}
|
|
|
|
module flap_b() {
|
|
skirt_flap_part(endpart = false, count = 2);
|
|
}
|
|
|
|
module flap_c() {
|
|
skirt_flap_part(endpart = true, count = 3);
|
|
}
|
|
|
|
module flap_full() {
|
|
flap_a();
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0, SKIRT_FLAP_THIKNES+0.1])
|
|
flap_b();
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0, SKIRT_FLAP_THIKNES+0.1]*2)
|
|
flap_c();
|
|
}
|
|
|
|
// =================================================
|
|
// === point =======================================
|
|
// =================================================
|
|
|
|
function point_r_fn(x) = 1-(0.8*x+0.2)^3;
|
|
function point_sheer_x_fn(x) = 0.3-(1.6*x)^3;
|
|
function point_sheer_y_fn(x) = max(0, x-0.3);
|
|
function add(list, c = 0) = c < len(list) - 1 ? list[c] + addl(list, c + 1) : list[c];
|
|
function addl(list, l, c = 0) = c < l ? list[c] + addl(list, l, c + 1) : list[c];
|
|
|
|
module spike(size, f_d, f_sx, f_sy, step)
|
|
{
|
|
union() {
|
|
rotate([0, 0, -90])
|
|
difference() {
|
|
union() {
|
|
scale(size)
|
|
for (pos = [0:step:1.5]) {
|
|
i = round(pos/step);
|
|
move_x = (i == 0) ? 0 : addl(f_sx, i-1) * step;
|
|
move_y = (i == 0) ? 0 : addl(f_sy, i-1) * step;
|
|
if (f_d[i] >= 0)
|
|
translate([move_x, move_y, pos])
|
|
multmatrix(m = [
|
|
[1, 0, f_sx[i], 0],
|
|
[0, 1, f_sy[i], 0],
|
|
[0, 0, 1, 0],
|
|
[0, 0, 0, 1],
|
|
])
|
|
cylinder(h = step, r1 = f_d[i], r2 = f_d[i+1]);
|
|
}
|
|
}
|
|
// screw hole
|
|
translate([0, 0, -0.01]) { // remove z bending
|
|
// heatSetInsert_hole_M3x5_7();
|
|
cylinder(h = 6.7, d = 4.0);
|
|
translate([0, 0, 6.699])
|
|
cylinder(h = 0.8, r1 = 2.0, r2 = 1.6);
|
|
cylinder(h = 13, d = 3.2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
module spike_noisy(size) {
|
|
noise = [
|
|
perlin_noise(no=4, seed=rands(0, 100000, 1)[0]),
|
|
perlin_noise(no=4, seed=rands(0, 100000, 1)[0]),
|
|
perlin_noise(no=4, seed=rands(0, 100000, 1)[0])
|
|
];
|
|
|
|
STEP = 1 / SPIKE_STEP_COUNT;
|
|
rotate([0, 0, -90])
|
|
spike(
|
|
size,
|
|
// [1, 1, 1],
|
|
[ for (i = [0:STEP:1.5]) point_r_fn(i) + noise[0][round(i*STEP)]*0.2 ],
|
|
[ for (i = [0:STEP:1.5]) point_sheer_x_fn(i) + noise[1][round(i*STEP)]*0.2 ],
|
|
[ for (i = [0:STEP:1.5]) point_sheer_y_fn(i) * (noise[2][round(i*STEP)]*4-2) ],
|
|
STEP
|
|
);
|
|
}
|
|
|
|
module spike_a() { spike_noisy([20, 20, 50]); }
|
|
module spike_b() { spike_noisy([17.5, 17.5, 43]); }
|
|
module spike_c() { spike_noisy([16, 16, 38]); }
|
|
module spike_d() { spike_noisy([14, 14, 35]); }
|
|
|
|
module spike_full() {
|
|
spike_a();
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0, SKIRT_FLAP_THIKNES+0.1])
|
|
spike_b();
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0, SKIRT_FLAP_THIKNES+0.1]*2)
|
|
spike_c();
|
|
translate([SKIRT_FLAP_SPIKE_SEPERATION, 0, SKIRT_FLAP_THIKNES+0.1]*3)
|
|
spike_d();
|
|
}
|
|
|
|
|
|
// =================================================
|
|
// === skull =======================================
|
|
// =================================================
|
|
|
|
function cubic_bezier_curve(p, n, z) =
|
|
[ for (t = [0:1/(n-1):1])
|
|
[
|
|
((1-t)^3 * p[0][0]+3*(1-t)^2*t * p[1][0]+3*(1-t)*t^2 * p[2][0]+t^3 * p[3][0]),
|
|
((1-t)^3 * p[0][1]+3*(1-t)^2*t * p[1][1]+3*(1-t)*t^2 * p[2][1]+t^3 * p[3][1]),
|
|
z
|
|
]
|
|
];
|
|
|
|
|
|
module skull(path, curve_points = 10)
|
|
{
|
|
points = [
|
|
[0, 0, 0],
|
|
[0, 0, len(path)-1],
|
|
for (h = [0:len(path)-1])
|
|
each for (p = [0:3:len(path[h])-2])
|
|
cubic_bezier_curve(p = [for (i=[p:p+3]) path[h][i]], n = curve_points, z = h)
|
|
];
|
|
// echo(points);
|
|
ll = round((len(path[0])-1)/3*curve_points);
|
|
faces = [
|
|
for (p = [0:1:ll])
|
|
[0, p, p+1]
|
|
,
|
|
for (h = [0:len(path)-2])
|
|
each for (p = [1:1:ll])
|
|
[ [h*ll+p+1, h*ll+p, (h+1)*ll+p], [(h+1)*ll+p, (h+1)*ll+p+1, h*ll+p+1] ]
|
|
,
|
|
for (p = [0:1:ll])
|
|
[1, (len(path)-1)*ll+p, (len(path)-1)*ll+p+1]
|
|
];
|
|
// echo(faces);
|
|
polyhedron(points = points, faces = faces);
|
|
}
|
|
|
|
function circle_path(r=[[1, 1], [1, 1], [1, 1]], p=90, d=45) =
|
|
[
|
|
[r[0][0], 0],
|
|
for (a = [p:p:360])
|
|
each [
|
|
[r[1][0]*cos(a-p+d), r[1][1]*sin(a-p+d)],
|
|
[r[2][0]*cos(a-d) , r[2][1]*sin(a-d)],
|
|
[r[0][0]*cos(a) , r[0][1]*sin(a)]
|
|
]
|
|
];
|
|
|
|
function skull_rx(h) = cos(asin(h*2-1))/2;
|
|
function skull_ry(h) = cos(asin(h*2-1));
|
|
|
|
module skull_a()
|
|
{
|
|
step = 0.1;
|
|
scale([1, 1, step])
|
|
skull(
|
|
path = [
|
|
for (r = [0:step:1])
|
|
circle_path(
|
|
r=[
|
|
[skull_rx(r), skull_ry(r)],
|
|
[skull_rx(r)*1.14237401488, skull_ry(r)*1.14237401488],
|
|
[skull_rx(r)*1.14237401488, skull_ry(r)*1.14237401488]
|
|
],
|
|
p=90,
|
|
d=28.9111986305
|
|
)
|
|
],
|
|
curve_points = 1/step
|
|
);
|
|
}
|
|
|
|
// =================================================
|
|
// === plot ========================================
|
|
// =================================================
|
|
|
|
if (PLOT == "ALL")
|
|
{
|
|
rotate([180, 0, 0])
|
|
flap_full();
|
|
spike_full();
|
|
}
|
|
else if (PLOT == "FLAPS")
|
|
{
|
|
flap_full();
|
|
}
|
|
else if (PLOT == "FLAP_A")
|
|
{
|
|
flap_a();
|
|
}
|
|
else if (PLOT == "FLAP_B")
|
|
{
|
|
flap_b();
|
|
}
|
|
else if (PLOT == "FLAP_C")
|
|
{
|
|
flap_c();
|
|
}
|
|
else if (PLOT == "SPIKES")
|
|
{
|
|
spike_full();
|
|
}
|
|
else if (PLOT == "SPIKE_A")
|
|
{
|
|
spike_a();
|
|
}
|
|
else if (PLOT == "SPIKE_B")
|
|
{
|
|
spike_b();
|
|
}
|
|
else if (PLOT == "SPIKE_C")
|
|
{
|
|
spike_c();
|
|
}
|
|
else if (PLOT == "SPIKE_D")
|
|
{
|
|
spike_d();
|
|
}
|
|
else if (PLOT == "SKULL")
|
|
{
|
|
skull_a();
|
|
}
|