首页 > 代码库 > 分形之万花筒
分形之万花筒
万花筒是一种光学玩具,只要往筒眼里一看,就会出现一朵美丽的“花”样。将它稍微转一下,又会出现另一种花的图案。不断地转,图案也在不断变化,所以叫“万花筒”。万花筒的图案是靠玻璃镜子反射而成的。它是由三面相交成60°角的镜子组成的,由于光的反射定律,放在三面镜子之间的每一件东西都会映出六个对称的图象来,构成一个六边形的图案.三面玻璃镜子组成一个三棱镜,再在一头放上一些各色玻璃碎片,这些碎片经过三面玻璃镜子的反射,就会出现对称的图案,看上去就像一朵朵盛开的花。
记得小时候我就亲手做过一个万花筒,虽然非常简陋,因为镜子条是摔出来的,但做好后有种创造了另外一个世界的感觉.这一节展示下我写的一个万花筒的程序.程序下载地址:http://files.cnblogs.com/WhyEngine/Phantoscope.7z
万花筒是由三面镜子构成,所以其图案是一系列的三角形网格,程序中最重要的是构造这种三角形网格.下面是生成网格顶点和纹理坐标的代码:
1 void YcRegularTriangleGridDrawer::UpdateVB() 2 { 3 if (!m_pVB) 4 { 5 return; 6 } 7 8 Vector2 vOffset; 9 Vertex_UV* v;10 Yuint index;11 Yuint odd_even;12 m_pVB->Lock(0, 0, (void**)&v, 0);13 {14 for (Yuint i = 0; i <= m_uiRow; i++)15 {16 odd_even = (i&0x1);17 vOffset.x = odd_even ? m_fCellSize*0.5f : 0.0f;18 vOffset.x -= m_fCellSize*m_uiCol*0.5f;19 vOffset.y = (m_uiRow*0.5f - i)*m_fCellSize*YD_SIN_60;20 21 for (Yuint j = 0; j <= m_uiCol; j++)22 {23 index = i*(m_uiCol + 1) + j;24 25 v[index]._x = vOffset.x + j*m_fCellSize;26 v[index]._y = vOffset.y;27 v[index]._z = 0.0f;28 29 if (odd_even)30 {31 v[index]._u = m_uvTexcoords[(2+j)%3].x;32 v[index]._v = m_uvTexcoords[(2+j)%3].y;33 }34 else35 {36 v[index]._u = m_uvTexcoords[j%3].x;37 v[index]._v = m_uvTexcoords[j%3].y;38 }39 }40 }41 }42 m_pVB->Unlock();43 }
顶点有了后,三角形的索引也很重要:
1 WORD* ib; 2 Yuint odd_even; 3 Yuint index; 4 m_pIB->Lock(0, 0, (void**)&ib, 0); 5 { 6 for (Yuint i = 0; i < m_uiRow; i++) 7 { 8 odd_even = (i&0x1); 9 for (Yuint j = 0; j < m_uiCol; j++)10 {11 index = i*m_uiCol + j;12 13 if (odd_even)14 {15 ib[index*6 + 0] = (WORD)(i*(m_uiCol + 1) + j);16 ib[index*6 + 1] = (WORD)((i+1)*(m_uiCol + 1) + j + 1);17 ib[index*6 + 2] = (WORD)((i+1)*(m_uiCol + 1) + j);18 19 ib[index*6 + 3] = (WORD)(i*(m_uiCol + 1) + j);20 ib[index*6 + 4] = (WORD)(i*(m_uiCol + 1) + j + 1);21 ib[index*6 + 5] = (WORD)((i+1)*(m_uiCol + 1) + j + 1);22 }23 else24 {25 ib[index*6 + 0] = (WORD)(i*(m_uiCol + 1) + j);26 ib[index*6 + 1] = (WORD)(i*(m_uiCol + 1) + j + 1);27 ib[index*6 + 2] = (WORD)((i+1)*(m_uiCol + 1) + j);28 29 ib[index*6 + 3] = (WORD)((i+1)*(m_uiCol + 1) + j);30 ib[index*6 + 4] = (WORD)(i*(m_uiCol + 1) + j + 1);31 ib[index*6 + 5] = (WORD)((i+1)*(m_uiCol + 1) + j + 1);32 }33 }34 }35 }36 m_pIB->Unlock();
程序启动后,会出现满屏的三角形网格.
将任意一图像文件拖入窗体内,即可看到万花筒的样子.
在窗体右下角会显示拖入图像.上面有个三角形,鼠标拖动三角形的顶点,可以改变三角形的形状,从而改变万花筒的视图.
这是个3D程序,鼠标右键的拖动可以改变视角.
X用于恢复为默认视角.
W用于网格与万花筒的切换.
F11用于全屏切换.
分形之万花筒
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。