Math and Graphics: Analog Clock Example Program
This chapter introduces Python's math module, which can perform calculations such as common trigonometric sine, cosine, and tangent functions.
Use the sine and cosine functions to draw a circle
to create an example program for Anlog Clock
About the math module
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.
Note:
For negative numbers, the modulo
remainder should be the number greater than or equal to 0 and less than the absolute value of the number, for example (-5)%3=1, consider -5 =3*(-2)+1
The example given in the book can be optimized.
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 function is redundant, because +-360° has no effect on the result in the operation of trigonometric functions.
After removing all the parts with wrap_angle(), the program works fine.
1. Modify the circle program so that a different shape is drawn at each angle instead of a small filled 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()
feels like drawing a little thing that will wriggle, which is a little interesting.
2. The Analog Circle looks better. I didn't implement this. I fine-tuned the angle of the hour hand, and it felt more customary. Now
the hour hand does not always point to the position of the hour, but instead points between two hours according to the minute.
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()
seems more idiomatic. As far as aesthetic requirements are concerned.
Introduction to Python Game Programming 4
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=324466487&siteId=291194637
Ranking