python 3d库_python+基本3D显示

1 from math import *

2 importpygame3 from pygame.locals import *

4 importtime5 importsys6 import binascii #任意中文字符时使用到此库

7

8 '''

9 * 文档: Transform3D.py10 * 作者: 执念执战11 * QQ:57231425112 * 微信:zhinianzhizhan13 * 原名:王成程14 * 时间:2019-615 * 随梦,随心,随愿,恒执念,为梦执战,执战苍天!16 *17 *18 *19 * 说明: 本文档是由之前的可以在单片机上实现3D显示的程序修改而来20 * 直接运行时需要math、time、sys、pygame、binascii 等库的支持21 * 3D算法从底层一步一步实现22 * 所有的算法都是使用基本的math库算法实现,没有使用高级的numpy矩阵算法23 * 所以理论上来说,只要移植好Gui_Point()函数和GUI_Line()函数,去掉需要pygame库支持的部分,24 * 就可以移植到任意Python环境中(包括可以在单片机上运行的MicroPython环境中),只不过速度有差距25 *26 * 转载或使用情注明出处27 '''

28

29

30

31 FOCAL_DISTANCE = 512 #透视模型

32 '''基于透视投影的基本模型'''

33

34

35

36

37 SCREEN_X_MAX = 800 #屏幕的宽和高

38 SCREEN_Y_MAX = 600

39

40 BLACK=(0,0,0)41 WHITE=(255,255,255)42 RED=(255,0,0)43 GREEN=(0,255,0)44 BLUE=(0,0,255)45

46 ForeColor = RED #前景色和背景色

47 BackColor =BLACK48 #Screen=[[0 for i in range(SCREEN_X_MAX)] for j in range(SCREEN_Y_MAX)] #屏幕缓存

49

50 screen =pygame.display.set_mode((SCREEN_X_MAX,SCREEN_Y_MAX))51

52 defGui_Point(x,y,color):53 '''|**********************************************************54 |**函数:Gui_Point55 |**功能:画点函数56 |**说明:x,y:坐标点57 | color:颜色58 | 若想支持其他Python环境,需要完成本函数的移植59 |60 |61 |**作者: 执念执战62 |**时间:2019-6-363 |*********************************************************'''

64 #Screen[(int)(y)][(int)(x)]=color

65 pygame.draw.line(screen,color,(x,y),(x+1,y),2)66 defGUI_Line(xstart,ystart,xend,yend,color):67 '''|**********************************************************68 |**GUI_Line69 |**功能:画线函数70 |**说明:xstart,ystart:起始坐标点71 | xend,yend:结束坐标点72 | color:颜色73 | 若想支持其他Python环境,需要完成本函数的移植74 |75 |76 |**作者: 执念执战77 |**时间:2019-6-378 |*********************************************************'''

79 pygame.draw.line(screen,color,(xstart,ystart),(xend,yend),2)80

81

82

83 classzuobiaostruct:84 '''坐标结构体'''

85 def __init__(self):86 self.x=087 self.y=088 self.z=089

90 Cube_Size = 16.0 #立方体基本边长

91 Cube=[zuobiaostruct() for i in range(8)]92

93 '''

94 相当于正方形的顶点坐标。95 修改长度可以改为长方形,或是修改边长等。96 当然,也可修改顶点坐标为任意数据,然后对顶点坐标进行3D运算,最后按照顺序在需要的顶点之间画线,就能生成其他3D图形97

98 '''

99 Cube[0].x=0.0

100 Cube[0].y=0.0

101 Cube[0].z=0.0

102

103 Cube[1].x=Cube_Size104 Cube[1].y=0.0

105 Cube[1].z=0.0

106

107 Cube[2].x=0.0

108 Cube[2].y=Cube_Size109 Cube[2].z=0.0

110

111 Cube[3].x=Cube_Size112 Cube[3].y=Cube_Size113 Cube[3].z=0.0

114

115 Cube[4].x=0.0

116 Cube[4].y=0.0

117 Cube[4].z=Cube_Size118

119 Cube[5].x=Cube_Size120 Cube[5].y=0.0

121 Cube[5].z=Cube_Size122

123 Cube[6].x=0.0

124 Cube[6].y=Cube_Size125 Cube[6].z=Cube_Size126

127 Cube[7].x=Cube_Size128 Cube[7].y=Cube_Size129 Cube[7].z=Cube_Size130 '''Cube=[[0,0,0],131 [16,0,0],132 [0,16,0],133 [16,16,0],134

135 [0,0,16],136 [16,0,16],137 [0,16,16],138 [16,16,16]]139 '''

140

141

142

143

144

145

146 '''

147 -**************************************************************-148 3D坐标运算部分149 -**************************************************************-150 '''

151

152

153

154

155 defMATRIX_copy(sourceMAT):156 '''|**********************************************************157 |**函数:MATRIX_copy158 |**功能:矩阵拷贝159 |**说明: sourceMAT[4][4](源矩阵,source matrix),160 | targetMAT[4][4] (目标矩阵 target matrix)161 | 边学边写162 |**作者: 执念执战163 |**时间:2015-11-29,21:52164 |*********************************************************'''

165 targetMAT=[[0.0 for i in range(4)] for n in range(4)]166 for a in range(4):167 for b in range(4):168 targetMAT[a][b]=sourceMAT[a][b]169 returntargetMAT170

171 ''

172

173 defMATRIX_multiply(MAT1,MAT2):174 '''|*******************************************************175 |**函数:MATRIX_multiply176 |**功能:矩阵相乘177 |**说明: MAT1[4][4](矩阵1),MAT2[4][4](矩阵2),178 | newMAT[4][4] (结果矩阵 )179 | 边学边写180 |**作者: 执念执战181 |**时间:2015-11-29182 |**********************************************************'''

183 newMAT=[[0.0 for i in range(4)] for n in range(4)]184 for a in range(4):185 for b in range(4):186 newMAT[a][b]=MAT1[a][0]*MAT2[0][b]+MAT1[a][1]*MAT2[1][b]+MAT1[a][2]*MAT2[2][b]+MAT1[a][3]*MAT2[3][b]187 returnnewMAT188

189

190

191 defvector_matrix_MULTIPLY(Source,MAT):192 '''**********************************************************193 |**函数: vector_matrix_MULTIPLY194 |**功能:矢量与矩阵相乘195 |**说明: Source(源矢量坐标) MAT[][](变换坐标)196 | 边学边写197 |**作者: 执念执战198 |**时间:2015-11-29199 |***********************************************************'''

200 Result=zuobiaostruct()201 Result.x=Source.x*MAT[0][0]+Source.y*MAT[1][0]+Source.z*MAT[2][0]+MAT[3][0]202 Result.y=Source.x*MAT[0][1]+Source.y*MAT[1][1]+Source.z*MAT[2][1]+MAT[3][1]203 Result.z=Source.x*MAT[0][2]+Source.y*MAT[1][2]+Source.z*MAT[2][2]+MAT[3][2]204 returnResult205

206

207

208 defstructure_3D():209 '''**********************************************************210 |**函数: structure_3D211 |**功能:构造单位矩阵212 |**说明: 将一个数组构造成单位矩阵(对角线上全为1,其他为0)213 | 边学边写214 |**作者: 执念执战215 |**时间:2015-11-29216 |*********************************************************'''

217 MAT=[[0.0 for i in range(4)] for i in range(4)]218 MAT[0][0]=1.0

219 MAT[0][1]=0.0

220 MAT[0][2]=0.0

221 MAT[0][3]=0.0 #// 1 0 0 0

222

223 MAT[1][0]=0.0

224 MAT[1][1]=1.0

225 MAT[1][2]=0.0

226 MAT[1][3]=0.0 #// 0 1 0 0

227

228 MAT[2][0]=0.0

229 MAT[2][1]=0.0

230 MAT[2][2]=1.0

231 MAT[2][3]=0.0

232 #// 0 0 1 0

233 MAT[3][0]=0.0

234 MAT[3][1]=0.0

235 MAT[3][2]=0.0

236 MAT[3][3]=1.0

237 #// 0 0 0 1

238

239 returnMAT240

241

242

243 defTranslate3D(MAT,tx, ty, tz):244 '''********************************************************245 |**函数: Translate3D246 |**功能:平移变换矩阵247 |**说明: 1:tx,ty,tz 为平移参数248 | 2:当为边长的一半的倒数时,图像绕着自己旋转,即原点在中心249 |250 | 边学边写251 |**作者: 执念执战252 |**时间:2015-11-29253 |**********************************************************'''

254 tMAT=[[0.0 for i in range(4)] for i in range(4)]255 tMAT[0][0]=1

256 tMAT[0][1]=0257 tMAT[0][2]=0258 tMAT[0][3]=0 #// 1 0 0 tx

259

260 tMAT[1][0]=0261 tMAT[1][1]=1

262 tMAT[1][2]=0263 tMAT[1][3]=0 #// 0 1 0 ty

264

265 tMAT[2][0]=0266 tMAT[2][1]=0267 tMAT[2][2]=1

268 tMAT[2][3]=0 #// 0 0 1 tz

269

270 tMAT[3][0]=tx271 tMAT[3][1]=ty272 tMAT[3][2]=tz273 tMAT[3][3]=1; #// 0 0 0 1

274

275 return MATRIX_multiply(MAT,tMAT)#//相乘

276

277

278

279 defScale_3D( MAT, sx, sy, sz):280 '''*******************************************************281 |**函数: Scale_3D282 |**功能:比例(scale)变换矩阵283 |**说明: 1:相对于原点上的比例变换284 | 2:sx,sy,sz 是对应轴上的缩放量285 | 3:矩阵根据三个比例进行比例变换286 | 边学边写287 |**作者: 执念执战288 |**时间:2015-11-30,7:45289 |*********************************************************'''

290 tMAT=[[0.0 for i in range(4)] for i in range(4)]291 tMAT[0][0]=sx292 tMAT[0][1]=0293 tMAT[0][2]=0294 tMAT[0][3]=0 #// sx0 0 0

295 tMAT[1][0]=0296 tMAT[1][1]=sy297 tMAT[1][2]=0298 tMAT[1][3]=0 #// 0 sy0 0

299 tMAT[2][0]=0300 tMAT[2][1]=0301 tMAT[2][2]=sz302 tMAT[2][3]=0 #// 0 0 sz0

303 tMAT[3][0]=0304 tMAT[3][1]=0305 tMAT[3][2]=0306 tMAT[3][3]=1 #// 0 0 0 1

307 return MATRIX_multiply(MAT,tMAT) #//相乘

308

309

310

311

312

313

314 defRotate_3D( MAT, ax, ay, az):315 '''**********************************************************/316 |**函数: Rotate_3D317 |**功能:旋转变换矩阵318 |**说明: 1:绕z轴旋转az度角319 | 2:az为旋转的角度量,赋正值为顺时针转320 | 3:矩阵MAT根据AZ度角进行旋转变换321 | 边学边写322 |**作者: 执念执战323 |**时间:2015-11-30,7:45324 |**********************************************************'''

325 MAT1=[[0.0 for i in range(4)] for i in range(4)]326 MAT2=[[0.0 for i in range(4)] for i in range(4)]327 MATx=[[0.0 for i in range(4)] for i in range(4)]328 MATy=[[0.0 for i in range(4)] for i in range(4)]329 MATz=[[0.0 for i in range(4)] for i in range(4)]330

331 ax=(3.1415926*ax)/180.0 #//角度转换为弧度量

332 ay=(3.1415926*ay)/180.0

333 az=(3.1415926*az)/180.0

334 '''/*****************************绕x轴旋转********************************************/'''

335

336 MATx[0][0]=1

337 MATx[0][1]=0338 MATx[0][2]=0339 MATx[0][3]=0 #//1 0 0 0

340 MATx[1][0]=0341 MATx[1][1]=cos(ax)342 MATx[1][2]=-sin(ax)343 MATx[1][3]=0 #//0 cos(ax) -sin(ax) 0

344 MATx[2][0]=0345 MATx[2][1]=sin(ax)346 MATx[2][2]=cos(ax)347 MATx[2][3]=0 #//0 sin(ax) cos(ax) 0

348 MATx[3][0]=0349 MATx[3][1]=0350 MATx[3][2]=0351 MATx[3][3]=1 #//0 0 0 1

352

353 '''/*****************************绕y轴旋转********************************************/'''

354 MATy[0][0]=cos(ay)355 MATy[0][1]=0356 MATy[0][2]=sin(ay)357 MATy[0][3]=0 #//cos(ay) 0 sin(ay) 0

358 MATy[1][0]=0359 MATy[1][1]=1

360 MATy[1][2]=0361 MATy[1][3]=0 #// 0 1 0 0

362 MATy[2][0]=-sin(ay)363 MATy[2][1]=0364 MATy[2][2]=cos(ay)365 MATy[2][3]=0 #// -sin(ay) 0 cos(ay) 0

366 MATy[3][0]=0367 MATy[3][1]=0368 MATy[3][2]=0369 MATy[3][3]=1 #// 0 0 0 1

370

371

372 '''/*****************************绕z轴旋转********************************************/'''

373 MATz[0][0]=cos(az)374 MATz[0][1]=-sin(az)375 MATz[0][2]=0376 MATz[0][3]=0 #//cos(az) -sin(az) 0 0

377 MATz[1][0]=sin(az)378 MATz[1][1]=cos(az)379 MATz[1][2]=0380 MATz[1][3]=0 #// sin(az) cos(az) 0 0

381 MATz[2][0]=0382 MATz[2][1]=0383 MATz[2][2]=1

384 MATz[2][3]=0 #// 0 0 1 0

385 MATz[3][0]=0386 MATz[3][1]=0387 MATz[3][2]=0388 MATz[3][3]=1 #// 0 0 0 1

389

390 MAT1=MATRIX_multiply(MAT,MATx)391 MAT2=MATRIX_multiply(MAT1,MATy)392 returnMATRIX_multiply(MAT2,MATz)393 #return MAT

394

395 '''

396 /********************************************************************************/397 /*------------------------------------------------------------------------------*/398 /* 投影算法 三维转二维的相关函数 */399 /*------------------------------------------------------------------------------*/400 /********************************************************************************/401 '''

402

403

404

405

406

407 defOrtProject(Space):408 '''********************************************************409 |**函数: OrtProject410 |**功能:透视投影(Perspective projection)411 |**说明:简单透视412

413 | 边学边写414 |**作者: 执念执战415 |**时间:2015-11-30416 |*********************************************************'''

417 Screen=zuobiaostruct()418 Screen.x=(int)(Space.x)419 Screen.y=(int)(Space.y)420

421 returnScreen;422

423

424

425 defPerProject( Space, XO, YO):426 '''**********************************************************/427 |**函数: PerProject428 |**功能:透视投影(Perspective projection)429 |**说明:XO,YO为投影后的图形中心的屏幕坐标430

431 | 边学边写432 |**作者: 执念执战433 |**时间:2015-11-30434 |********************************************************'''

435

436 Screen=zuobiaostruct()437 if (Space.z==0):438 Space.z=0.01 #//被除数不能为零

439 Screen.x=(int)(FOCAL_DISTANCE*Space.x /(Space.z+FOCAL_DISTANCE)+XO)440 Screen.y=(int)(FOCAL_DISTANCE*Space.y /(Space.z+FOCAL_DISTANCE)+YO)441 returnScreen442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457 def RateCube_size( sx, sy, sz, x,y,color,X_Size=1,Y_Size=1,Z_Size=1, ratio=1):458 '''**********************************************************/459 |**函数: RateCube_size460 |**功能:显示3D的立方体461 |**说明:sx,sy,sz :角度值462 | x,y: 欲显示的坐标位置463 | X_Size,Y_Size,Z_Size:立方体的三个边长,默认为1464 | ratio:放大比例465

466 |467 |**作者: wcc 执念执战468 |**时间:2019-6-3469 |********************************************************'''

470 gMAT=[[0.0 for i in range(4)] for n in range(4)]471 temp=zuobiaostruct()472 Cube_dis=[zuobiaostruct() for i in range(8)]473

474

475

476

477 gMAT=structure_3D() #//构造为单位矩阵

478 gMAT=Translate3D(gMAT,-10,-8,-8) #//平移变换矩阵,当为边长的一半的倒数时,图像绕着自己旋转,即原点在中心

479 gMAT=Scale_3D(gMAT,X_Size*ratio,Y_Size*ratio,Z_Size*ratio) #//比例变换矩阵

480 gMAT=Rotate_3D(gMAT,sx,sy,sz) #//旋转变换矩阵

481 gMAT=Translate3D(gMAT,8,8,8) #//平移变换矩阵 x:调节距离中心点的位置,相当于下面Point0.z

482 #// y:上下调动位置 ,具体根据实际修改

483

484

485 for i in range(8):486

487

488 temp=vector_matrix_MULTIPLY(Cube[i],gMAT)#//矢量与矩阵相乘

489 Cube_dis[i]=PerProject(temp,0,0)#//正射投影 xo,yo:position

490 Cube_dis[i].x+=x491 Cube_dis[i].y+=y492 #Cube_dis[i].x+=SCREEN_X_MAX

493 #Cube_dis[i].y+=SCREEN_Y_MAX

494

495

496 '''将目标顶点按照预期连接起来'''

497 GUI_Line(Cube_dis[0].x,Cube_dis[0].y,Cube_dis[1].x,Cube_dis[1].y,color)498 GUI_Line(Cube_dis[0].x,Cube_dis[0].y,Cube_dis[2].x,Cube_dis[2].y,color)499 GUI_Line(Cube_dis[3].x,Cube_dis[3].y,Cube_dis[1].x,Cube_dis[1].y,color)500 GUI_Line(Cube_dis[3].x,Cube_dis[3].y,Cube_dis[2].x,Cube_dis[2].y,color)501

502

503 GUI_Line(Cube_dis[0+4].x,Cube_dis[0+4].y,Cube_dis[1+4].x,Cube_dis[1+4].y,color)504 GUI_Line(Cube_dis[0+4].x,Cube_dis[0+4].y,Cube_dis[2+4].x,Cube_dis[2+4].y,color)505 GUI_Line(Cube_dis[3+4].x,Cube_dis[3+4].y,Cube_dis[1+4].x,Cube_dis[1+4].y,color)506 GUI_Line(Cube_dis[3+4].x,Cube_dis[3+4].y,Cube_dis[2+4].x,Cube_dis[2+4].y,color)507

508

509 GUI_Line(Cube_dis[0].x,Cube_dis[0].y,Cube_dis[0+4].x,Cube_dis[0+4].y,color)510 GUI_Line(Cube_dis[1].x,Cube_dis[1].y,Cube_dis[1+4].x,Cube_dis[1+4].y,color)511 GUI_Line(Cube_dis[2].x,Cube_dis[2].y,Cube_dis[2+4].x,Cube_dis[2+4].y,color)512 GUI_Line(Cube_dis[3].x,Cube_dis[3].y,Cube_dis[3+4].x,Cube_dis[3+4].y,color)513

514

515

516

517

518 Last_flg1=False519 Last_flg2=False520 Last_x1=0521 Last_y1=0522

523 Last_x2=0524 Last_y2=0525

526

527 defRotatecircle( ax, ay, az,x, y,Z_Size, r, color ):528 '''**********************************************************/529 |**函数: Rotatecircle530 |**功能:显示3D的圆531 |**说明:sx,sy,sz :角度值532 | x,y: 欲显示的坐标位置533 | Z_Size:距旋转轴的距离534 | r:半径535 | color:颜色536

537 |538 |**作者: wcc 执念执战539 |**时间:2019-6-3540 |********************************************************'''

541

542 globalLast_flg1543 globalLast_flg2544 globalLast_x1,Last_y1,Last_x2,Last_y2545

546 gMAT=[[0.0 for i in range(4)] for n in range(4)]547 Point0=zuobiaostruct()548 Point3=zuobiaostruct()549

550 Point1=zuobiaostruct()551 PointDis=zuobiaostruct()552

553 gMAT=structure_3D() #//构造单位矩阵

554 gMAT=Translate3D(gMAT,-r,0,0) #//平移变换矩阵

555 gMAT=Scale_3D(gMAT,3,3,3) #//比例变换矩阵

556 gMAT=Rotate_3D(gMAT,ax,ay,az) #//旋转变换矩阵

557 #gMAT=Translate3D(gMAT,-r/2,-r/2,-r/2) #//平移变换矩阵

558

559

560

561 for i in range(0,r+r+1):562

563 Point0.x=i564 Point0.y=r-(r-sqrt(r*r-(r-i)*(r-i)))565 Point0.z=0#Point0.z+Z_Size

566 Point3.x=i567 Point3.y=r-(r+sqrt(r*r-(r-i)*(r-i)))568 Point3.z=0#Point3.z+Z_Size

569

570

571 Point1=vector_matrix_MULTIPLY(Point0,gMAT) #//矢量与矩阵相乘

572 PointDis=PerProject(Point1,0,0) #//映射投影

573 #PointDis.x+=SCREEN_X_MAX

574 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

575 #// 还要注意图像不要大到超过两个屏

576

577 if Last_flg1 == True and i!=0:578 GUI_Line(PointDis.x+x,PointDis.y+y,Last_x1+x,Last_y1+y,color) #连接上次的保存,避免点的空隙过大

579 else:580 GUI_Line(PointDis.x+x,PointDis.y+y,PointDis.x+1+x,PointDis.y+1+y,color)581 Last_x1=PointDis.x582 Last_y1=PointDis.y583 Last_flg1=True584

585 Point1=vector_matrix_MULTIPLY(Point3,gMAT) #//矢量与矩阵相乘

586 PointDis=PerProject(Point1,0,0) #//映射投影

587

588 #PointDis.x+=SCREEN_X_MAX

589 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

590 if Last_flg2 == True and i!=0:591 GUI_Line(PointDis.x+x,PointDis.y+y,Last_x2+x,Last_y2+y,color)#连接上次的保存,避免点的空隙过大

592 else:593 GUI_Line(PointDis.x+x,PointDis.y+y,PointDis.x+1+x,PointDis.y+1+y,color)594 Last_x2=PointDis.x595 Last_y2=PointDis.y596 Last_flg2=True597

598

599 SETCH32X29=[[0 for i in range(128)] for i in range(4)]600

601 '''// 设置宋体小二常规, 参数中的其他选项为纵向取模,字节倒序,保留,任何时候都加零'''

602 '''本字符集为 宽29 高 32的字符,使用时注意 32/8'''

603

604 '''

605 /*-- 执--*/606 /*-- 29 x32 ---*/607 '''

608 SETCH32X29[0]=(0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFC,0x04,0x80,0x80,0x00,0x00,0x00,0xFC,609 0xFC,0xFC,0x08,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,610 0x81,0x81,0x81,0xFF,0xFF,0xFF,0x61,0x23,0xB3,0x93,0x82,0x82,0xFF,0xFF,0xFF,0x02,611 0x02,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x01,612 0xFF,0xFF,0xFF,0x00,0x00,0x80,0xE0,0xF9,0x7F,0x1F,0x07,0x0E,0x1E,0x1C,0x1F,0x7F,613 0xFF,0xF0,0x80,0xC0,0xF8,0xF8,0x00,0x00,0x00,0x02,0x02,0x06,0x0E,0x0F,0x0F,0x0B,614 0x0C,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,615 0x07,0x07,0x07,0x00,616 )617

618 '''/*-- 念 --*/619 /*-- 29 x32 ---*/'''

620 SETCH32X29[1]=(621 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF8,0xFC,0xBE,0x1E,0x3C,622 0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x30,623 0x18,0x18,0x0C,0x26,0x27,0x23,0x21,0x21,0x20,0x21,0x27,0x2F,0x2F,0x24,0xE0,0xF1,624 0xF1,0x73,0x27,0x06,0x0E,0x0E,0x0C,0x0C,0x04,0x00,0x00,0x00,0x80,0xC0,0xF0,0xF8,625 0x78,0x00,0xFC,0xFC,0xFC,0x0B,0x0F,0x3E,0x3C,0x1E,0x07,0x07,0x03,0xE0,0xE0,0x88,626 0x38,0xF8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x07,627 0x07,0x07,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x07,0x07,0x07,0x02,0x00,0x01,628 0x01,0x00,0x00,0x00, )629

630 '''/*-- 执--*/631 /*-- 29 x32 ---*/'''

632 SETCH32X29[2]=(633

634 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFC,0x04,0x80,0x80,0x00,0x00,0x00,0xFC,635 0xFC,0xFC,0x08,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,636 0x81,0x81,0x81,0xFF,0xFF,0xFF,0x61,0x23,0xB3,0x93,0x82,0x82,0xFF,0xFF,0xFF,0x02,637 0x02,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x01,638 0xFF,0xFF,0xFF,0x00,0x00,0x80,0xE0,0xF9,0x7F,0x1F,0x07,0x0E,0x1E,0x1C,0x1F,0x7F,639 0xFF,0xF0,0x80,0xC0,0xF8,0xF8,0x00,0x00,0x00,0x02,0x02,0x06,0x0E,0x0F,0x0F,0x0B,640 0x0C,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,641 0x07,0x07,0x07,0x00, )642 '''/*-- 战 --*/643 /*-- 29 x32 ---*/'''

644 SETCH32X29[3]=(645

646 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0x08,0x00,0x00,0x80,0x80,0x80,0x00,647 0xFE,0xFE,0xFC,0x04,0x08,0x18,0x70,0xF0,0xF0,0x60,0x00,0x00,0x00,0x00,0x00,0xC0,648 0xC0,0x80,0x80,0xFF,0xFF,0xFF,0x81,0x81,0xC9,0xC9,0xC9,0x89,0x0D,0x0F,0xFF,0xFF,649 0xF4,0x04,0x04,0xC4,0xF6,0xF7,0x63,0x66,0x04,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x80,650 0x80,0x80,0x80,0x80,0x80,0xFF,0xFF,0xFF,0x00,0x00,0x80,0xC3,0xFF,0x7F,0xFC,0xFF,651 0xCF,0x07,0x01,0xF0,0xF0,0x00,0x00,0x00,0x00,0x07,0x03,0x03,0x00,0x00,0x00,0x00,652 0x00,0x08,0x0B,0x0F,0x07,0x06,0x03,0x01,0x01,0x00,0x00,0x00,0x01,0x03,0x07,0x07,653 0x0F,0x0F,0x08,0x00,)654

655

656

657

658

659

660

661

662

663

664 defShow3DCharXxY(dp,dp_x,dp_y,ax,ay,az,x,y,Z_Size,color):665 '''**********************************************************/666 |**函数: Show3DCharXxY667 |**功能:显示3D字体,需要自己取模,支持任意python环境668 |**说明:dp:字体数组的名称,为需要取模的字体。如上面的 SETCH32X29[]数组669 取模方式:设置宋体小二常规, 参数中的其他选项为纵向取模,字节倒序,保留,任何时候都加零670 dp_x,dp_y:取模字体的长宽,比如32x29的字符为:29,32/4,因为保存的字符格式为列项一个字节表示8个像素点,具体参考取模原理671 | ax,ay,az:角度值672 | x,y: 欲显示的坐标位置673 | Z_Size:距旋转轴的距离674 | color:颜色675

676 |677 |**作者: wcc 执念执战678 |**时间:2019-6-3679 |********************************************************'''

680

681 gMAT=[[0.0 for i in range(4)] for n in range(4)]682 Point0=zuobiaostruct()683 Point1=zuobiaostruct()684 PointDis=zuobiaostruct()685

686 gMAT=structure_3D() #//构建单位矩阵

687 gMAT=Translate3D(gMAT,-16,-12,-6); #//平移变换矩阵

688 gMAT=Scale_3D(gMAT,4,4,4); #//比例变换矩阵

689 gMAT=Rotate_3D(gMAT,ax,ay,az); #//旋转变换矩阵

690 #gMAT=Translate3D(gMAT,0,-8,8); #//平移变换矩阵 x:调节距离中心点的位置,相当于下面Point0.z

691 #//y:上下调动位置 ,具体根据实际修改

692

693

694

695 for i inrange(dp_y):696 for k in range(8):697 temp = 0x01 <

702 Point0.x=j703 Point0.y=(i*8)+k704 Point0.z =Z_Size #//此参数能够改变字符距离旋转轴中心的距离

705

706 Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘

707 PointDis=PerProject(Point1,0,0) #//映射投影

708 #PointDis.x+=SCREEN_X_MAX

709 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

710 Gui_Point(PointDis.x+x,PointDis.y+y,color)711

712

713

714

715

716

717 def Show3D16x16Font(font,ax,ay,az,x,y,Z_Size,frontcolor,backcolor,model=0):718 '''**********************************************************/719 |**函数: Show3D16x16Font720 |**功能:显示3D的16x16字符,为从汉字库读取的字符数据,支持数千个汉字721 | 本函数需要 binascii 库的支持,不支持此库的环境无法运行本函数722 |**说明:font:欲显示的汉字,目前只支持一个字符的显示,只支持汉字的显示723 | sx,sy,sz :角度值724 | x,y: 欲显示的坐标位置725 | Z_Size:距旋转轴的距离726 | frontcolor,backcolor:颜色,前景色和背景色727 | model:显示模式,只有模式为1时才填充背景色,否则只填充前景色728 |729 |**作者: wcc 执念执战730 |**时间:2019-6-3731 |********************************************************'''

732 length =len(font)733 if length == 1: #只支持一个支付的显示

734 text =font735 else:736 return

737 gb2312 = text.encode('gb2312')738 hex_str =binascii.b2a_hex(gb2312)739 result = str(hex_str,encoding = 'utf-8')740

741 area = eval('0x' + result[:2]) - 0xA0

742 index = eval('0x' + result[2:]) - 0xA0

743 offset = (94 * (area - 1)+ (index - 1))*32

744 font_rect =None745 with open("D:/Mystudy/Python/pyGame/HZK16","rb") as f: #16x16字符集的地址

746 f.seek(offset)747 font_rect = f.read(32)748 f.close()749

750 gMAT=[[0.0 for i in range(4)] for n in range(4)]751 Point0=zuobiaostruct()752 Point1=zuobiaostruct()753 PointDis=zuobiaostruct()754

755 gMAT=structure_3D() #//构建单位矩阵

756 gMAT=Translate3D(gMAT,-8,-8,-8); #//平移变换矩阵

757 gMAT=Scale_3D(gMAT,4,4,4); #//比例变换矩阵

758 gMAT=Rotate_3D(gMAT,ax,ay,az); #//旋转变换矩阵

759 #gMAT=Translate3D(gMAT,8,8,8); #//平移变换矩阵 x:调节距离中心点的位置,相当于下面Point0.z

760

761

762

763 i=0764 k=0765 j=0766 XO=0767 YO=0768

769 for i in range(16):770 for k in range(8):771 temp = 0x01 <

776 Point0.x=16-(k+(1-j)*8)777 Point0.y=i #(i*8)+k

778 Point0.z=Z_Size #//此参数能够改变字符距离旋转轴中心的距离

779

780 Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘

781 PointDis=PerProject(Point1,XO,YO) #//映射投影

782 #PointDis.x+=SCREEN_X_MAX

783 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

784 Gui_Point(PointDis.x+x,PointDis.y+y,frontcolor)785 else:786 if model ==1: #模式为1 时才会绘制底色

787 Point0.x=16-(k+(1-j)*8)788 Point0.y=i #(i*8)+k

789 Point0.z=Z_Size #//此参数能够改变字符距离旋转轴中心的距离

790

791 Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘

792 PointDis=PerProject(Point1,XO,YO) #//映射投影

793 #PointDis.x+=SCREEN_X_MAX

794 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

795 Gui_Point(PointDis.x+x,PointDis.y+y,backcolor)796

797

798

799

800

801

802

803

804 def Show3D32x32Font(font,ax,ay,az,x,y,Z_Size,frontcolor,backcolor,model=0):805 '''**********************************************************/806 |**函数: Show3D32x32Font807 |**功能:显示3D的32x32字符,为从汉字库读取的字符数据,支持数千个汉字808 | 本函数需要 binascii 库的支持,不支持此库的环境无法运行本函数809 |**说明:font:欲显示的汉字,目前只支持一个字符的显示,只支持汉字的显示810 | sx,sy,sz :角度值811 | x,y: 欲显示的坐标位置812 | Z_Size:距旋转轴的距离813 | frontcolor,backcolor:颜色,前景色和背景色814 | model:显示模式,只有模式为1时才填充背景色,否则只填充前景色815 |816 |**作者: wcc 执念执战817 |**时间:2019-6-3818 |********************************************************'''

819 length =len(font)820 if length == 1: #只支持一个支付的书写

821 text =font822 else:823 return

824 gb2312 = text.encode('gb2312')825 hex_str =binascii.b2a_hex(gb2312)826 result = str(hex_str,encoding = 'utf-8')827

828 area = eval('0x' + result[:2]) - 0xA0

829 index = eval('0x' + result[2:]) - 0xA0

830 offset = (94 * (area - 1)+ (index - 1))*32*4

831 font_rect = []*32*4

832 with open("D:/Mystudy/Python/pyGame/HZK32zkkh","rb") as f:#32x32字符集的地址,HZK32wryh 为微软雅黑字体,HZK32zkkh为站酷酷黑字体

833 f.seek(offset)834 font_rect = f.read(32*4)835 f.close()836

837 gMAT=[[0.0 for i in range(4)] for n in range(4)]838 #temp=zuobiaostruct()

839 Point0=zuobiaostruct()840 Point1=zuobiaostruct()841 PointDis=zuobiaostruct()842

843 gMAT=structure_3D() #//构建单位矩阵

844 gMAT=Translate3D(gMAT,-16,-12,-6); #//平移变换矩阵,能够调节字体相对中心轴的位置

845 gMAT=Scale_3D(gMAT,4,4,4); #//比例变换矩阵

846 gMAT=Rotate_3D(gMAT,ax,ay,az); #//旋转变换矩阵

847 #gMAT=Translate3D(gMAT,8,8,8); #//平移变换矩阵 x:调节距离中心点的位置,相当于下面Point0.z

848

849

850

851 i=0852 k=0853 j=0854 XO=0855 YO=0856

857 for i in range(32):858 for k in range(8):859 temp = 0x01 <

864 Point0.x=32-(k+(3-j)*8)865 Point0.y=i #(i*8)+k

866 Point0.z=Z_Size #//此参数能够改变字符距离旋转轴中心的距离

867

868 Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘

869 PointDis=PerProject(Point1,XO,YO) #//映射投影

870 #PointDis.x+=SCREEN_X_MAX

871 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

872 Gui_Point(PointDis.x+x,PointDis.y+y,frontcolor)873 else:874 if model ==1: #模式为1 时才会绘制底色

875 Point0.x=32-(k+(3-j)*8)876 Point0.y=i #(i*8)+k

877 Point0.z=Z_Size #//此参数能够改变字符距离旋转轴中心的距离

878

879 Point1=vector_matrix_MULTIPLY(Point0,gMAT)#//矢量与矩阵相乘

880 PointDis=PerProject(Point1,XO,YO) #//映射投影

881 #PointDis.x+=SCREEN_X_MAX

882 #PointDis.y+=SCREEN_Y_MAX #//用来解决超出屏幕后乱码的问题。去掉后顺时针转到超出左边界后会找不到坐标无限划线,

883 Gui_Point(PointDis.x+x,PointDis.y+y,backcolor)884

885

886

887

888

889

890

891

892 defexample_1(ax,ay,az,x,y,char1,char2,forecolor,backcolor):893 '''**********************************************************/894 |**函数: example_1895 |**功能:旋转立方体 + 旋转字符,字符为取模字符,支持取模,支持其他Python环境896 | 只能显示取模字体897 |**说明:898 | ax,ay,az :角度值899 | x,y: 欲显示的坐标位置900 char1,char2:切换显示哪个字符901 | Z_Size:距旋转轴的距离902 | frontcolor,backcolor:颜色,前景色和背景色903 |904 |905 |**作者: wcc 执念执战906 |**时间:2019-6-3907 |********************************************************'''

908 RateCube_size(ax,ay,az,x,y,forecolor,8,8,8,1)909 RateCube_size(ax,ay+45,az,x,y,forecolor,12,12,12,1)910

911 Show3DCharXxY(SETCH32X29[char1],29,4,ax,ay,az,x,y,-12,forecolor)912 Show3DCharXxY(SETCH32X29[char2],29,4,ax,ay-90,az,x,y,-12,forecolor)913

914 defexample_2(ax,ay,az,x,y,char1,char2,forecolor,backcolor):915 '''**********************************************************/916 |**函数: example_2917 |**功能:旋转立方体 + 旋转字符,字符为字符集,需要库支持,需要字符集支持918 | 修改内部的 char 字符串可现实任意(字符集所支持的)中文字符919 |**说明:920 | ax,ay,az :角度值921 | x,y: 欲显示的坐标位置922 char1,char2:切换显示哪个字符923 | Z_Size:距旋转轴的距离924 | frontcolor,backcolor:颜色,前景色和背景色925 |926 |927 |**作者: wcc 执念执战928 |**时间:2019-6-3929 |********************************************************'''

930

931 char="执念执战"

932 RateCube_size(ax,ay,az,x,y,forecolor,8,8,8,1)933 RateCube_size(ax,ay,az,x,y,forecolor,12,12,12,1)934

935 Show3D32x32Font(char[char1],ax,ay%90,az,x,y,-12,forecolor,backcolor,0)936 Show3D32x32Font(char[char2],ax,ay%90-90,az,x,y,-12,forecolor,backcolor,0)937

938 defexample_3(ax,ay,az,x,y,char1,char2,forecolor,backcolor):939 '''**********************************************************/940 |**函数: example_3941 |**功能:旋转的16x16的中文字符串942 | 修改内部的 char 字符串可现实任意(字符集所支持的)中文字符943 |**说明:944 | ax,ay,az :角度值945 | x,y: 欲显示的坐标位置946 char1,char2:切换显示哪个字符947 | Z_Size:距旋转轴的距离948 | frontcolor,backcolor:颜色,前景色和背景色949 |950 |951 |**作者: wcc 执念执战952 |**时间:2019-6-3953 |********************************************************'''

954 char="任意中文字符测试"

955 length =len(char)956 for i inrange(length):957 Show3D16x16Font(char[i],ax,ay,az,x+16*4*i,y,2,forecolor,backcolor,0)958

959

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值