Added inscriptions for 600-cell, improved the gui, you can now see
all five 600-cells in the 120-cell for full mindbendingfeature-inscriptions
parent
73c1cb0193
commit
fc5acaeda8
33
gui.js
33
gui.js
|
@ -6,7 +6,10 @@ const DEFAULTS = {
|
||||||
thickness: 0.25,
|
thickness: 0.25,
|
||||||
nodesize: 1.25,
|
nodesize: 1.25,
|
||||||
linkopacity: 0.5,
|
linkopacity: 0.5,
|
||||||
|
link2opacity: 0.5,
|
||||||
shape: '120-cell',
|
shape: '120-cell',
|
||||||
|
inscribed: false,
|
||||||
|
inscribe_all: false,
|
||||||
color: 0x3293a9,
|
color: 0x3293a9,
|
||||||
background: 0xd4d4d4,
|
background: 0xd4d4d4,
|
||||||
hyperplane: 2,
|
hyperplane: 2,
|
||||||
|
@ -19,14 +22,17 @@ const DEFAULTS = {
|
||||||
|
|
||||||
class FourDGUI {
|
class FourDGUI {
|
||||||
|
|
||||||
constructor(createShape, setColor, setBackground, setLinkOpacity) {
|
constructor(changeShape, setColor, setBackground, setLinkOpacity) {
|
||||||
this.gui = new GUI();
|
this.gui = new GUI();
|
||||||
this.parseLinkParams();
|
this.parseLinkParams();
|
||||||
const guiObj = this;
|
const guiObj = this;
|
||||||
this.params = {
|
this.params = {
|
||||||
shape: this.link['shape'],
|
shape: this.link['shape'],
|
||||||
|
inscribed: this.link['inscribed'],
|
||||||
|
inscribe_all: this.link['inscribe_all'],
|
||||||
thickness: this.link['thickness'],
|
thickness: this.link['thickness'],
|
||||||
linkopacity: this.link['linkopacity'],
|
linkopacity: this.link['linkopacity'],
|
||||||
|
link2opacity: this.link['linkopacity'],
|
||||||
nodesize: this.link['nodesize'],
|
nodesize: this.link['nodesize'],
|
||||||
color: this.link['color'],
|
color: this.link['color'],
|
||||||
background: this.link['background'],
|
background: this.link['background'],
|
||||||
|
@ -39,12 +45,19 @@ class FourDGUI {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.gui.add(this.params, 'shape',
|
this.gui.add(this.params, 'shape',
|
||||||
[ '5-cell', '16-cell', 'tesseract', '24-cell', '600-cell', '120-cell', '120-cell-inscribed' ]
|
[ '5-cell', '16-cell', 'tesseract',
|
||||||
).onChange(createShape)
|
'24-cell', '600-cell', '120-cell' ]
|
||||||
|
).onChange(changeShape)
|
||||||
|
this.gui.add(this.params, 'inscribed').onChange(changeShape);
|
||||||
|
this.gui.add(this.params, 'inscribe_all').onChange(changeShape);
|
||||||
this.gui.add(this.params, 'hyperplane', 1.5, 2.25);
|
this.gui.add(this.params, 'hyperplane', 1.5, 2.25);
|
||||||
this.gui.add(this.params, 'thickness', 0.1, 2);
|
this.gui.add(this.params, 'thickness', 0.1, 2);
|
||||||
this.gui.add(this.params, 'linkopacity', 0, 1).onChange(setLinkOpacity);
|
this.gui.add(this.params, 'linkopacity', 0, 1).onChange(
|
||||||
|
(v) => setLinkOpacity(v, true)
|
||||||
|
);
|
||||||
|
this.gui.add(this.params, 'link2opacity', 0, 1).onChange(
|
||||||
|
(v) => setLinkOpacity(v, false)
|
||||||
|
);
|
||||||
this.gui.add(this.params, 'nodesize', 0.1, 4);
|
this.gui.add(this.params, 'nodesize', 0.1, 4);
|
||||||
this.gui.addColor(this.params, 'color').onChange(setColor);
|
this.gui.addColor(this.params, 'color').onChange(setColor);
|
||||||
this.gui.addColor(this.params, 'background').onChange(setBackground);
|
this.gui.addColor(this.params, 'background').onChange(setBackground);
|
||||||
|
@ -79,6 +92,7 @@ class FourDGUI {
|
||||||
parseLinkParams() {
|
parseLinkParams() {
|
||||||
this.linkUrl = new URL(window.location.toLocaleString());
|
this.linkUrl = new URL(window.location.toLocaleString());
|
||||||
this.link = {};
|
this.link = {};
|
||||||
|
const guiObj = this;
|
||||||
|
|
||||||
this.urlParams = this.linkUrl.searchParams;
|
this.urlParams = this.linkUrl.searchParams;
|
||||||
for( const param of [ "shape", "rotation" ]) {
|
for( const param of [ "shape", "rotation" ]) {
|
||||||
|
@ -89,10 +103,13 @@ class FourDGUI {
|
||||||
this.link[param] = DEFAULTS[param];
|
this.link[param] = DEFAULTS[param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const guiObj = this;
|
for( const param of [ "inscribed", "inscribe_all"] ) {
|
||||||
|
this.link[param] = ( this.urlParams.get(param) === 'y' );
|
||||||
|
}
|
||||||
this.link['hyperplane'] = this.numParam('hyperplane', parseFloat);
|
this.link['hyperplane'] = this.numParam('hyperplane', parseFloat);
|
||||||
this.link['thickness'] = this.numParam('thickness', parseFloat);
|
this.link['thickness'] = this.numParam('thickness', parseFloat);
|
||||||
this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
|
this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
|
||||||
|
this.link['link2opacity'] = this.numParam('link2opacity', parseFloat);
|
||||||
this.link['nodesize'] = this.numParam('nodesize', parseFloat);
|
this.link['nodesize'] = this.numParam('nodesize', parseFloat);
|
||||||
this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
|
this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
|
||||||
this.link['background'] = this.numParam('background', (s) => guiObj.stringToHex(s));
|
this.link['background'] = this.numParam('background', (s) => guiObj.stringToHex(s));
|
||||||
|
@ -104,8 +121,12 @@ class FourDGUI {
|
||||||
copyUrl() {
|
copyUrl() {
|
||||||
const url = new URL(this.linkUrl.origin + this.linkUrl.pathname);
|
const url = new URL(this.linkUrl.origin + this.linkUrl.pathname);
|
||||||
url.searchParams.append("shape", this.params.shape);
|
url.searchParams.append("shape", this.params.shape);
|
||||||
|
url.searchParams.append("inscribed", this.params.inscribed ? 'y': 'n');
|
||||||
|
url.searchParams.append("inscribe_all", this.params.inscribe_all ? 'y': 'n');
|
||||||
url.searchParams.append("thickness", this.params.thickness.toString());
|
url.searchParams.append("thickness", this.params.thickness.toString());
|
||||||
url.searchParams.append("nodesize", this.params.nodesize.toString());
|
url.searchParams.append("nodesize", this.params.nodesize.toString());
|
||||||
|
url.searchParams.append("linkopacity", this.params.thickness.toString());
|
||||||
|
url.searchParams.append("link2opacity", this.params.nodesize.toString());
|
||||||
url.searchParams.append("color", this.hexToString(this.params.color));
|
url.searchParams.append("color", this.hexToString(this.params.color));
|
||||||
url.searchParams.append("background", this.hexToString(this.params.background));
|
url.searchParams.append("background", this.hexToString(this.params.background));
|
||||||
url.searchParams.append("hyperplane", this.params.hyperplane.toString());
|
url.searchParams.append("hyperplane", this.params.hyperplane.toString());
|
||||||
|
|
49
main.js
49
main.js
|
@ -65,17 +65,39 @@ const STRUCTURES = {
|
||||||
'tesseract': POLYTOPES.tesseract(),
|
'tesseract': POLYTOPES.tesseract(),
|
||||||
'24-cell': POLYTOPES.cell24(),
|
'24-cell': POLYTOPES.cell24(),
|
||||||
'120-cell': POLYTOPES.cell120(),
|
'120-cell': POLYTOPES.cell120(),
|
||||||
'120-cell-inscribed': POLYTOPES.cell120_inscribed(),
|
'120-cell-all-inscribed': POLYTOPES.cell120_all_inscribed(),
|
||||||
'600-cell': POLYTOPES.cell600()
|
'600-cell': POLYTOPES.cell600(),
|
||||||
|
'600-cell-all-inscribed': POLYTOPES.cell600_all_inscribed(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const INSCRIBED = {
|
||||||
|
'120-cell': POLYTOPES.cell120_inscribed(),
|
||||||
|
'600-cell': POLYTOPES.cell600_inscribed(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const ALL_INSCRIBED = {
|
||||||
|
'120-cell': POLYTOPES.cell120_all_inscribed(),
|
||||||
|
'600-cell': POLYTOPES.cell600_all_inscribed(),
|
||||||
|
}
|
||||||
|
|
||||||
let shape = false;
|
let shape = false;
|
||||||
|
|
||||||
function createShape(name) {
|
function createShape(name, inscribed, all) {
|
||||||
if( shape ) {
|
if( shape ) {
|
||||||
scene.remove(shape);
|
scene.remove(shape);
|
||||||
}
|
}
|
||||||
shape = new FourDShape(node_ms, link_ms, face_ms, STRUCTURES[name]);
|
let structure = STRUCTURES[name];
|
||||||
|
if( inscribed ) {
|
||||||
|
if( name in INSCRIBED ) {
|
||||||
|
if( all ) {
|
||||||
|
structure = ALL_INSCRIBED[name];
|
||||||
|
} else {
|
||||||
|
structure = INSCRIBED[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shape = new FourDShape(node_ms, link_ms, face_ms, structure);
|
||||||
scene.add(shape);
|
scene.add(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +119,24 @@ function setBackground(c) {
|
||||||
scene.background = new THREE.Color(c)
|
scene.background = new THREE.Color(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLinkOpacity(o) {
|
function setLinkOpacity(o, primary) {
|
||||||
for( const lm of link_ms ) {
|
if( primary ) {
|
||||||
|
link_ms[0].opacity = o;
|
||||||
|
} else {
|
||||||
|
for( const lm of link_ms.slice(1) ) {
|
||||||
lm.opacity = o;
|
lm.opacity = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const gui = new FourDGUI(createShape, setColors, setBackground, setLinkOpacity);
|
let gui; //
|
||||||
|
|
||||||
|
function changeShape() {
|
||||||
|
console.log("change shape!")
|
||||||
|
createShape(gui.params.shape, gui.params.inscribed, gui.params.inscribe_all);
|
||||||
|
}
|
||||||
|
|
||||||
|
gui = new FourDGUI(changeShape, setColors, setBackground, setLinkOpacity);
|
||||||
|
|
||||||
// these are here to pick up colour settings from the URL params
|
// these are here to pick up colour settings from the URL params
|
||||||
setColors(gui.params.color);
|
setColors(gui.params.color);
|
||||||
|
@ -146,7 +179,7 @@ renderer.domElement.addEventListener("pointerup", (event) => {
|
||||||
dragging = false;
|
dragging = false;
|
||||||
})
|
})
|
||||||
|
|
||||||
createShape(gui.params.shape);
|
createShape(gui.params.shape, gui.params.inscribed, gui.params.inscribe_all);
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame( animate );
|
requestAnimationFrame( animate );
|
||||||
|
|
62
polytopes.js
62
polytopes.js
|
@ -151,6 +151,11 @@ const CELL24_INDEXING = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function node_by_id(nodes, nid) {
|
||||||
|
const ns = nodes.filter((n) => n.id === nid);
|
||||||
|
return ns[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const cell24 = () => {
|
export const cell24 = () => {
|
||||||
const nodes = PERMUTE.coordinates([0, 0, 1, 1], 0);
|
const nodes = PERMUTE.coordinates([0, 0, 1, 1], 0);
|
||||||
|
@ -163,6 +168,15 @@ export const cell24 = () => {
|
||||||
index_nodes(nodes);
|
index_nodes(nodes);
|
||||||
const links = auto_detect_edges(nodes, 8);
|
const links = auto_detect_edges(nodes, 8);
|
||||||
|
|
||||||
|
links.map((l) => {
|
||||||
|
const ls = [ l.source, l.target ].map((nid) => node_by_id(nodes, nid).label);
|
||||||
|
for ( const c of [1, 2, 3] ) {
|
||||||
|
if( ! ls.includes(c) ) {
|
||||||
|
l.label = c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
links: links,
|
links: links,
|
||||||
|
@ -357,7 +371,7 @@ export const cell120 = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const cell120_inscribed = () => {
|
const cell120_some_inscribed = (ps) => {
|
||||||
const nodes = make_120cell_vertices();
|
const nodes = make_120cell_vertices();
|
||||||
const links = auto_detect_edges(nodes, 4);
|
const links = auto_detect_edges(nodes, 4);
|
||||||
|
|
||||||
|
@ -366,7 +380,7 @@ export const cell120_inscribed = () => {
|
||||||
const all_links = links;
|
const all_links = links;
|
||||||
all_links.map((l) => l.label = 0);
|
all_links.map((l) => l.label = 0);
|
||||||
|
|
||||||
for( const p of [ 5 ]) {
|
for( const p of ps) {
|
||||||
const nodes600 = nodes.filter((n) => n.label === p);
|
const nodes600 = nodes.filter((n) => n.label === p);
|
||||||
const links600 = auto_detect_edges(nodes600, 12);
|
const links600 = auto_detect_edges(nodes600, 12);
|
||||||
links600.map((l) => l.label = p);
|
links600.map((l) => l.label = p);
|
||||||
|
@ -383,6 +397,9 @@ export const cell120_inscribed = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const cell120_inscribed = () => cell120_some_inscribed([5]);
|
||||||
|
export const cell120_all_inscribed = () => cell120_some_inscribed([1,2,3,4,5]);
|
||||||
|
|
||||||
|
|
||||||
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
||||||
|
|
||||||
|
@ -518,7 +535,7 @@ function make_600cell_vertices() {
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
for( const n of nodes ) {
|
for( const n of nodes ) {
|
||||||
n.label = label_vertex(n, coords, partition600) - 1;
|
n.label = label_vertex(n, coords, partition600);
|
||||||
}
|
}
|
||||||
|
|
||||||
for( const n of nodes ) {
|
for( const n of nodes ) {
|
||||||
|
@ -570,3 +587,42 @@ export const cell600 = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cell600_some_inscribed = (ps) => {
|
||||||
|
const nodes = make_600cell_vertices();
|
||||||
|
const links = auto_detect_edges(nodes, 12);
|
||||||
|
|
||||||
|
const all_links = links;
|
||||||
|
all_links.map((l) => l.label = 0);
|
||||||
|
|
||||||
|
for( const p of ps) {
|
||||||
|
const nodes24 = nodes.filter((n) => n.label === p);
|
||||||
|
const links24 = auto_detect_edges(nodes24, 8);
|
||||||
|
links24.map((l) => l.label = p);
|
||||||
|
all_links.push(...links24);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodes: nodes,
|
||||||
|
links: all_links,
|
||||||
|
geometry: {
|
||||||
|
node_size: 0.02,
|
||||||
|
link_size: 0.02
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodes: nodes,
|
||||||
|
links: links,
|
||||||
|
geometry: {
|
||||||
|
node_size: 0.02,
|
||||||
|
link_size: 0.02
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const cell600_inscribed = () => cell600_some_inscribed([5]);
|
||||||
|
export const cell600_all_inscribed = () => cell600_some_inscribed([1,2,3,4,5]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue