3D屏保: 线圈

LineFlower3DSP

一个3D屏保程序,算法的原理类似于圆内轮旋线的生成.

下载地址:

https://files.cnblogs.com/WhyEngine/LineFlower3D_sp.zip

切图:

 

双击"LineFlower3DSP.scr"可运行程序

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

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

程序启动后,点击鼠标或按下键盘任意按键会自动退出
使用鼠标滚轮滚动进行切换

 

代码也贴出来.其实这代码写得麻烦了,如果对数学了解得深一些的话,可以使用更简单的算法生成.

 1 /****************************************************************
 2 
 3   File name   :  LineFlower.h
 4   Author      :  
 5   Version     :  1.0a
 6   Create Date :  2014/06/09
 7   Description :  
 8 
 9 *****************************************************************/
10 
11 // --------------------------------------------------------------------------------------
12 
13 #ifndef _LineFlower_H_
14 #define _LineFlower_H_
15 
16 // --------------------------------------------------------------------------------------
17 
18 #define MAX_CIRCLES_COUNT       200
19 
20 struct LfVertex
21 {
22     float x;
23     float y;
24     float z;
25 };
26 
27 // --------------------------------------------------------------------------------------
28 
29 class CLineFlower
30 {
31 public:
32     CLineFlower();
33 
34     void Reset();
35 
36     void AutoSize(float width, float height);
37 
38     const LfVertex& GetVertex(unsigned int index)
39     {
40         return m_listVertices[index % m_nVerticesNum];
41     }
42 
43 public:
44     float m_listSinValues[361];
45     float m_listCosValues[361];
46 
47     float m_fOutCircleRadius;
48     float m_fInCircleRadius;
49     float m_fScreenCircleRadius;
50     float m_fOffset;
51     float m_fStepScale0;
52     float m_fStepScale180;
53     float m_fOffsetScale0;
54     float m_fOffsetScale180;
55 
56     unsigned int m_zParam;
57 
58     float m_fHalfExtendXY;
59     float m_fHalfExtendZ;
60     float m_fHalfExtendXYZ;
61 
62     LfVertex m_listVertices[MAX_CIRCLES_COUNT * 360 + 1];
63 
64     unsigned int m_nVerticesNum;
65     unsigned int m_nCirclesCount;
66 
67     bool m_enableZ;
68 };
69 
70 // --------------------------------------------------------------------------------------
71 
72 #endif
  1 /****************************************************************
  2 
  3   File name   :  LineFlower.cpp
  4   Author      :  
  5   Version     :  1.0a
  6   Create Date :  2014/06/09
  7   Description :  
  8 
  9 *****************************************************************/
 10 
 11 // --------------------------------------------------------------------------------------
 12 
 13 #include "LineFlower.h"
 14 #include <float.h>
 15 #include <math.h>
 16 #include <stdlib.h>
 17 #include <string.h>
 18 
 19 // --------------------------------------------------------------------------------------
 20 
 21 #define DEGREE_MAX_ERROR    3.0f
 22 
 23 // --------------------------------------------------------------------------------------
 24 
 25 inline int          yf_rand(int a)
 26 {
 27     return (int)(::rand() % a);
 28 }
 29 
 30 inline int          yf_rand(int a, int b)
 31 {
 32     return a + (int)(::rand() % (b-a));
 33 }
 34 
 35 inline float        yf_rand_real(float a)
 36 {
 37     return a * (float)(::rand() / ((float)RAND_MAX + 1));
 38 }
 39 
 40 inline float        yf_rand_real(float a, float b)
 41 {
 42     const float r = (float)(::rand() / ((float)RAND_MAX + 1));
 43     return r*(b-a) + a;
 44 }
 45 
 46 inline bool         yf_rand_bool()
 47 {
 48     return (::rand() % 2 == 1);
 49 }
 50 
 51 inline float        yf_lerp(float a, float b, float r)
 52 {
 53     return a + (b - a) * r;
 54 }
 55 
 56 // --------------------------------------------------------------------------------------
 57 
 58 CLineFlower::CLineFlower()
 59 {
 60     const float d2r = 0.01745329251994f;
 61     float r;
 62     for (unsigned int i = 0; i < 361; i++)
 63     {
 64         r = i * d2r;
 65         m_listSinValues[i] = sinf(r);
 66         m_listCosValues[i] = cosf(r);
 67     }
 68 
 69     m_nVerticesNum = 0;
 70     m_nCirclesCount = 0;
 71 
 72     memset(m_listVertices, 0, sizeof(m_listVertices));
 73 
 74     m_enableZ = true;
 75 } 
 76 
 77 void CLineFlower::Reset()
 78 {
 79     m_fOutCircleRadius = yf_rand_real(8.0f, 64.0f);
 80     m_fInCircleRadius = yf_rand_real(4.0f, 64.0f);
 81     m_fOffset = yf_rand_real(2.0f, m_fInCircleRadius);
 82     if (yf_rand_bool())
 83     {
 84         m_fOffset = -m_fOffset;
 85     }
 86 
 87     m_fStepScale0 = yf_rand_real(0.1f, 1.0f);
 88     if (yf_rand_bool())
 89     {
 90         m_fStepScale0 = 1.0f / m_fStepScale0;
 91     }
 92     m_fStepScale180 = yf_rand_real(0.1f, 1.0f);
 93     if (yf_rand_bool())
 94     {
 95         m_fStepScale180 = 1.0f / m_fStepScale180;
 96     }
 97 
 98     m_fOffsetScale0 = yf_rand_real(0.1f, 1.0f);
 99     if (yf_rand_bool())
100     {
101         m_fOffsetScale0 = 1.0f / m_fOffsetScale0;
102     }
103     m_fOffsetScale180 = yf_rand_real(0.1f, 1.0f);
104     if (yf_rand_bool())
105     {
106         m_fOffsetScale180 = 1.0f / m_fOffsetScale180;
107     }
108 
109     m_fScreenCircleRadius = m_fOutCircleRadius + m_fInCircleRadius;
110     float step = m_fScreenCircleRadius / m_fInCircleRadius;
111     if (step > 360.0f)
112     {
113         return;
114     }
115 
116     float maxOffset = (m_fOffsetScale180 > m_fOffsetScale0) ? m_fOffsetScale180 : m_fOffsetScale0;
117     maxOffset *= fabs(m_fOffset);
118     m_fHalfExtendXY = m_fOutCircleRadius + maxOffset;
119     if (m_enableZ)
120     {
121         m_fHalfExtendZ = yf_rand_real(0.0f, 64.0f);
122         m_fHalfExtendXYZ = sqrtf(m_fHalfExtendXY*m_fHalfExtendXY + m_fHalfExtendZ*m_fHalfExtendZ);
123     }
124     else
125     {
126         m_fHalfExtendZ = 0.0f;
127         m_fHalfExtendXYZ = m_fHalfExtendXY;
128     }
129 
130     m_zParam = yf_rand(1, 12);
131 
132     m_nCirclesCount = MAX_CIRCLES_COUNT;
133     m_nVerticesNum = m_nCirclesCount * 360;
134 
135     LfVertex vCenter;
136     float degree = 0;
137 
138     LfVertex vPos0;
139     LfVertex vPos1;
140     unsigned int index;
141     float r, a;
142     float scale;
143 
144     for (unsigned int i = 0; i < m_nCirclesCount; i++)
145     {
146         for (unsigned int j = 0; j < 360; j++)
147         {
148             vCenter.x = m_fOutCircleRadius*m_listSinValues[j];
149             vCenter.y = m_fOutCircleRadius*m_listCosValues[j];
150             if (m_enableZ)
151             {
152                 vCenter.z = m_fHalfExtendZ*m_listSinValues[j*m_zParam % 360];
153             }
154             else
155             {
156                 vCenter.z = 0.0f;
157             }
158 
159             r = fabsf(degree - 180.0f) / 180.0f;
160             scale = yf_lerp(m_fOffsetScale0, m_fOffsetScale180, r);
161 
162             index = (unsigned int)degree;
163             vPos0.x = vCenter.x - m_fOffset*scale*m_listSinValues[index];
164             vPos0.y = vCenter.y - m_fOffset*scale*m_listCosValues[index];
165 
166             vPos1.x = vCenter.x - m_fOffset*scale*m_listSinValues[index + 1];
167             vPos1.y = vCenter.y - m_fOffset*scale*m_listCosValues[index + 1];
168 
169             a = degree - index;
170             LfVertex& v = m_listVertices[i*360 + j];
171             v.x = vPos0.x*(1.0f - a) + vPos1.x*a;
172             v.y = vPos0.y*(1.0f - a) + vPos1.y*a;
173             if (m_enableZ)
174             {
175                 float dis = sqrtf(v.x*v.x + v.y*v.y);
176                 v.z = vCenter.z * (1.0f - dis / m_fScreenCircleRadius);
177             }
178             else
179             {
180                 v.z = 0.0f;
181             }
182 
183             scale = yf_lerp(m_fStepScale0, m_fStepScale180, r);
184             degree += step*scale;
185             degree = fmodf(degree, 360.0f);
186         }
187 
188         if (degree < DEGREE_MAX_ERROR || degree > 360.0f - DEGREE_MAX_ERROR)
189         {
190             m_nCirclesCount = i + 1;
191             m_nVerticesNum = m_nCirclesCount * 360;
192             m_listVertices[m_nVerticesNum] = m_listVertices[0];
193             m_nVerticesNum++;
194             break;
195         }
196     }
197 }
198 
199 void CLineFlower::AutoSize(float width, float height)
200 {
201     float fMinX = FLT_MAX;
202     float fMaxX = -FLT_MAX;
203     float fMinY = FLT_MAX;
204     float fMaxY = -FLT_MAX;
205 
206     for (unsigned int i = 0; i < m_nVerticesNum; i++)
207     {
208         if (fMinX > m_listVertices[i].x)
209         {
210             fMinX = m_listVertices[i].x;
211         }
212         if (fMaxX < m_listVertices[i].x)
213         {
214             fMaxX = m_listVertices[i].x;
215         }
216 
217         if (fMinY > m_listVertices[i].y)
218         {
219             fMinY = m_listVertices[i].y;
220         }
221         if (fMaxY < m_listVertices[i].y)
222         {
223             fMaxY = m_listVertices[i].y;
224         }
225     }
226 
227     float ox = fMaxX - fMinX;
228     float oy = fMaxY - fMinY;
229 
230     float halfWidth = width*0.5f;
231     float halfHeight = height*0.5f;
232 
233     for (unsigned int i = 0; i < m_nVerticesNum; i++)
234     {
235         m_listVertices[i].x = -halfWidth + (m_listVertices[i].x - fMinX)*width/ox;
236         m_listVertices[i].y = -halfHeight + (m_listVertices[i].y - fMinY)*height/ox;
237     }
238 }

 

 

 

 

 

posted on 2014-07-03 12:24  叶飞影  阅读(1939)  评论(5编辑  收藏  举报