屏保:画线圈LineFlower

LineFlowerSP

      小时候玩过一种画线圈的玩具,将一个圆形齿轮在一个大圈里转,会画出各种图形来.这个程序就是模仿它做的.算法原理:将一个圆围绕着另一个大圆公转,并且它还做自转运动.那么圆内一点的运动轨迹就能生成一个奇妙的图形.更奇妙的是,一个小小参数的改变,会使整个画面完全不同.
      程序启动后,会随机生成不同的图形,点击鼠标或按下键盘任意按键会自动退出.使用鼠标滚轮滚动进行图形切换.我的博客头像就是用这个软件生成的.

下载地址:

https://files.cnblogs.com/WhyEngine/LineFlower%E5%B1%8F%E4%BF%9D.zip

图形生成算法代码:

  1 void        CLineFlowerSPEntity::Reset()
  2 {
  3     m_nFinishTime = 0;
  4     m_nVerticesNum = 0;
  5     m_nPlayVertices = 2;
  6 
  7     UINT width;
  8     UINT height;
  9     m_pDX9Render->GetBackBufferSize(width, height);
 10 
 11     Vector2 vScreenCenter(width*0.5f, height*0.5f);
 12 
 13     Yreal screenCircleRadius = width < height ? width*0.5f : height*0.5f;
 14     if (screenCircleRadius < 10.0f)
 15     {
 16         return;
 17     }
 18 
 19     Yreal rotateCircleRadius = yf_rand_real(screenCircleRadius - 128.0f);
 20     Yreal fixCircleRadius = screenCircleRadius - rotateCircleRadius;
 21     Yreal offset = yf_rand_real(64.0f, screenCircleRadius - 10.0f);
 22     if (yf_rand_bool())
 23     {
 24         offset = -offset;
 25     }
 26 
 27     Yreal stepScale0 = yf_rand_real(0.1f, 1.0f);
 28     if (yf_rand_bool())
 29     {
 30         stepScale0 = 1.0f / stepScale0;
 31     }
 32     Yreal stepScale180 = yf_rand_real(0.1f, 1.0f);
 33     if (yf_rand_bool())
 34     {
 35         stepScale180 = 1.0f / stepScale180;
 36     }
 37 
 38     Yreal offsetScale0 = yf_rand_real(0.1f, 1.0f);
 39     if (yf_rand_bool())
 40     {
 41         offsetScale0 = 1.0f / offsetScale0;
 42     }
 43     Yreal offsetScale180 = yf_rand_real(0.1f, 1.0f);
 44     if (yf_rand_bool())
 45     {
 46         offsetScale180 = 1.0f / offsetScale180;
 47     }
 48 
 49     Yreal maxOffset = (offsetScale180 > offsetScale0) ? offsetScale180 : offsetScale0;
 50     maxOffset *= fabs(offset);
 51     Yreal posScale = screenCircleRadius / (fixCircleRadius + maxOffset);
 52     posScale *= 0.95f;
 53 
 54     Yreal scale0 = yf_rand_real(0.1f, 1.0f);
 55     if (yf_rand_bool())
 56     {
 57         scale0 = 1.0f / scale0;
 58     }
 59     Yreal scale180 = yf_rand_real(0.1f, 1.0f);
 60     if (yf_rand_bool())
 61     {
 62         scale180 = 1.0f / scale0;
 63     }
 64 
 65     Yreal step = screenCircleRadius / rotateCircleRadius;
 66     if (step > 360.0f)
 67     {
 68         return;
 69     }
 70 
 71     m_nCirclesCount = YD_MAX_CIRCLES_COUNT;
 72     m_nVerticesNum = m_nCirclesCount * 360;
 73 
 74     Vector2 vCenter;
 75     Yreal degree = 0;
 76 
 77     Vector2 vPos;
 78     Vector2 vPos0;
 79     Vector2 vPos1;
 80     Yuint index;
 81     Yreal r, a;
 82     Yreal scale;
 83 
 84     RhwVertex* vb;
 85     m_pVB->Lock(0, 0, (void**)&vb, 0);
 86 
 87     for (Yuint i = 0; i < m_nCirclesCount; i++)
 88     {
 89         for (Yuint j = 0; j < 360; j++)
 90         {
 91             vCenter.x = vScreenCenter.x + fixCircleRadius*m_listSinValues[j];
 92             vCenter.y = vScreenCenter.y + fixCircleRadius*m_listCosValues[j];
 93 
 94             r = fabsf(degree - 180.0f) / 180.0f;
 95             scale = yf_lerp(offsetScale0, offsetScale180, r);
 96 
 97             index = (Yint)degree;
 98             vPos0.x = vCenter.x - offset*scale*m_listSinValues[index];
 99             vPos0.y = vCenter.y - offset*scale*m_listCosValues[index];
100 
101             vPos1.x = vCenter.x - offset*scale*m_listSinValues[index + 1];
102             vPos1.y = vCenter.y - offset*scale*m_listCosValues[index + 1];
103 
104             a = degree - index;
105             vPos = vPos0*(1.0f - a) + vPos1*a;
106             vPos.x = posScale*(vScreenCenter.x - vPos.x) + vScreenCenter.x;
107             vPos.y = posScale*(vScreenCenter.y - vPos.y) + vScreenCenter.y;
108 
109             vb[i*360 + j].Set(vPos.x, vPos.y, 0.0f, 1.0f);
110 
111             scale = yf_lerp(stepScale0, stepScale180, r);
112             degree += step*scale;
113             degree = fmodf(degree, 360.0f);
114         }
115 
116         if (degree < YD_DEGREE_MAX_ERROR || degree > 360.0f - YD_DEGREE_MAX_ERROR)
117         {
118             m_nCirclesCount = i + 1;
119             m_nVerticesNum = m_nCirclesCount * 360;
120             vb[m_nVerticesNum] = vb[0];
121             m_nVerticesNum++;
122             break;
123         }
124     }
125 
126     m_pVB->Unlock();
127 }
View Code

屏保设置方式
XP:
将目录下的所有文件拷贝到WINDOWS系统目录下如"C:\WINDOWS\system32"
在设置屏保的对话框中,选择"LineFlowerSP"

WIN7,WIN8
将目录下的所有文件拷贝到"C:\WINDOWS\SysWOW64"或"C:\WINDOWS\SysWOW32"目录下
在设置屏保的对话框中,选择"LineFlowerSP"

 

posted on 2013-11-14 21:19  叶飞影  阅读(1023)  评论(0编辑  收藏  举报