n维超立方体中的连接点
connecting points in n-dimensional hyper cube
我正在尝试在不使用 p3d 渲染器的情况下创建类似 3d 的处理草图。我已经设法制作了一个立方体,但为此我对所有坐标和连接进行了硬编码,一旦你想添加另一个维度,它就会开始变得有点无聊。所以我创建了一个函数来创建所有坐标:
float[][] cube(int dims, float w) {
int outputSize = (int)pow(2, dims);
float[] temp = new float[dims];
float[][] res = new float[outputSize][dims];
Arrays.fill(temp, w);
res[0] = temp.clone();
for (int i = 0; i < outputSize - 1; i++) {
for (int j = dims - 1; true; j--) {
temp[j] *= -1;
if (temp[j] < 0) {
break;
}
}
res[i + 1] = temp.clone();
}
return res;
}
它只是通过使用二进制来工作,所以输入 (2, 1) 立方体将是:
[[1, 1], [1, -1], [-1, 1], [-1, -1]]
它工作正常,但问题是它只连接 returns 个角落而不是 个角落,但我找不到有效的方法来做到这一点。我需要另一个函数 returns 要连接的索引。
下面是函数在给定上述数组的情况下应该做什么的示例:
[[0, 1], [1, 3], [3, 2], [2, 0]]
(内部数组可能顺序不同)
有没有已知的算法可以连接n维立方体的角?
如果其他积分生成有帮助,我可以更改其他功能。
这是一种迭代生成坐标和索引的方法:
- 从一个维度为
n
的立方体开始
- 制作两个立方体副本,并在第
n + 1
轴 上的每个极值坐标(例如 -1 和 +1)放置一个
- 创建边以连接立方体上每对对应的顶点
您已经知道顶点数V(n) = 2^n
。由于添加到 n + 1
立方体的边数等于此(所有对应的顶点对)加上复制的 n
立方体的边数,因此边数的递归关系为:
E(n) = 2 * E(n - 1) + V(n - 1) // copies + joining edges
E(1) = 1 // base case for n = 1
--> E(n) = n * 2^(n - 1)
n | E(n)
-------------
1 | 1
2 | 4
3 | 12
4 | 32
5 | 80
这允许在复制新立方体/添加新边时预先分配所需边的数量并计算索引偏移量。
代码:
// edge index
class Edge
{
public int A, B;
public Edge(int a, int b)
{
A = a; B = b;
}
public Edge shift(int n)
{
return new Edge(A + n, B + n);
}
}
// cube class
class Cube
{
// I'll leave out the get-functions etc here
private float[][] m_verts;
private Edge[] m_edges;
public Cube(float[][] v, Edge[] e)
{
m_verts = v;
m_edges = e;
}
}
Cube cube_N(int dims, float w)
{
// base case
if (dims < 1)
return null;
// calculate buffer sizes
int dpow2 = 1 << dims;
int numVerts = dpow2;
int numEdges = dims * (dpow2 / 2);
// buffers
float[] temp = new float[dims];
float[][] verts = new float[numVerts][];
Edge[] edges = new Edge[numEdges];
// base case creation
Arrays.fill(temp, w);
verts[0] = temp.clone();
edges[0] = new Edge(0, 1);
// iterative step
for (int i = 0; i < dims; i++)
{
int nV = 1 << i;
int nE = i * (nV / 2);
// copy + shift vertices
for (int j = 0; j < nV; j++)
{
float[] v = verts[j].clone();
v[i] = -w;
verts[nV + j] = v;
}
// copy + shift previous edges
for (int j = 0; j < nE; j++)
{
edges[nE + j] = edges[j].shift(nV);
}
// create new edges to join cube copies
int off = nE * 2;
for (int j = 0; j < nV; j++)
{
edges[off + j] = new Edge(j, nV + j);
}
}
return new Cube(verts, edges);
}
n = 3
的结果:
verts:
[1, 1, 1], [-1, 1, 1], [1, -1, 1], [-1, -1, 1],
[1, 1, -1], [-1, 1, -1], [1, -1, -1], [-1, -1, -1]
edges:
[0, 1], [2, 3], [0, 2], [1, 3], [4, 5], [6, 7],
[4, 6], [5, 7], [0, 4], [1, 5], [2, 6], [3, 7]
n = 4
的结果:
verts:
[1, 1, 1, 1], [-1, 1, 1, 1], [1, -1, 1, 1], [-1, -1, 1, 1],
[1, 1, -1, 1], [-1, 1, -1, 1], [1, -1, -1, 1], [-1, -1, -1, 1],
[1, 1, 1, -1], [-1, 1, 1, -1], [1, -1, 1, -1], [-1, -1, 1, -1],
[1, 1, -1, -1], [-1, 1, -1, -1], [1, -1, -1, -1], [-1, -1, -1, -1]
edges:
[0 , 1], [2 , 3], [0 , 2], [1 , 3], [4, 5], [6 , 7], [4 , 6], [5 , 7],
[0 , 4], [1 , 5], [2 , 6], [3 , 7], [8, 9], [10, 11], [8 , 10], [9 , 11],
[12, 13], [14, 15], [12, 14], [13, 15], [8, 12], [9 , 13], [10, 14], [11, 15],
[0 , 8], [1 , 9], [2 , 10], [3 , 11], [4, 12], [5 , 13], [6 , 14], [7 , 15]
我正在尝试在不使用 p3d 渲染器的情况下创建类似 3d 的处理草图。我已经设法制作了一个立方体,但为此我对所有坐标和连接进行了硬编码,一旦你想添加另一个维度,它就会开始变得有点无聊。所以我创建了一个函数来创建所有坐标:
float[][] cube(int dims, float w) {
int outputSize = (int)pow(2, dims);
float[] temp = new float[dims];
float[][] res = new float[outputSize][dims];
Arrays.fill(temp, w);
res[0] = temp.clone();
for (int i = 0; i < outputSize - 1; i++) {
for (int j = dims - 1; true; j--) {
temp[j] *= -1;
if (temp[j] < 0) {
break;
}
}
res[i + 1] = temp.clone();
}
return res;
}
它只是通过使用二进制来工作,所以输入 (2, 1) 立方体将是:
[[1, 1], [1, -1], [-1, 1], [-1, -1]]
它工作正常,但问题是它只连接 returns 个角落而不是 个角落,但我找不到有效的方法来做到这一点。我需要另一个函数 returns 要连接的索引。
下面是函数在给定上述数组的情况下应该做什么的示例:
[[0, 1], [1, 3], [3, 2], [2, 0]]
(内部数组可能顺序不同)
有没有已知的算法可以连接n维立方体的角?
如果其他积分生成有帮助,我可以更改其他功能。
这是一种迭代生成坐标和索引的方法:
- 从一个维度为
n
的立方体开始
- 制作两个立方体副本,并在第
n + 1
轴 上的每个极值坐标(例如 -1 和 +1)放置一个
- 创建边以连接立方体上每对对应的顶点
您已经知道顶点数V(n) = 2^n
。由于添加到 n + 1
立方体的边数等于此(所有对应的顶点对)加上复制的 n
立方体的边数,因此边数的递归关系为:
E(n) = 2 * E(n - 1) + V(n - 1) // copies + joining edges
E(1) = 1 // base case for n = 1
--> E(n) = n * 2^(n - 1)
n | E(n)
-------------
1 | 1
2 | 4
3 | 12
4 | 32
5 | 80
这允许在复制新立方体/添加新边时预先分配所需边的数量并计算索引偏移量。
代码:
// edge index
class Edge
{
public int A, B;
public Edge(int a, int b)
{
A = a; B = b;
}
public Edge shift(int n)
{
return new Edge(A + n, B + n);
}
}
// cube class
class Cube
{
// I'll leave out the get-functions etc here
private float[][] m_verts;
private Edge[] m_edges;
public Cube(float[][] v, Edge[] e)
{
m_verts = v;
m_edges = e;
}
}
Cube cube_N(int dims, float w)
{
// base case
if (dims < 1)
return null;
// calculate buffer sizes
int dpow2 = 1 << dims;
int numVerts = dpow2;
int numEdges = dims * (dpow2 / 2);
// buffers
float[] temp = new float[dims];
float[][] verts = new float[numVerts][];
Edge[] edges = new Edge[numEdges];
// base case creation
Arrays.fill(temp, w);
verts[0] = temp.clone();
edges[0] = new Edge(0, 1);
// iterative step
for (int i = 0; i < dims; i++)
{
int nV = 1 << i;
int nE = i * (nV / 2);
// copy + shift vertices
for (int j = 0; j < nV; j++)
{
float[] v = verts[j].clone();
v[i] = -w;
verts[nV + j] = v;
}
// copy + shift previous edges
for (int j = 0; j < nE; j++)
{
edges[nE + j] = edges[j].shift(nV);
}
// create new edges to join cube copies
int off = nE * 2;
for (int j = 0; j < nV; j++)
{
edges[off + j] = new Edge(j, nV + j);
}
}
return new Cube(verts, edges);
}
n = 3
的结果:
verts:
[1, 1, 1], [-1, 1, 1], [1, -1, 1], [-1, -1, 1],
[1, 1, -1], [-1, 1, -1], [1, -1, -1], [-1, -1, -1]
edges:
[0, 1], [2, 3], [0, 2], [1, 3], [4, 5], [6, 7],
[4, 6], [5, 7], [0, 4], [1, 5], [2, 6], [3, 7]
n = 4
的结果:
verts:
[1, 1, 1, 1], [-1, 1, 1, 1], [1, -1, 1, 1], [-1, -1, 1, 1],
[1, 1, -1, 1], [-1, 1, -1, 1], [1, -1, -1, 1], [-1, -1, -1, 1],
[1, 1, 1, -1], [-1, 1, 1, -1], [1, -1, 1, -1], [-1, -1, 1, -1],
[1, 1, -1, -1], [-1, 1, -1, -1], [1, -1, -1, -1], [-1, -1, -1, -1]
edges:
[0 , 1], [2 , 3], [0 , 2], [1 , 3], [4, 5], [6 , 7], [4 , 6], [5 , 7],
[0 , 4], [1 , 5], [2 , 6], [3 , 7], [8, 9], [10, 11], [8 , 10], [9 , 11],
[12, 13], [14, 15], [12, 14], [13, 15], [8, 12], [9 , 13], [10, 14], [11, 15],
[0 , 8], [1 , 9], [2 , 10], [3 , 11], [4, 12], [5 , 13], [6 , 14], [7 , 15]