|
|
|
|
|
|
|
function braid_get_rnd_params() {
|
|
|
|
return {
|
|
|
|
num_points: 10,
|
|
|
|
point_noise: 0.6,
|
|
|
|
num_connections: 12,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function braid(params) {
|
|
|
|
if(typeof params == 'undefined') {
|
|
|
|
var params = braid_get_rnd_params();
|
|
|
|
}
|
|
|
|
|
|
|
|
let points = [];
|
|
|
|
for(let i=0; i<params.num_points; i++) {
|
|
|
|
//const angle = i/params.num_points * 2 * Math.PI + Math.random() * params.point_noise;
|
|
|
|
const angle = i/params.num_points * 2 * Math.PI + Math.random() * params.point_noise;
|
|
|
|
const p1 = new Point(Math.sin(angle) + (Math.random() - 0.5) * params.point_noise, Math.cos(angle) + (Math.random() - 0.5) * params.point_noise);
|
|
|
|
const p2 = new Point(Math.sin(angle) + (Math.random() - 0.5) * params.point_noise, Math.cos(angle) + (Math.random() - 0.5) * params.point_noise);
|
|
|
|
points.push([p1, p2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
var lines = [];
|
|
|
|
for(let i=0; i<params.num_points; i++) {
|
|
|
|
var l = new Path.Line(points[i][0], points[i][1]);
|
|
|
|
l.strokeColor = 'red';
|
|
|
|
l.strokeWidth = 5;
|
|
|
|
lines.push(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
var connections = [];
|
|
|
|
for(let i=0; i<params.num_points; i++) {
|
|
|
|
var l1 = lines[i];
|
|
|
|
var l2 = lines[(i+1) % params.num_points];
|
|
|
|
var conngrp = new paper.Group();
|
|
|
|
const n = params.num_connections; // + Math.floor(Math.random() * 4);
|
|
|
|
for(let j=0; j<n; j++) {
|
|
|
|
const o = j / (n - 1);
|
|
|
|
const p1 = l1.getPointAt(o * l1.length);
|
|
|
|
// offset required for plotting, TODO: generate path instead of single lines
|
|
|
|
const p2 = l2.getPointAt(o * l2.length).add(new Point(0.0001, 0.0001));
|
|
|
|
var cl = new Path.Line(p1, p2);
|
|
|
|
cl.strokeColor = 'black';
|
|
|
|
conngrp.addChild(cl);
|
|
|
|
}
|
|
|
|
connections.push(conngrp);
|
|
|
|
}
|
|
|
|
|
|
|
|
var grp = new paper.Group(lines);
|
|
|
|
grp.addChildren(connections);
|
|
|
|
return grp;
|
|
|
|
}
|
|
|
|
|