Added indexing for tesseract
parent
c3766b749b
commit
971a791339
|
@ -3,7 +3,7 @@ import ColorScheme from 'color-scheme';
|
||||||
export const get_colours = (basis) => {
|
export const get_colours = (basis) => {
|
||||||
const scheme = new ColorScheme;
|
const scheme = new ColorScheme;
|
||||||
const hexbasis = basis.toString(16).padStart(6, "0");
|
const hexbasis = basis.toString(16).padStart(6, "0");
|
||||||
scheme.from_hex(hexbasis).scheme("analogic").variation("hard").distance(0.5);
|
scheme.from_hex(hexbasis).scheme("tetrade").variation("hard").distance(0.5);
|
||||||
return scheme.colors().map((cs) => parseInt('0x' + cs));
|
return scheme.colors().map((cs) => parseInt('0x' + cs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
main.js
2
main.js
|
@ -33,6 +33,8 @@ scene.background = new THREE.Color(0x808080);
|
||||||
const material = new THREE.MeshStandardMaterial({ color: 0x3293a9 });
|
const material = new THREE.MeshStandardMaterial({ color: 0x3293a9 });
|
||||||
const node_colours = get_colours(0x3293a9);
|
const node_colours = get_colours(0x3293a9);
|
||||||
|
|
||||||
|
material.transparent = true;
|
||||||
|
material.opacity = 0.5;
|
||||||
|
|
||||||
const node_ms = node_colours.map((c) => new THREE.MeshStandardMaterial({color: c}));
|
const node_ms = node_colours.map((c) => new THREE.MeshStandardMaterial({color: c}));
|
||||||
|
|
||||||
|
|
|
@ -505,38 +505,42 @@ function make_120_partition(nodes, n) {
|
||||||
const pairs60 = neighbour_angles(chord3, n, "60.000");
|
const pairs60 = neighbour_angles(chord3, n, "60.000");
|
||||||
const icosas = partition_nodes(pairs60);
|
const icosas = partition_nodes(pairs60);
|
||||||
|
|
||||||
|
n.label = 1;
|
||||||
const angles = icosa_nodes(nodes, icosas[0]);
|
const angles = icosa_nodes(nodes, icosas[0]);
|
||||||
label_120_partition_r(nodes, chord3, 1, n, angles);
|
label_120_partition_r(nodes, chord3, 1, n, angles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursive function to label a single 600-cell vertex partition of the
|
// recursive function to label a single 600-cell vertex partition of the
|
||||||
// 120-cell by following icosahedral nets
|
// 120-cell by following icosahedral nets
|
||||||
|
// this doesn't work! completely - labels only 108-112
|
||||||
|
|
||||||
function label_120_partition_r(nodes, chords, label, origin, neighbours) {
|
function label_120_partition_r(nodes, chords, label, origin, neighbours) {
|
||||||
console.log(`label_120_partition_r`);
|
console.log(`label_120_partition_r ${origin.id}`);
|
||||||
console.log(origin);
|
console.log(neighbours.map((n) => n.id).join(', '));
|
||||||
console.log(neighbours.map((n) => n.id));
|
|
||||||
|
// first try to label everything
|
||||||
|
const unlabelled = [];
|
||||||
for( const n of neighbours ) {
|
for( const n of neighbours ) {
|
||||||
|
|
||||||
if( n.label === 0 ) {
|
if( n.label === 0 ) {
|
||||||
|
console.log(`Labelled ${n.id} ${label}`);
|
||||||
n.label = label;
|
n.label = label;
|
||||||
console.log(`Added ${n.id} to group ${label}`);
|
unlabelled.push(n);
|
||||||
|
} else if( n.label !== label ) {
|
||||||
// the angles represent two icosahedral pyramids - partition them and
|
console.log(`node ${n.id} is already in group ${n.label}`);
|
||||||
// pick the one which is at 60 to the edge we arrived on
|
//return false;
|
||||||
console.log(`looking for more neighbors for ${n}`);
|
|
||||||
const pairs60 = neighbour_angles(chords, n, "60.000");
|
|
||||||
const icosas = partition_nodes(pairs60);
|
|
||||||
const icosa = choose_icosa(nodes, origin, n, icosas);
|
|
||||||
const icosa_n = icosa_nodes(nodes, icosa);
|
|
||||||
return label_120_partition_r(nodes, chords, label, n, icosa_n);
|
|
||||||
} else {
|
|
||||||
if( n.label !== label ) {
|
|
||||||
console.log(`node ${n.id} is already in group ${n.label}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for( const n of unlabelled ) {
|
||||||
|
// the angles represent two icosahedral pyramids - partition them and
|
||||||
|
// pick the one which is at 60 to the edge we arrived on
|
||||||
|
//console.log(`looking for more neighbors for ${n}`);
|
||||||
|
const pairs60 = neighbour_angles(chords, n, "60.000");
|
||||||
|
const icosas = partition_nodes(pairs60);
|
||||||
|
const icosa = choose_icosa(nodes, origin, n, icosas);
|
||||||
|
const icosa_n = icosa_nodes(nodes, icosa);
|
||||||
|
console.log(`recursing to ${nice_icosa(nodes,icosa)}`);
|
||||||
|
return label_120_partition_r(nodes, chords, label, n, icosa_n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a pair of icosa-sets, pick the one which is at the right angle to
|
// given a pair of icosa-sets, pick the one which is at the right angle to
|
||||||
|
@ -558,7 +562,7 @@ function choose_icosa(nodes, origin, n1, icosas) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function icosa_nodes(nodes, icosa) {
|
function icosa_nodes(nodes, icosa) {
|
||||||
return Array.from(icosa).map((nid) => node_by_id(nodes, nid));
|
return Array.from(icosa).map((nid) => node_by_id(nodes, nid)).sort((a, b) => a.id - b.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function node_by_id(nodes, nid) {
|
function node_by_id(nodes, nid) {
|
||||||
|
@ -567,13 +571,64 @@ function node_by_id(nodes, nid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function enumerate_icosas(nodes) {
|
||||||
|
const chords = find_all_chords(nodes);
|
||||||
|
const chord3 = chords["1.74806"]; // these are edges of the 600-cells;
|
||||||
|
|
||||||
|
for( const n of nodes ) {
|
||||||
|
const pairs60 = neighbour_angles(chord3, n, "60.000");
|
||||||
|
const icosas = partition_nodes(pairs60);
|
||||||
|
for( const icosa of icosas ) {
|
||||||
|
const inodes = icosa_nodes(nodes, icosa);
|
||||||
|
console.log(icosa_to_csv(n.id, inodes).join(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function icosa_to_csv(nid, icosa) {
|
||||||
|
const cols = [ nid ];
|
||||||
|
const ia = icosa.map((n) => n.id);
|
||||||
|
for( let i = 1; i < 601; i++ ) {
|
||||||
|
if( ia.includes(i) ) {
|
||||||
|
cols.push(i);
|
||||||
|
} else {
|
||||||
|
cols.push('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function start_icosas(nodes, chords, origin) {
|
||||||
|
const pairs60 = neighbour_angles(chords, origin, "60.000");
|
||||||
|
return partition_nodes(pairs60).map((i) => nice_icosa(nodes, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function next_icosa(nodes, chords, origin, nid) {
|
||||||
|
const n = node_by_id(nodes, nid);
|
||||||
|
const pairs60 = neighbour_angles(chords, n, "60.000");
|
||||||
|
const icosas = partition_nodes(pairs60);
|
||||||
|
const icosa = choose_icosa(nodes, origin, n, icosas);
|
||||||
|
|
||||||
|
return nice_icosa(nodes, icosa);
|
||||||
|
}
|
||||||
|
|
||||||
|
function nice_icosa(nodes, icosa) {
|
||||||
|
return icosa_nodes(nodes, icosa).map((n) => n.id).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const nodes = make_120cell_vertices();
|
const nodes = make_120cell_vertices();
|
||||||
|
|
||||||
// const chords = find_all_chords(nodes);
|
// const chords = find_all_chords(nodes);
|
||||||
// const chord3 = chords["1.74806"]; // these are edges of the 600-cells;
|
// const chord3 = chords["1.74806"]; // these are edges of the 600-cells;
|
||||||
// const pairs60 = neighbour_angles(chord3, nodes[0], "60.000");
|
|
||||||
// const icosas = partition_nodes(pairs60);
|
//const pairs60 = neighbour_angles(chord3, nodes[0], "60.000");
|
||||||
|
//const icosas = partition_nodes(pairs60);
|
||||||
|
|
||||||
|
make_120_partition(nodes, nodes[0])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
26
polytopes.js
26
polytopes.js
|
@ -119,6 +119,13 @@ export const cell16 = () => {
|
||||||
export const tesseract = () => {
|
export const tesseract = () => {
|
||||||
const nodes = PERMUTE.coordinates([1, 1, 1, 1], 0);
|
const nodes = PERMUTE.coordinates([1, 1, 1, 1], 0);
|
||||||
index_nodes(nodes);
|
index_nodes(nodes);
|
||||||
|
|
||||||
|
for( const n of nodes ) {
|
||||||
|
if( n.x * n.y * n.z * n.w > 0 ) {
|
||||||
|
n.label = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scale_nodes(nodes, Math.sqrt(2) / 2);
|
scale_nodes(nodes, Math.sqrt(2) / 2);
|
||||||
const links = auto_detect_edges(nodes, 4);
|
const links = auto_detect_edges(nodes, 4);
|
||||||
|
|
||||||
|
@ -168,6 +175,7 @@ export const cell24 = () => {
|
||||||
// see table in https://en.wikipedia.org/wiki/120-cell - maybe adapt the
|
// see table in https://en.wikipedia.org/wiki/120-cell - maybe adapt the
|
||||||
// unit radius table
|
// unit radius table
|
||||||
|
|
||||||
|
|
||||||
function make_120cell_vertices() {
|
function make_120cell_vertices() {
|
||||||
const phi = 0.5 * (1 + Math.sqrt(5));
|
const phi = 0.5 * (1 + Math.sqrt(5));
|
||||||
const r5 = Math.sqrt(5);
|
const r5 = Math.sqrt(5);
|
||||||
|
@ -177,23 +185,21 @@ function make_120cell_vertices() {
|
||||||
|
|
||||||
const nodes = [
|
const nodes = [
|
||||||
PERMUTE.coordinates([0, 0, 2, 2], 0),
|
PERMUTE.coordinates([0, 0, 2, 2], 0),
|
||||||
PERMUTE.coordinates([1, 1, 1, r5], 0),
|
PERMUTE.coordinates([1, 1, 1, r5], 1),
|
||||||
PERMUTE.coordinates([phi, phi, phi, phi2inv], 0),
|
PERMUTE.coordinates([phi, phi, phi, phi2inv], 2),
|
||||||
PERMUTE.coordinates([phiinv, phiinv, phiinv, phi2], 0),
|
PERMUTE.coordinates([phiinv, phiinv, phiinv, phi2], 3),
|
||||||
|
|
||||||
PERMUTE.coordinates([phi2, phi2inv, 1, 0], 0, true),
|
PERMUTE.coordinates([phi2, phi2inv, 1, 0], 4, true),
|
||||||
PERMUTE.coordinates([r5, phiinv, phi, 0], 0, true),
|
PERMUTE.coordinates([r5, phiinv, phi, 0], 5, true),
|
||||||
PERMUTE.coordinates([2, 1, phi, phiinv], 0, true),
|
PERMUTE.coordinates([2, 1, phi, phiinv], 6, true),
|
||||||
].flat();
|
].flat();
|
||||||
index_nodes(nodes);
|
index_nodes(nodes);
|
||||||
label_nodes(nodes, [1], 1);
|
|
||||||
label_nodes(nodes, [25, 41, 97, 109, 157, 161, 173, 177, 113, 37, 53, 93 ], 2);
|
|
||||||
|
|
||||||
label_nodes(nodes, [29, 45, 101, 105, 153, 165, 169, 181, 117, 33, 49, 89], 4);
|
|
||||||
scale_nodes(nodes, 0.5);
|
scale_nodes(nodes, 0.5);
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function label_nodes(nodes, ids, label) {
|
function label_nodes(nodes, ids, label) {
|
||||||
nodes.filter((n) => ids.includes(n.id)).map((n) => n.label = label);
|
nodes.filter((n) => ids.includes(n.id)).map((n) => n.label = label);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue