fourdjs/layer600cell.js

82 lines
1.5 KiB
JavaScript
Raw Normal View History

import * as POLYTOPES from './polytopes.js';
// face detection for the 600-cell
export function nodes_links(links, nodeid) {
return links.filter((l) => l.source === nodeid || l.target === nodeid);
}
export function linked(links, n1, n2) {
const ls = nodes_links(nodes_links(links, n1), n2);
if( ls.length ) {
return ls[0]
} else {
return false;
}
}
function fingerprint(ids) {
const sids = [...ids];
sids.sort();
return sids.join(',');
}
export function make_600cell() {
const nodes = POLYTOPES.make_600cell_vertices();
const links = POLYTOPES.auto_detect_edges(nodes, 12);
return {
nodes: nodes,
links: links
}
}
export function link_to_tetras(nodes, links, link) {
const n1 = link.source;
const n2 = link.target;
const nl1 = nodes_links(links, n1).filter((l) => l.id !== link.id);
const nl2 = nodes_links(links, n2).filter((l) => l.id !== link.id);
const p1 = new Set();
const p = new Set();
for( const nl of nl1 ) {
if( nl.source !== n1 ) {
p1.add(nl.source);
}
if( nl.target !== n1 ) {
p1.add(nl.target);
}
}
for( const nl of nl2 ) {
if( nl.source !== n2 && p1.has(nl.source) ) {
p.add(nl.source);
}
if( nl.target !== n2 && p1.has(nl.target) ) {
p.add(nl.target);
}
}
const lp = Array.from(p);
const seen = {};
const tetras = [];
for( const p1 of lp ) {
for( const p2 of lp ) {
if( p1 != p2 ) {
if( linked(links, p1, p2) ) {
const fp = fingerprint([n1, n2, p1, p2]);
if( !seen[fp] ) {
seen[fp] = true;
tetras.push([n1, n2, p1, p2])
}
}
}
}
}
return tetras;
}