Skip to content

Instantly share code, notes, and snippets.

@samsartor
Last active August 29, 2015 14:26
Show Gist options
  • Save samsartor/4d58150bba9f000ed1ce to your computer and use it in GitHub Desktop.
Save samsartor/4d58150bba9f000ed1ce to your computer and use it in GitHub Desktop.
Create n-dimentional plexispheres!
(function() {
var arr = function(length, fill) {
var arr = [];
for (var i = 0; i < length; i++)
{
arr.push(fill);
}
return arr;
};
var arrbut = function(arr, but) {
var out = [];
for (var i in arr) {
if (i != but)
{
out.push(arr[i]);
}
}
return out;
}
var mixverts = function(verts) {
var dim = verts[0].length;
var vert = arr(dim, 0);
for (var i in verts)
{
for (var j in verts[i])
{
vert[j] += verts[i][j] / verts.length;
}
}
return vert;
}
var simplex = function(dim) {
var geo = {verts: [], facets: []};
for (var i = 0; i < dim + 1; i++)
{
geo.verts.push(arr(dim, null));
for (var j = i + 1; j < dim; j++)
{
geo.verts[i][j] = 0;
}
}
//https://en.wikipedia.org/wiki/Simplex#Cartesian_coordinates_for_regular_n-dimensional_simplex_in_Rn
var dotsolve = 1;
var dotrem = -1 / dim;
for (var i = 0; i < dim; i++)
{
var ssum = 0;
for (var j = 0; j < i; j++)
{
ssum += geo.verts[i][j] * geo.verts[i][j];
}
var pythsolve = geo.verts[i][i] = Math.sqrt(1 - ssum);
dotsolve = dotrem / pythsolve;
for (var j = i + 1; j < dim + 1; j++)
{
geo.verts[j][i] = dotsolve;
}
dotrem -= dotsolve * dotsolve;
}
for (var i = 0; i < dim + 1; i++)
{
var facet = [];
for (var j = 0; j < dim + 1; j++)
{
if (i != j)
{
facet.push(j);
}
}
geo.facets.push(facet);
}
return geo;
};
var sub = {
center: function (geo, dim) {
var newfacets = [];
for (var i in geo.facets)
{
var facet = geo.facets[i];
var vertind = geo.verts.length;
var verts = [];
for (var j = 0; j < dim; j++)
{
var newfacet = [];
for (var k = 0; k < dim; k++)
{
verts.push(geo.verts[facet[j]]);
if (k != j)
{
newfacet.push(facet[k]);
}
}
newfacet.push(vertind);
newfacets.push(newfacet);
}
geo.verts.push(mixverts(verts));
}
geo.facets = newfacets;
return geo;
},
edge: function (geo, dim) {
var edges = {};
for (var i in geo.facets)
{
var facet = geo.facets[i];
var newfacet = [];
for (var j = 0; j < facet.length; j++)
{
var sel = arrbut(facet, j);
sel.sort();
var edge = edges[sel];
if (!edge)
{
var verts = [];
for (var k in sel)
{
verts.push(geo.verts[sel[k]]);
}
edge = geo.verts.length;
edges[sel] = edge;
geo.verts.push(mixverts(verts));
}
newfacet.push(edge);
}
for (var j = 0; j < facet.length; j++)
{
var nextfacet = [facet[j]];
for (var k = 0; k < facet.length; k++)
{
if (k != j)
{
nextfacet.push(newfacet[k]);
}
}
geo.facets.push(nextfacet);
}
geo.facets[i] = newfacet;
}
return geo;
}
};
var norm = function (vert)
{
var ssum = 0;
for (var i in vert)
{
ssum += vert[i] * vert[i];
}
ssum = Math.sqrt(ssum);
for (var i in vert)
{
vert[i] /= ssum;
}
return vert;
}
plexisphere = function(pos, radius, subdiv, mode, normmode) {
var dim = pos.length;
if (!sub[mode])
{
console.log("fail");
return;
}
var geo = simplex(dim);
for (var i = 0; i < subdiv; i++)
{
geo = sub[mode](geo, dim);
if (normmode == "each")
{
for (var j in geo.verts)
{
norm(geo.verts[j]);
}
}
}
if (normmode == "last")
{
for (var i in geo.verts)
{
norm(geo.verts[i]);
}
}
for (var i in geo.verts)
{
for (var j = 0; j < dim; j++)
{
geo.verts[i][j] *= radius;
geo.verts[i][j] += pos[j];
}
}
return geo;
};
})();
var toobj = function(geo)
{
var obj = "";
for (var i in geo.verts)
{
var vert = geo.verts[i];
obj += "v";
for (var j in vert)
{
obj += " " + vert[j];
}
obj += "\n";
}
for (var i in geo.facets)
{
obj += "\n";
var facet = geo.facets[i];
obj += "f";
for (var j in facet)
{
obj += " " + (facet[j] + 1);
}
}
return obj;
}
@samsartor
Copy link
Author

@samsartor
Copy link
Author

toobj(plexisphere([0, 0, 0], 5, 6, "edge", "last")); //nice 3-d plexisphere as a .obj model
plexisphere([0, 0, 0, 0], 5, 3, "center", "each"); //wtf 5-d thing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment