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:
18
examples/differential_line_growth.scad
Normal file
18
examples/differential_line_growth.scad
Normal 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));
|
109
src/experimental/_impl/_differential_line_growth.scad
Normal file
109
src/experimental/_impl/_differential_line_growth.scad
Normal 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);
|
||||||
|
|
19
src/experimental/differential_line_growth.scad
Normal file
19
src/experimental/differential_line_growth.scad
Normal 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)];
|
||||||
|
|
Reference in New Issue
Block a user