Astrid/skirt.scad

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();
}