Imitating vibrato rotation characters clock

      Face processing algorithms have been very interested in all kinds of people on the vibrato, the individual's current level I think I can write a simple implementation, but involve complex, or too dishes. But before seen on a vibrato write Chinese characters with a web video rotation clock, I feel a lot of fun, and I felt I write no problem, just use the underlying code Pygame and rotate the cube before implementation to achieve a bit. I can not find the original video address, only a vague impression, so one thinks of. What ultimately requires a large amount of computation, and the speed is very slow. So if I have time, I will transplant as C or C ++ language and then look. Because my code is made before the change to the C language, so the change will not be difficult to go back, only trouble is not trouble.

      In addition, the contents of this paper and realized purely for fun and completely written himself, and original video presentation is achieved by other code, and I have no record of who the author is and can not be grateful. But no matter what, if there is a place of hope inform tort, will be processed immediately.

    First on the map:

        

Also can adjust the size of the (non-dynamic), as long as the modified file in a global variable that can modify the size of:

    On a rotating cube inside the pygame achieve has been achieved and to read dot-matrix display font, then just write a single character, and now look to expand to support more characters on it. Because the main use Chinese characters, but also no add support English characters. In fact, very simple principle interlinked.

    Multi-character multi nothing more than calculating coordinates corresponding to the character dot matrix, then the projection can be calculated.

    The equation is then derived relationship circle coordinates of a point on the circle and the angle, this angle can be obtained character should be displayed at what position, and then rotated character displayed at this location, enough.

    When the angle of the radius of the circle and know the value of a point, the coordinates of the relationship can be obtained as follows:

   Known center: (x0, y0) radius: R & lt angle: A0     of circular coordinates of any point on: (x1, y1), the following equation can be obtained:

          x1=x0+r*cos(a0 * 3.14/180)
          y1=y0+r*sin(a0 * 3.14/180)

     然后将字符串沿Z轴旋转(当前角度a0 减去 90度)的度数就能够将字符旋转到a0的角度,符合当前角度。选择适当的半径,就能够将字符调整到合适的位置,然后输出显示就可以了。

    中文字符串16x16点阵的显示:在Transform3D.py 文件中

 1 def Show3D16x16Char(font,ax,ay,az,x,y,Z_Size,frontcolor,backcolor,model=1.5,fontmultiple=1.0):
 2     '''**********************************************************/
 3     |**函数: Show3D16x16Font
 4     |**功能:显示3D的16x16字符,为从汉字库读取的字符数据,支持数千个汉字
 5     |        本函数需要 binascii  库的支持,不支持此库的环境无法运行本函数
 6     |**说明:font:欲显示的汉字,目前只支持一个字符的显示,只支持汉字的显示
 7     |        sx,sy,sz :角度值
 8     |        x,y: 欲显示的坐标位置
 9     |        Z_Size:距旋转轴的距离
10     |        frontcolor,backcolor:颜色,前景色和背景色
11     |        model:显示模式,只有模式为1时才填充背景色,否则只填充前景色
12     |                     
13     |**作者: wcc  执念执战
14     |**时间:2019-6-3
15     |********************************************************'''
16     length = len(font)
17     if length == 0:#字符数要大于一个
18         return 
19     if length == 1: #只支持一个字符的显示
20         text = font
21     else:
22         text = font[0]
23   
24        
25     
26     m=0
27     i=0
28     k=0
29     j=0
30     XO=0
31     YO=0
32     #fontmultiple=1.0 #放大倍数,放到外面统一调整
33     
34     
35     gMAT=[[0.0 for i in range(4)]  for n in range(4)]
36     Point0=zuobiaostruct()
37     Point1=zuobiaostruct()
38     PointDis=zuobiaostruct()
39     
40     gMAT=structure_3D()                        #//构建单位矩阵
41     gMAT=Translate3D(gMAT,-8,-8,-8);         #//平移变换矩阵
42     gMAT=Scale_3D(gMAT,fontmultiple,fontmultiple,fontmultiple);                #//比例变换矩阵
43     gMAT=Rotate_3D(gMAT,ax,ay,az);            #//旋转变换矩阵
44     
45     for m in range(length): #理论上就是将单个的字符延长为多个字符,最重要的就是坐标的确定和计算
46         
47         text=font[m]
48         gb2312 = text.encode('gb2312')
49         hex_str = binascii.b2a_hex(gb2312)
50         result = str(hex_str,encoding = 'utf-8' )  #换算出汉字对应的字符地址
51         if eval('0x' + result[:2]) <128:
52             print("请输入中文")  #目前只支持gb2312中文字符,英文字符没加。原理一样,可以取模保存起来
53             return
54         else:
55             
56             area = eval('0x' + result[:2]) - 0xA0
57             index = eval('0x' + result[2:]) - 0xA0 #换算为16进制地址
58             offset = (94 * (area - 1)+ (index - 1))*32  #得出具体地址
59             font_rect = None
60             with open("D:/Mystudy/Python/pyGame/HZK16","rb") as f: #16x16字符集的地址,从中读取出一个字符的点阵数据
61                 f.seek(offset)
62                 font_rect = f.read(32)#得到32个点阵数据
63             f.close()
64         
65       
66         #gMAT=Translate3D(gMAT,8,8,8);             #//平移变换矩阵       x:调节距离中心点的位置,相当于下面Point0.z
67         
68         
69         
70         for i in range(16):
71             for k in range(8):
72                 temp = 0x01 << k
73                 for j in range(2):
74                     data=font_rect[i*2+j]  #取出数据
75                     if data & temp == temp:
76                         
77                         Point0.x=16-(k+(1-j)*8)+m*16+m*2 #第m个字符的当前点的坐标
78                         '''
79                             每个字符16个像素,第m个字符共m*16个像素,每两个字符间的间距设为2,则m*16+m*2,前面的时实现当前点阵坐标的计算
80                         '''
81                         Point0.y=i #(i*8)+k
82                         Point0.z=Z_Size        #//此参数能够改变字符距离旋转轴中心的距离
83                         
84                         Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘
85                         PointDis=PerProject(Point1,XO,YO)       #//映射投影
86                         Gui_Point(PointDis.x+x,PointDis.y+y,frontcolor)
87                     else:
88                         if model ==1: #模式为1 时才会绘制底色
89                             Point0.x=16-(k+(1-j)*8)+m*16+m*2
90                             Point0.y=i #(i*8)+k
91                             Point0.z=Z_Size        #//此参数能够改变字符距离旋转轴中心的距离
92                             
93                             Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘
94                             PointDis=PerProject(Point1,XO,YO)       #//映射投影
95                             Gui_Point(PointDis.x+x,PointDis.y+y,backcolor)
96      

 

 

    下面是实现旋转时钟的代码:

  1 # -*- coding: utf-8 -*-
  2 """
  3 Created on Sat Jun 29 15:22:12 2019
  4 
  5 @author: Administrator
  6 """
  7 
  8 from Transform3D import *
  9 
 10 
 11 import pygame 
 12 import time 
 13 import math
 14 
 15 fontmultiple=0.8   #字符倍数比例函数,修改次数据可以实现整体的放大和缩小,建议此数值在0.8-1.3 之间,看起来比较合适
 16 
 17 SCREEN_X_MAX = int(800*fontmultiple) #屏幕的宽和高
 18 SCREEN_Y_MAX = int(800*fontmultiple)
 19 
 20 BLACK=(0,0,0)
 21 WHITE=(255,255,255)
 22 RED=(255,0,0)
 23 GREEN=(0,255,0)
 24 BLUE=(0,0,255)
 25 
 26 ForeColor = RED #前景色和背景色
 27 BackColor = BLACK    
 28 
 29 
 30 pygame.init()
 31 screen = pygame.display.set_mode((SCREEN_X_MAX,SCREEN_Y_MAX))
 32 
 33 
 34 #myfont=pygame.font.Font(None,1)
 35 #textImage=myfont.render("test",True,WHITE)
 36 
 37 Week_zw=("","","","","","","") #周的中文
 38 Day_zw=("","","","","","","","","","","") #可用于所有需要0-10的中文的地方
 39 Mouth_day=[31,28,31,30,31,30,31,31,30,31,30,31] #月份时长表
 40 
 41 
 42 
 43 '''
 44 圆: (x-a)^2+(y-b)^2=r^2
 45     a,b:圆心坐标
 46     r:半径
 47     
 48     圆心:(x0,y0)
 49     半径:r
 50     角度:a0
 51     圆上任意一点:(x1,y1)
 52     x1=x0+r*cos(a0 * 3.14/180)
 53     y1=y0+r*sin(a0 * 3.14/180)
 54 '''
 55 def Show_Year(x0,y0,r,angel):
 56     '''
 57     显示年
 58     '''
 59     
 60     timenow=time.localtime(time.time())
 61     yearstr=Day_zw[(int)(timenow[0]/1000)]+Day_zw[int((timenow[0]%1000)/100)]+Day_zw[int((timenow[0]%100)/10)]+Day_zw[int((timenow[0]%10))]+""
 62     Show3D16x16Char(yearstr,0,0,angel-90,x0,y0,1,ForeColor,BackColor,0,fontmultiple)
 63 def Show_Week(x0,y0,r,agl):
 64     '''
 65     显示周
 66     '''
 67     timenow=time.localtime(time.time()) #获取时间
 68     for i in range(7):
 69         angel=360/7
 70        
 71         if i < timenow[6]:
 72             angel=agl-angel*(timenow[6]-i)
 73             ForeColor=RED
 74         elif i >timenow[6]:
 75             angel=agl+angel*(i-timenow[6])
 76             ForeColor=RED
 77         else :
 78             angel=agl  #当前周设为90度,即在水平方向上
 79             ForeColor=WHITE
 80             
 81         x1=x0 + r * math.sin(angel * 3.14/180) #由角度计算出当前应在的坐标点
 82         y1=y0 + r * math.cos(angel * 3.14/180)
 83         Show3D16x16Char(""+Week_zw[i],0,0,angel-90,(int)(x1),(int)(y1),1,ForeColor,BackColor,0,fontmultiple)#输出旋转后的字符串
 84 
 85 def Show_Month(x0,y0,r,agl):
 86     '''
 87     显示月份
 88     '''
 89     timenow=time.localtime(time.time())#获取时间
 90     for i in range(1,13): #一年12个月
 91         angel=360/12
 92        
 93         if i < timenow[1]:
 94             angel=agl-angel*(timenow[1]-i) #其他月份相应得到角度推算
 95             ForeColor=RED
 96         elif i >timenow[1]:
 97             angel=agl+angel*(i-timenow[1])
 98             ForeColor=RED
 99         else :
100             angel=agl  #当前月份设为90度,即在水平方向上
101             ForeColor=WHITE
102         x1=x0 + r * math.sin(angel * 3.14/180) #由角度计算出当前应在的坐标点
103         y1=y0 + r * math.cos(angel * 3.14/180)
104         if i>10:
105             monthstr=Day_zw[10]+Day_zw[i%10]+""  #得出要显示的字符串
106         else:
107             monthstr = Day_zw[i]+""
108         Show3D16x16Char(monthstr,0,0,angel-90,(int)(x1),(int)(y1),1,ForeColor,BackColor,0,fontmultiple)#显示字符串
109 
110 def Show_Day(x0,y0,r,agl):
111     '''
112     显示日期
113     '''
114     timenow=time.localtime(time.time()) #获取时间
115     if (timenow[0]%4==0 and timenow[0]%100 !=0) or (timenow[0]%400 == 0):
116         Mouth_day[1]=29 #闰年,补全二月的时长表
117     else:
118         Mouth_day[1]=28
119         
120         #Mouth_day 为月份的时长表
121     for i in range(1,Mouth_day[timenow[1]-1]+1):
122         angel=360/Mouth_day[timenow[1]-1]
123         
124         if i < timenow[2]:
125             angel=agl-angel*(timenow[2]-i)#其他日期相应得到角度推算
126             ForeColor=RED
127         elif i >timenow[2]:
128             angel=agl+angel*(i-timenow[2])
129             ForeColor=RED
130         else :
131             angel=agl  #当前日期设为90度,即在水平方向上
132             ForeColor=WHITE
133         x1=x0 + r * math.sin(angel * 3.14/180)#由角度计算出当前应在的坐标点
134         y1=y0 + r * math.cos(angel * 3.14/180)
135         if i>20:
136             if i%10 !=0:
137                 daystr= Day_zw[(int)(i/10) ]+ Day_zw[10] +Day_zw[i%10]+""#得出要显示的字符串
138             else:
139                 daystr= Day_zw[(int)(i/10) ]+ Day_zw[10]+""
140         elif i>10:
141             daystr= Day_zw[10]+Day_zw[i%10]+""
142         else:
143             daystr=Day_zw[i]+""
144         Show3D16x16Char(daystr,0,0,angel-90,(int)(x1),(int)(y1),1,ForeColor,BackColor,0,fontmultiple)#显示字符串
145         
146 
147 def Show_Hour(x0,y0,r,agl):
148     '''
149     显示时
150     '''
151     
152     timenow=time.localtime(time.time())#获取时间
153 
154     for i in range(0,24):
155         angel=360/24
156         
157         if i < timenow[3]:
158             angel=agl-angel*(timenow[3]-i)#其他时间相应得到角度推算
159             ForeColor=RED
160         elif i >timenow[3]:
161             angel=agl+angel*(i-timenow[3])
162             ForeColor=RED
163         else :
164             angel=agl  #当前时间设为90度,即在水平方向上
165             ForeColor=WHITE
166         x1=x0 + r * math.sin(angel * 3.14/180)
167         y1=y0 + r * math.cos(angel * 3.14/180)
168         if i>20:
169             if i%10 !=0:
170                 daystr= Day_zw[(int)(i/10) ]+ Day_zw[10] +Day_zw[i%10]+""  #得到要显示的字符串
171             else:
172                 daystr= Day_zw[(int)(i/10) ]+ Day_zw[10]+""
173         elif i>10:
174             daystr= Day_zw[10]+Day_zw[i%10]+""
175         else:
176             daystr=Day_zw[i]+""
177         Show3D16x16Char(daystr,0,0,angel-90,(int)(x1),(int)(y1),1,ForeColor,BackColor,0,fontmultiple) #显示角度计算后的字符串
178         
179 def Show_Min(x0,y0,r,agl):
180     '''
181     显示分
182     '''
183     
184     timenow=time.localtime(time.time())
185 
186     for i in range(0,60):
187         angel = 360/60
188         
189         if i < timenow[4]:
190             angel=agl-angel*(timenow[4]-i)-(360/60/60 * timenow[5] ) #将秒数也代入角度计算中就可以得到更精确的角度偏移,而且每秒钟都会移动,好看
191             ForeColor=RED
192         elif i > timenow[4]:
193             angel = agl + angel * (i-timenow[4]) - (360/60/60 * timenow[5] )
194             ForeColor = RED
195         else :
196             angel = agl - (360/60/60 * timenow[5] )  #当前日期设为90度-秒钟的角度,实现动态显示
197             ForeColor = WHITE
198         x1 = x0 + r * math.sin(angel * 3.14/180) #由角度计算出当前应在的坐标点
199         y1 = y0 + r * math.cos(angel * 3.14/180)
200         if i>=20:
201             if i%10 !=0:
202                 daystr = Day_zw[(int)(i/10) ]+ Day_zw[10] +Day_zw[i%10]+"" #得到要显示的字符串
203             else:
204                 daystr = Day_zw[(int)(i/10) ]+ Day_zw[10]+""
205         elif i>10:
206             daystr = Day_zw[10]+Day_zw[i%10]+""
207         else:
208             daystr = Day_zw[i]+""
209         Show3D16x16Char(daystr,0,0,angel-90,(int)(x1),(int)(y1),1,ForeColor,BackColor,0,fontmultiple)#显示角度计算后的字符串
210 
211 
212 i=0
213 while True:
214     for event in pygame.event.get():
215         if event.type in (QUIT,KEYDOWN):
216             pygame.quit()
217             sys.exit()
218             
219     i+=1  #开始的动画,调整大小可以调整速度,因为没优化,所以显示速度很慢,数据大一些动画能尽早结束
220     if i>90:
221         i=90
222         
223     Show_Year(SCREEN_X_MAX/2-40*fontmultiple,SCREEN_Y_MAX/2,32,90) #显示年
224     Show_Week(SCREEN_X_MAX/2,SCREEN_Y_MAX/2,65*fontmultiple,180-i) #显示周
225     Show_Month(SCREEN_X_MAX/2,SCREEN_Y_MAX/2,110*fontmultiple,i)    #显示月份
226     Show_Day(SCREEN_X_MAX/2,SCREEN_Y_MAX/2,170*fontmultiple,180-i)  #显示日期
227     Show_Hour(SCREEN_X_MAX/2,SCREEN_Y_MAX/2,245*fontmultiple,i)     #显示时
228     Show_Min(SCREEN_X_MAX/2,SCREEN_Y_MAX/2,325*fontmultiple,180-i)  #显示分
229     
230     pygame.draw.circle(screen,ForeColor,((int)(SCREEN_X_MAX/2),(int)(SCREEN_Y_MAX/2)),int(55*fontmultiple),1) #显示几个圆
231     pygame.draw.circle(screen,ForeColor,((int)(SCREEN_X_MAX/2),(int)(SCREEN_Y_MAX/2)),int(100*fontmultiple),1)
232     pygame.draw.circle(screen,ForeColor,((int)(SCREEN_X_MAX/2),(int)(SCREEN_Y_MAX/2)),int(160*fontmultiple),1)
233     pygame.draw.circle(screen,ForeColor,((int)(SCREEN_X_MAX/2),(int)(SCREEN_Y_MAX/2)),int(235*fontmultiple),1)
234     pygame.draw.circle(screen,ForeColor,((int)(SCREEN_X_MAX/2),(int)(SCREEN_Y_MAX/2)),int(315*fontmultiple),1)
235     
236     pygame.display.update()
237     screen.fill(0)  #屏幕清零
238     #time.sleep(30/1000)
View Code

   其他调用的代码都在 Transform3D.py文件中,可在我的另一篇博客《python+基本3D显示》中下载,然后将上面的字符串显示代码加进去,就可以了。

 

 

    

本文水平有限,内容很多词语由于知识水平问题不严谨或很离谱,但主要作为记录作用,能理解就好了,希望以后的自己和路过的大神对必要的错误提出批评与指点,对可笑的错误不要嘲笑,指出来我会改正的。 

 另外,转载使用请注明作者和出处,不要删除文档中的关于作者的注释。                                                                                                

                                                                                             随梦,随心,随愿,恒执念,为梦执战,执战苍天!    ------------------执念执战

 

      

Guess you like

Origin www.cnblogs.com/zhinianzhizhan/p/11129717.html