Math和Graphics:Analog Clock示例程序
本章介绍Python的math模块,该模块可以执行计算,如常见的三角正弦函数、余弦函数、正切函数等。

使用正弦和余弦函数绘制圆
创建Anlog Clock示例程序

关于math模块
https://docs.python.org/3/library/math.html
https://docs.python.org/2.7/library/math.html

math.cos(x)
    Return the cosine of x radians.

math.sin(x)
    Return the sine of x radians.

math.tan(x)
    Return the tangent of x radians.

math.degrees(x)
    Convert angle x from radians to degrees.

math.radians(x)
    Convert angle x from degrees to radians.

math.pi
    The mathematical constant π = 3.141592..., to available precision.

math.e
    The mathematical constant e = 2.718281..., to available precision.

注意:
    对于负数的取模
    余数应该是大于等于0小于该数绝对值的那个数,比方说(-5)%3=1,认为-5=3*(-2)+1

书中给出的示例可以优化。

Draw circle in hard way

import sys,pygame,math,random
from pygame.locals import *
pygame.init()

screen=pygame.display.set_mode((600,500))
pygame.display.set_caption("Circle Demo")
angle=0
color=random.randint(0,255),random.randint(0,255),random.randint(0,255)
while True:
    for event in pygame.event.get():
        if event.type==QUIT:
            sys.exit()
    keys=pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
    
    screen.fill((255,255,255))

x=300
    y=250
    radius=200
    
    
    circle_x=x+radius*math.cos(math.radians(angle))
    circle_y=y+radius*math.sin(math.radians(angle))

pygame.draw.circle(screen,color,(int(circle_x),int(circle_y)),10,0)
    angle+=1
    if angle>359:
        color=random.randint(0,255),random.randint(0,255),random.randint(0,255)
        angle=0    
    
    pygame.display.update()

Anlog Clock示例程序

import sys,datetime,pygame,math
from pygame.locals import *
from datetime import datetime,date,time
pygame.init()
def print_text(font,x,y,text,color=(255,255,255)):
    imgtext=font.render(text,True,color)
    screen.blit(imgtext,(x,y))

def wrap_angle(angle):
    return angle%360

#main program begins
screen=pygame.display.set_mode((600,500))
pygame.display.set_caption("Anlog Clock Demo")
font=pygame.font.Font(None,36)
orange=220,180,0
white=255,255,255
yellow=255,255,0
pink=255,100,100

pos_x=300
pos_y=250
radius=250
angle=360

#repeating loop
while True:
    for event in pygame.event.get():
        if event.type==QUIT:
            sys.exit()
    keys=pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
    
    screen.fill((0,0,100))
    #draw one step around the circle
    pygame.draw.circle(screen,white,(pos_x,pos_y),radius,6)
    
    #draw the clock numbers1-12
    for n in range(1,13):
        angle=math.radians(n*30-90)
        x=(radius-20)*math.cos(angle)+pos_x-10
        y=(radius-20)*math.sin(angle)+pos_y-10
        print_text(font,int(x),int(y),str(n))
    
    #get the time of day
    today=datetime.today()
    hours=today.hour%12
    minutes=today.minute
    seconds=today.second
    
    #draw the hours hand
    hour_angle=wrap_angle(hours*30-90)
    hour_angle=math.radians(hour_angle)
    hour_x=pos_x+math.cos(hour_angle)*(radius-80)
    hour_y=pos_y+math.sin(hour_angle)*(radius-80)
    target_h=(int(hour_x),int(hour_y))
    pygame.draw.line(screen,pink,(pos_x,pos_y),target_h,25)
    
    #draw the minutes hand
    minute_angle=wrap_angle(minutes*6-90)
    minute_angle=math.radians(minute_angle)
    minute_x=pos_x+math.cos(minute_angle)*(radius-60)
    minute_y=pos_y+math.sin(minute_angle)*(radius-60)
    target_m=(int(minute_x),int(minute_y))
    pygame.draw.line(screen,orange,(pos_x,pos_y),target_m,12)
    
    #draw the seconds hand
    second_angle=wrap_angle(seconds*6-90)
    second_angle=math.radians(second_angle)
    second_x=pos_x+math.cos(second_angle)*(radius-40)
    second_y=pos_y+math.sin(second_angle)*(radius-40)
    target_s=(int(second_x),int(second_y))
    pygame.draw.line(screen,yellow,(pos_x,pos_y),target_s,6)
    
    #cover the center
    pygame.draw.circle(screen,white,(pos_x,pos_y),20)

print_text(font,0,0,str(hours)+":"+str(minutes)+":"+str(seconds))

pygame.display.update()

wrap_angle函数是多余的,因为在三角函数的运算中+-360°对于结果没有影响。
去除所有带有 wrap_angle()的部分,程序运行正常。

1、修改circle程序,以使得在每个角度绘制不同的形状,而不是绘制一个小的填充的圆。
import sys,pygame,math,random
from pygame.locals import *
pygame.init()

screen=pygame.display.set_mode((600,500))
pygame.display.set_caption("Circle Demo")
angle=0
color=random.randint(0,255),random.randint(0,255),random.randint(0,255)
while True:
    for event in pygame.event.get():
        if event.type==QUIT:
            sys.exit()
    keys=pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
    
    screen.fill((0,0,0))

x=300
    y=250
    radius=200
    
    
    circle_x=int(x+radius*math.cos(math.radians(angle)))
    circle_y=int(y+radius*math.sin(math.radians(angle)))
    
    if angle%3==0:
        pygame.draw.circle(screen,color,(circle_x,circle_y),12)
    elif angle%3==1:
        pygame.draw.rect(screen,color,(circle_x-10,circle_y-10,20,20))
    elif angle%3==2:
        pygame.draw.ellipse(screen,color,(circle_x-15,circle_y-10,30,20))

angle+=1
    if angle>359:
        color=random.randint(0,255),random.randint(0,255),random.randint(0,255)
        angle=0    
    
    pygame.display.update()

感觉画了一个会蠕动的小东西,有一点意思。

2、Analog Circle变得更好看些。这个我没去实现,我把时针的角度做了微调,感觉更符合习惯。现在
时针不会一直指向整点的位置了,而是会根据分钟数指向两个整点之间。
import sys,datetime,pygame,math
from pygame.locals import *
from datetime import datetime,date,time
pygame.init()
def print_text(font,x,y,text,color=(255,255,255)):
    imgtext=font.render(text,True,color)
    screen.blit(imgtext,(x,y))

def wrap_angle(angle):
    return angle%360

#main program begins
screen=pygame.display.set_mode((600,500))
pygame.display.set_caption("Anlog Clock Demo")
font=pygame.font.Font(None,36)
orange=220,180,0
white=255,255,255
yellow=255,255,0
pink=255,100,100

pos_x=300
pos_y=250
radius=250
angle=360

#repeating loop
while True:
    for event in pygame.event.get():
        if event.type==QUIT:
            sys.exit()
    keys=pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
    
    screen.fill((0,0,100))
    #draw one step around the circle
    pygame.draw.circle(screen,white,(pos_x,pos_y),radius,6)
    
    #draw the clock numbers1-12
    for n in range(1,13):
        angle=math.radians(n*30-90)
        x=(radius-20)*math.cos(angle)+pos_x-10
        y=(radius-20)*math.sin(angle)+pos_y-10
        print_text(font,int(x),int(y),str(n))
    
    #get the time of day
    today=datetime.today()
    hours=today.hour%12
    minutes=today.minute
    seconds=today.second
    
    #draw the hours hand
    hour_angle=wrap_angle(hours*30-90+minutes*0.5)  #对比原来的程序修改了这一行。
    hour_angle=math.radians(hour_angle)
    hour_x=pos_x+math.cos(hour_angle)*(radius-80)
    hour_y=pos_y+math.sin(hour_angle)*(radius-80)
    target_h=(int(hour_x),int(hour_y))
    pygame.draw.line(screen,pink,(pos_x,pos_y),target_h,25)
    
    #draw the minutes hand
    minute_angle=wrap_angle(minutes*6-90)
    minute_angle=math.radians(minute_angle)
    minute_x=pos_x+math.cos(minute_angle)*(radius-60)
    minute_y=pos_y+math.sin(minute_angle)*(radius-60)
    target_m=(int(minute_x),int(minute_y))
    pygame.draw.line(screen,orange,(pos_x,pos_y),target_m,12)
    
    #draw the seconds hand
    second_angle=wrap_angle(seconds*6-90)
    second_angle=math.radians(second_angle)
    second_x=pos_x+math.cos(second_angle)*(radius-40)
    second_y=pos_y+math.sin(second_angle)*(radius-40)
    target_s=(int(second_x),int(second_y))
    pygame.draw.line(screen,yellow,(pos_x,pos_y),target_s,6)
    
    #cover the center
    pygame.draw.circle(screen,white,(pos_x,pos_y),20)

print_text(font,0,0,str(hours)+":"+str(minutes)+":"+str(seconds))

pygame.display.update()

看起来更符合习惯了。至于美观的要求就算了。

最新文章

  1. bitset用法总结
  2. 冲刺阶段 day 8
  3. redis unwatch discard
  4. PHP 按二维数组的键值排序
  5. oc-31-多对象的内存管理
  6. Oracle MERGE INTO的使用方法
  7. python基础补充
  8. 【.NET】Linq几样特点
  9. structs2的核心和工作原理
  10. 20165318 预备作业二 学习基础和C语言基础调查
  11. 安装WebLogic的详细步骤
  12. Spring服务定制
  13. 聚类-31省市居民家庭消费水平-city
  14. 局域网 服务器 https
  15. sql语句(一)— —判断是否有这条数据的优化
  16. Python 学习之路的前言
  17. 集合总结三(HashMap的实现原理)
  18. Flink(三)Flink开发IDEA环境搭建与测试
  19. LeetCode 985 Sum of Even Numbers After Queries 解题报告
  20. zl

热门文章

  1. IDEA导入Git项目后右键项目找不到Git选项的解决方法
  2. [vue--开发记录]使用location.href修改地址跳转页面在ie上遇到的坑
  3. 基于RAP(Mock)实现前后端分离开发
  4. ui component 是一个前端 mvc 开发框架
  5. 使用commons.cli实现MyCP
  6. tensorflow(3)可视化,日志,调试
  7. python selenium处理windows窗口
  8. Linux启动顺序、运行级别及开机启动
  9. 网络编程之实现server端并发聊天
  10. linux 下常用的50条命令