1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-28 17:00:00 +02:00

add differential_line_growth

This commit is contained in:
Justin Lin
2022-05-26 18:19:56 +08:00
parent 27536f28f6
commit bce7487a96
3 changed files with 146 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
use <shape_circle.scad>;
use <experimental/differential_line_growth.scad>;
$fn = 24;
r = 20;
times = 50;
thickness = 2;
node_option = [
0.5, // maxForce
0.7, // maxSpeed
12, // separationDistance
1.5, // separationCohesionRatio
10 // maxEdgeLength
];
init_shape = shape_circle(r);
linear_extrude(thickness)
polygon(differential_line_growth(init_shape, node_option, times));

View File

@@ -0,0 +1,109 @@
use <../../util/unit_vector.scad>;
use <../../util/sum.scad>;
ZERO_VT = [0, 0];
function limit(vt, magnitude) =
let(m = norm(vt))
m > magnitude ? vt / m * magnitude : vt;
function setMagnitude(vt, magnitude) = vt == ZERO_VT ? vt : unit_vector(vt) * magnitude;
// node
function node(position, option) = [
position, // position
rands(0, 1, 2), // velocity
option // option
];
function position_of(node) = node[0];
function velocity_of(node) = node[1];
function option_of(node) = node[2];
function maxForce_of(node) = node[2][0];
function maxSpeed_of(node) = node[2][1];
function separationDistance_of(node) = node[2][2];
function separationCohesionRatio_of(node) = node[2][3];
function maxEdgeLength_of(node) = node[2][4];
function cohesionWith(node, other) =
limit(
setMagnitude(other - position_of(node), maxSpeed_of(node)) - velocity_of(node),
maxForce_of(node)
);
function seperationFrom(node, other) =
let(
v = position_of(node) - position_of(other),
dist = norm(v)
)
dist < separationDistance_of(node) ? v / dist : ZERO_VT;
function applyForceTo(node, seperation, cohesion) =
let(
acceleration = limit(seperation, maxForce_of(node)) * separationCohesionRatio_of(node) + cohesion,
velocity = limit(velocity_of(node) + acceleration,
maxSpeed_of(node))
)
[
position_of(node) + velocity,
velocity,
option_of(node)
];
function suitableForGrowth(node, nxNode) =
norm(position_of(node) - position_of(nxNode)) > maxEdgeLength_of(node);
function growNode(node, nxNode) =
node((position_of(node) + position_of(nxNode)) / 2, option_of(node));
// nodes
function cohesion(nodes, leng, i) =
let(
node = nodes[i],
middlePt = (position_of(nodes[(leng + i - 1) % leng]) + position_of(nodes[(i + 1) % leng])) / 2
)
cohesionWith(node, middlePt);
function grow(nodes, leng) =
[
for(i = 0, j = 1; i < leng; i = i + 1, j = j + 1)
let(
node = nodes[i],
nxNode = nodes[j % leng]
)
each [node, if(suitableForGrowth(node, nxNode)) growNode(node, nxNode)]
];
function allSeperationFrom(nodes, leng, node, n) = [
for(j = n; j < leng; j = j + 1)
seperationFrom(node, nodes[j])
];
function updateAllSeperation(allSeperation, allSeperationFrom_i_1, leng, n) = [
for(i = 0; i < leng; i = i + 1)
if(i < n) allSeperation[i]
else allSeperation[i] - allSeperationFrom_i_1[i - n]
];
function differentiate(nodes, leng) =
[
for(i = 0,
allSep = [for(i = [0:leng - 1]) ZERO_VT],
allSeperationFrom_i_1 = allSeperationFrom(nodes, leng, nodes[i], i + 1);
i < leng;
allSep = updateAllSeperation(allSep, allSeperationFrom_i_1, leng, i + 1),
i = i + 1,
allSeperationFrom_i_1 = i < leng ? allSeperationFrom(nodes, leng, nodes[i], i + 1) : undef
)
let(
seperation_i = sum([allSep[i], each allSeperationFrom_i_1]),
cohesion_i = cohesion(nodes, leng, i)
)
applyForceTo(nodes[i], seperation_i, cohesion_i)
];
function _differential_line_growth(nodes) =
let(leng = len(nodes))
grow(differentiate(nodes, leng), leng);

View File

@@ -0,0 +1,19 @@
use <_impl/_differential_line_growth.scad>;
function differential_line_growth(init_shape, option, times) =
let(
init_nodes = [
for(p = init_shape)
node(p, option)
],
nodes_lt = [
for(i = 0, line = _differential_line_growth(init_nodes);
i < times;
i = i + 1,
line = _differential_line_growth(line)
)
line
]
)
[for(node = nodes_lt[times - 1]) position_of(node)];