jsketcher/web/app/utils/genSerpinski.js
Val Erastov (xibyte) f24a3f45a5 imports grooming
2020-07-19 23:09:46 -07:00

57 lines
1.4 KiB
JavaScript

import Vector from 'math/vector';
export default function genSerpinski(viewer, depthLimit = 7) {
let [line] = viewer.selected;
genSerpinskiImpl(viewer, line.a, line.b, depthLimit);
viewer.remove(line);
viewer.refresh();
}
export function genSerpinskiImpl(viewer, aInit, bInit, depthLimit) {
function serpinskiStep(a, b) {
a = new Vector().setV(a);
b = new Vector().setV(b);
let ab = b.minus(a);
let S = ab.length() * 0.5;
let v = ab.normalize();
let SH = S * 0.5;
let dp = v.multiply(SH);
let p = a.plus(dp);
let D = new Vector(-v.y, v.x, 0);
let DL = Math.sqrt(S * S - SH * SH);
let A = p.plus(D.multiply(DL));
let B = A.plus(v.multiply(S));
return [
[A, a],
[A, B],
[b, B],
]
}
function addLineOnScene(line) {
let [a, b] = line;
viewer.addSegment(a.x, a.y, b.x, b.y, viewer.activeLayer)
}
function generate(a, b, depth) {
let lines = serpinskiStep(a, b);
if (depth === depthLimit) {
return lines;
}
let subLines = [];
let [l1, l2, l3] = lines;
generate(l1[0], l1[1], depth + 1).forEach(sl => subLines.push(sl));
generate(l2[0], l2[1], depth + 1).forEach(sl => subLines.push(sl));
generate(l3[0], l3[1], depth + 1).forEach(sl => subLines.push(sl));
return subLines;
}
let lines = generate(aInit, bInit, 1);
lines.forEach(l => addLineOnScene(l));
}