zoukankan      html  css  js  c++  java
  • 分形之万花筒

          万花筒是一种光学玩具,只要往筒眼里一看,就会出现一朵美丽的“花”样。将它稍微转一下,又会出现另一种花的图案。不断地转,图案也在不断变化,所以叫“万花筒”。万花筒的图案是靠玻璃镜子反射而成的。它是由三面相交成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                 else
    35                 {
    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                 else
    24                 {
    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用于全屏切换.

  • 相关阅读:
    Spring Boot全日志设置
    SpringBoot整合Quartz
    Kubernetes网络方案的三大类别和六个场景
    微服务化之缓存的设计
    金融创新业务基于容器云的微服务化实践
    致传统企业朋友:不够痛就别微服务,有坑 (1)
    致传统企业朋友:不够痛就别微服务,有坑 (2)
    The Beam Model:Stream & Tables翻译(上)
    细说Mammut大数据系统测试环境Docker迁移之路
    [译] 关于 SPA,你需要掌握的 4 层 (1)
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/3980673.html
Copyright © 2011-2022 走看看