Geometry 以最少的步数绘制立方体顶点
在不从纸上拿起笔的情况下,绘制立方体所有顶点所需的最少步骤是多少 到目前为止,我已将其简化为16个步骤:Geometry 以最少的步数绘制立方体顶点,geometry,line,shape,coordinate-systems,vertices,Geometry,Line,Shape,Coordinate Systems,Vertices,在不从纸上拿起笔的情况下,绘制立方体所有顶点所需的最少步骤是多少 到目前为止,我已将其简化为16个步骤: 0, 0, 0 0, 0, 1 0, 1, 1 1, 1, 1 1, 1, 0 0, 1, 0 0, 0, 0 1, 0, 0 1, 0, 1 0, 0, 1 0, 1, 1 0, 1, 0 1, 1, 0 1, 0, 0 1, 0, 1 1, 1, 1 我认为它可以减少到16步以下,因为只有12个顶点需要绘制 您可以在three.js javascript中查看工作示例: 我为此编写了
0, 0, 0
0, 0, 1
0, 1, 1
1, 1, 1
1, 1, 0
0, 1, 0
0, 0, 0
1, 0, 0
1, 0, 1
0, 0, 1
0, 1, 1
0, 1, 0
1, 1, 0
1, 0, 0
1, 0, 1
1, 1, 1
我认为它可以减少到16步以下,因为只有12个顶点需要绘制
您可以在three.js javascript中查看工作示例:
我为此编写了一个小型蛮力求解器
- 最好的解决方案是使用16个顶点
- 计算耗时约11.6秒
- 全部是C++(OpenGL可视化)
//---------------------------------------------------------------------------
#define a 0.5
double pnt[]=
{
-a,-a,-a, // point 0
-a,-a,+a,
-a,+a,-a,
-a,+a,+a,
+a,-a,-a,
+a,-a,+a,
+a,+a,-a,
+a,+a,+a, // point 7
1e101,1e101,1e101, // end tag
};
#undef a
int lin[]=
{
0,1,
0,2,
0,4,
1,3,
1,5,
2,3,
2,6,
3,7,
4,5,
4,6,
5,7,
6,7,
-1,-1, // end tag
};
// int solution[]={ 0, 1, 3, 1, 5, 4, 0, 2, 3, 7, 5, 4, 6, 2, 6, 7, -1 }; // found polyline solution
//---------------------------------------------------------------------------
void draw_lin(double *pnt,int *lin)
{
glBegin(GL_LINES);
for (int i=0;lin[i]>=0;)
{
glVertex3dv(pnt+(lin[i]*3)); i++;
glVertex3dv(pnt+(lin[i]*3)); i++;
}
glEnd();
}
//---------------------------------------------------------------------------
void draw_pol(double *pnt,int *pol)
{
glBegin(GL_LINE_STRIP);
for (int i=0;pol[i]>=0;i++) glVertex3dv(pnt+(pol[i]*3));
glEnd();
}
//---------------------------------------------------------------------------
现在,解算器:
//---------------------------------------------------------------------------
struct _vtx // vertex
{
List<int> i; // connected to (vertexes...)
_vtx(){}; _vtx(_vtx& a){ *this=a; }; ~_vtx(){}; _vtx* operator = (const _vtx *a) { *this=*a; return this; }; /*_vtx* operator = (const _vtx &a) { ...copy... return this; };*/
};
const int _max=16; // know solution size (do not bother to find longer solutions)
int use[_max],uses=0; // temp line usage flag
int pol[_max],pols=0; // temp solution
int sol[_max+2],sols=0; // best found solution
List<_vtx> vtx; // model vertexes + connection info
//---------------------------------------------------------------------------
void _solve(int a)
{
_vtx *v; int i,j,k,l,a0,a1,b0,b1;
// add point to actual polyline
pol[pols]=a; pols++; v=&vtx[a];
// test for solution
for (l=0,i=0;i<uses;i++) use[i]=0;
for (a0=pol[0],a1=pol[1],i=1;i<pols;i++,a0=a1,a1=pol[i])
for (j=0,k=0;k<uses;k++)
{
b0=lin[j]; j++;
b1=lin[j]; j++;
if (!use[k]) if (((a0==b0)&&(a1==b1))||((a0==b1)&&(a1==b0))) { use[k]=1; l++; }
}
if (l==uses) // better solution found
if ((pols<sols)||(sol[0]==-1))
for (sols=0;sols<pols;sols++) sol[sols]=pol[sols];
// recursion only if pol not too big
if (pols+1<sols) for (i=0;i<v->i.num;i++) _solve(v->i.dat[i]);
// back to previous state
pols--; pol[pols]=-1;
}
//---------------------------------------------------------------------------
void solve(double *pnt,int *lin)
{
int i,j,a0,a1;
// init sizes
for (i=0;i<_max;i++) { use[i]=0; pol[i]=-1; sol[i]=-1; }
for(i=0,j=0;pnt[i]<1e100;i+=3,j++); vtx.allocate(j); vtx.num=j;
for(i=0;i<vtx.num;i++) vtx[i].i.num=0;
// init connections
for(uses=0,i=0;lin[i]>=0;uses++)
{
a0=lin[i]; i++;
a1=lin[i]; i++;
vtx[a0].i.add(a1);
vtx[a1].i.add(a0);
}
// start actual solution (does not matter which vertex on cube is first)
pols=0; sols=_max+1; _solve(0);
sol[sols]=-1; if (sol[0]<0) sols=0;
}
//---------------------------------------------------------------------------
名单
- 就是我的动态数组模板
相当于List x
int x[]
。。。在列表末尾添加5x.add(5)
是条目中使用的列表大小x.num
将列表大小预先分配到100个条目(以避免重新定位速度变慢)x.allocate(100)
- 每个顶点
对应于vtx[i]
表中的第i点pnt
- i[]列表包含连接到此顶点的每个顶点的索引
- 否则,将有for循环通过每个顶点作为起点
- 它将顶点索引添加到实际解决方案
pol[pols]
- 然后测试实际解决方案中存在多少行
- 如果从lin[]中绘制了所有的线,并且解决方案比已经找到的要小
- 将其复制为新解决方案
- 测试后若实际解不太长,则递归添加下一个顶点
- 作为连接到最后使用的顶点的顶点之一
- 限制组合的数量
- sols是使用的顶点数(第1行)
- 代码不是很干净,但是可以工作(很抱歉)
- 希望我没有忘记抄写一些东西
solve(pnt,lin); // call once to compute the solution
glColor3f(0.2,0.2,0.2); draw_lin(pnt,lin); // draw gray outline
glColor3f(1.0,1.0,1.0); draw_pol(pnt,sol); // overwrite by solution to visually check correctness (Z-buffer must pass also on equal values!!!)