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)
其他调用的代码都在 Transform3D.py文件中,可在我的另一篇博客《python+基本3D显示》中下载,然后将上面的字符串显示代码加进去,就可以了。
本文水平有限,内容很多词语由于知识水平问题不严谨或很离谱,但主要作为记录作用,能理解就好了,希望以后的自己和路过的大神对必要的错误提出批评与指点,对可笑的错误不要嘲笑,指出来我会改正的。
另外,转载使用请注明作者和出处,不要删除文档中的关于作者的注释。
随梦,随心,随愿,恒执念,为梦执战,执战苍天! ------------------执念执战