|
马上注册,结交更多好友,享用更多功能,让你轻松玩转新大榭论坛!
您需要 登录 才可以下载或查看,没有账号?注册
x
大家好!今天是 九 · 一八,还有十来天就到了伟大的十一国庆节了。
7 @1 E4 g* U7 p3 c& ^7 v: \! ?让我们牢记历史,不辱使命!今年是中华人民共和国建国第72周年,为了迎接这个伟大的日子,《新大榭邀你一起学Python》系列课程培训主讲张老师给新大榭学员带来一期特别的教程——用 Python turtle 绘制国旗,同时祝愿我们的祖国繁荣昌盛! 5 h& E2 p0 c: x; z6 L) l
5 f* f- D9 u" i# F
. |. k( M( B; X ~& r- A0 ?4 T
在开始绘制之前,我们要明白一点:不是随手画出的五星红旗都是国旗。在我国,国旗的形状、大小是有明确规定的,我们特地找到了《中华人民共和国国家标准 国旗(GB 12982-2004)》,这份标准明确记录了国旗的比例、颜色、每颗星的形状和位置等信息,为我们绘制国旗提供参考。
$ w# |/ k/ h% |- R: B' C, M4 \
# C- D% l+ v4 C
5 l* w& [% v' o6 M* L! x- z
首先,我们先来分析一下结构,方便整理绘制逻辑和流程。
l4 `3 `4 C4 b
( |2 M, N) K3 R" s国旗的形状可以分解为一个四边形(旗面)、1颗大星星和4颗小星星组成。绘制时我们将星星的边框和填充颜色设置为黄色,把四边形的底色设置为红色。接下来我们将通过Python turtle逐步把国旗画出来。
8 R& O' e5 ^$ {% r( g6 U' G
7 F$ P8 _+ L; I
5 I5 w; L1 { F% ?第一步:绘制国旗的四边:
& x3 C: g D4 b: T% ]+ I《GB:12982-2004》对国旗尺寸的定义为长宽比为3:2,所以大家在绘制的时候长,宽的数值一定要满足这个比例。+ W7 H8 P# @0 y8 O0 R3 H' J
- import turtle # 导入turtle模块3 B1 a$ e$ s% [; n# W1 T# ~
- turtle.speed(10) # 设置画笔绘制速度) U+ Q" r7 z+ L4 v! ?2 ]# K
, P" B. s* u/ `* J% e5 `$ n- # 国旗的四边
5 P3 m/ R" N0 U1 _6 E0 ^$ W8 J6 ? - turtle.up()
2 I1 h R( Q4 u, ?- w - turtle.goto(-200, 200)
% p* _' s" ?0 O4 g4 g - turtle.down()
6 g, @. n: l3 x" ^, Z4 y - turtle.begin_fill()
6 h9 U, q# K" C: k" l - turtle.fillcolor("red") # 填充色# r% t! |+ Y* G9 w' }6 I6 P7 o
- turtle.pencolor("red") # 画笔颜色
, K) D7 {0 I1 g/ W4 I2 |7 D8 m - for i in range(2):# c& [* o5 h: c0 w k$ O& }. h
- turtle.forward(438) # 向前移动438
- b" h' D9 L6 R! ~ - turtle.right(90) # 以角度单位向右90度转动; [6 E# C* `: m5 [6 c
- turtle.forward(292) # 向前移动292
" E+ Q0 n/ s3 H y# r/ c2 m - turtle.right(90) # 以角度单位向右90度转动
) m" c' f. f5 }' |: g& _ - turtle.end_fill() # 结束四边的填充
复制代码 : Q ^2 F% }3 ^& C" r6 ^- ]& Y: b
第二步:绘制大五角星$ e) W% I" |6 I/ M) U1 e! a: b
接下来我们就要来画五角星了,我们首先画出一个填充色为黄色的五角星:- # 更改海龟的画笔颜色和填充色: o" y, Z0 R' h- Y+ y4 [& \
- turtle.fillcolor('yellow') # 填充色3 L9 N1 _) |. H
- turtle.pencolor("yellow") # 画笔颜色
, W. W: O5 b$ B |- E
5 H2 b6 d6 ]( ^% B! ^- # 绘制大五角星4 j: c) b% ?. {5 _
- turtle.up() # 抬笔不绘制
, O J1 Y+ x: k" D$ Y5 D - turtle.goto(-170, 145) # 画笔设置到起始位置% ^0 s, q' G" P- u: n( T( e
- turtle.down()
5 Z% b2 e+ \ {' w) @- P* d. C - turtle.begin_fill()
. o' C4 M, |) Q( d - for i in range(5): # 循环5次
- d* e: O" p: {# P% n c - turtle.forward(50) # 向前移动501 Z2 Y8 D! y. v! I( F
- turtle.right(144) # 以角度单位向右转动. y( j6 a( G' |# d
- turtle.end_fill() # 结束填充
复制代码 . e& I7 J4 H0 W2 Z7 K
效果是这样:
# r; F5 g1 z' {& B4 ^
9 F0 e B" N) }6 D" O" p5 Z
4 J: b! e: ~5 p, m$ m
% B, i) E" m4 D
% L* S/ I V- {4 r) J+ U
是不是也挺简单的?代码相信大家看这都不陌生。 w& v3 o f3 P2 N
, \$ w0 ?0 g1 d" n: h5 I" `学会了如何画五角星,我们现在看看如何在红色背景上绘制出和国旗一样的5颗五角星。我们先从大五角星开始,也就是最大的那颗五角星:' U+ g, u- c% ~' o( ^" r) v6 V
- # 更改海龟的画笔颜色和填充色/ j/ T5 z) ~* t8 Q
- turtle.fillcolor('yellow') # 填充色3 ^; j) A8 |8 U4 b9 ?9 k4 f6 ?! U# y
- turtle.pencolor("yellow") # 画笔颜色& v4 l _: _; ~- m- [% D0 |
5 m, C4 `. M6 s- # 绘制大五角星% }' \. W# z$ l8 V
- turtle.up() # 抬笔不绘制
; X; ]; [( Q' r u3 k0 Y$ N* S - turtle.goto(-170, 145) # 画笔设置到起始位置
! z8 F* S/ M! P) S - turtle.down()
5 U$ B2 c2 K5 s( F% Y- ` - turtle.begin_fill()& x# J% d, C9 C" ?5 K6 O! ^
- for i in range(5): # 循环5次
2 q$ y2 h. t9 _% J) i0 E: a5 o - turtle.forward(50) # 向前移动50
) p' w) H4 ?! s5 P' h1 o4 }; y* ^ - turtle.right(144) # 以角度单位向右转动' f) F! g+ A3 Y; x2 C
- turtle.end_fill() # 结束填充
复制代码 2 d' a, ^( H2 d# s" _& m) `
在这里大家要注意,我们画的第一颗大五角星是需要填充颜色的,需要将for循环的部分放在 begin_fill 和 end_fill 之间。因为我们真正绘制的部分就是在for循环中。同时,begin_fill 和 end_fill 方法一定要成对出现,缺一不可。
% U2 O1 b2 e% X; Z ^) b: {2 ^/ \( D1 s3 W8 Z
第三步:画出四颗小五角星
% S% p0 f" U9 Z( u4 M1 ?' A/ l; ~% f* b
大五角星绘制好了,我们从上到下依次绘制小五角星。绘制的时候大家需要注意关于小五角星的坐标问题了,我们前面的文章turtle已经为你详细介绍了turtle中的坐标系问题。点击这里了解坐标系的设置方法。9 j; K `+ j+ B; H4 w! ?. I( M' e
1 M8 L) N+ @' i: \2 |. k; d五角星在国旗上的位置如何确定呢?这里我们又要参考《GB:12982-2004》给出的国旗的设计方法。国旗设计中还有很多数学知识。为了确定每一个五角星的在国旗上的物理位置,将旗面对分为四个相等的长方形,并将左上方之长方形上下划为十等分,左右划为十五等分,如下图:
6 c0 \; |+ U5 i
. t% M8 x2 ?6 {0 [ A. t# A6 m( z9 o
根据《GB:12982-2004》的图示,我们可以看出:大五角星的中心点,在该长方形上5下5、左5右10的地方。其画法为:以此点为圆心,以三等分为半径作一圆。在圆周上,定出5个等距离的点,第一点须位于圆之正上方。然后将此五点中各相隔的两点相联,使各成一直线。这5条直线所构成之外轮廓线,即为所需之大五角星。$ U# D8 w# z6 U
9 K0 t+ S5 n+ _: l
四颗小五角星的中心点,第一点在该长方形上二下八、左十右五之处,第二点在上四下六、左十二右三之处,第三点在上七下三、左十二右三之处,第四点在上九下一、左十右五之处。其画法为:以以上四点为加圆心,各以一等分为半径,分别作四个圆。在每个圆上各定出五个等距离的点,其中均须各有一点位于大五角星中心点与以上四个圆心的各联结线上,然后用构成大五角星的同样方法,构成小五角星。此四颗小五角星均各有一个角尖对大五角星的中心点。% `5 Z8 Y7 }' b6 V3 m
( o/ k4 {8 T4 Y6 x
根据《GB:12982-2004》给我们的提示,我们用平面几何的知识就可以计算出具体坐标了,具体如下:6 b/ S' F5 G- L& Z
大五角星坐标为:(-170,145)
7 Z i- C. d7 F7 E第1颗小五角星坐标为:(-100,180). o1 q0 q, S/ E! J- C* }
第2颗小五角星坐标为:(-85,150)! v9 Y% T2 d; o! y
第3颗小五角星坐标为:(-85,120)
4 M% ]$ g1 g0 F$ g第4颗小五角星坐标为:(-100,100)
! @& K# ^: q2 O. G: O) m7 H; f 0 z" V8 o" \/ X. g6 S n
有了以上这些信息,我们就可以轻松的把所有的五角星画出来了。
1 L% H. ^) G6 S( [, ~/ Y- # 绘制第1颗副星
. s, ~) m. b- ]: Q - turtle.up()( ?6 U, V# O$ B, W/ ~9 c
- turtle.goto(-100,180); Z) F2 C6 s$ M8 d# x( F
- turtle.setheading(305)
- N% a( c% `# |# d, g" d - turtle.down()
; G& H( F9 p0 } - turtle.begin_fill()
0 ?5 n% m. C, V - for i in range (5):6 @ j( m3 w$ S d; t/ S, t8 D4 ]
- turtle.forward(20)# h) C9 E5 q, U
- turtle.left(144)* P( y+ U- g7 M
- turtle.end_fill()
复制代码
7 j# Z W. L \其实代码跟第一个大五角星的流程都是一样的,但是多了一条语句:turtle.setheading (305) ,这个语句的意思是改变海龟的朝向。其实 turtle.left 或者 turtle.right 也可以改变海龟的方向,但是跟这个方法有什么区别呢?
+ M& O9 @) |$ m5 ^! j
9 c5 A/ [; J, u1 i& h最大的区别就是 left 或者 right 改变了方向以后,本身的朝向是不会变的,而 setheading 方法在改变了方向以后,也会改变海龟本身的方向。这里主要是用于控制每一个五角星之间的距离的,大家可以自己动手写一段简单的代码分别用 right , left 和 setheading 方法测试一下就能看出区别了。
- _& r, V8 H! E- ?; ?! X3 [5 w0 B8 q. S
第一个小五角星画出来了以后,剩下的就很简单了:, W# g8 G) ~$ v
- # 绘制第2颗副星* V' ^) ], W* {/ w
- turtle.up()
* i2 k5 f7 v3 y6 B* @5 [4 J - turtle.goto(-85,150)0 A3 j+ Y/ t% l' s
- turtle.setheading(30); C+ ^7 ]/ b: [
- turtle.down()
0 k: p; g1 z! \2 { - turtle.begin_fill()! Q$ P& ^( ]7 _- |1 y" k
- for i in range (5):) Z% Q; _" D5 s# B q+ R7 Q5 f6 N4 W$ i
- turtle.forward(20)# Q6 \* e$ _8 v( Q; d) ^
- turtle.right(144)1 y! r% g7 j) J6 ]; p/ ` R
- turtle.end_fill()
! ] q1 u6 l9 L - ( e, F8 _8 k) ] d
- # 绘制第3颗副星
( s9 \4 Y, f3 Y; v1 u, s; x - turtle.up()
, I- A- E5 d4 t+ P7 I$ ]+ a' r - turtle.goto(-85,120)1 M6 [4 Q3 l* L* x" v
- turtle.setheading(0)
+ _* j& f8 b/ A p- f9 O! I8 V - turtle.down()9 O; i' f1 X% n3 i! P; h& Y
- turtle.begin_fill()
; U% h h) H: c/ k w2 { - for i in range (5):
9 k/ L; l' [# b2 N - turtle.forward(20). Z8 B- Q5 [6 Q$ Y
- turtle.right(144)
* S+ t( b' _$ g9 R - turtle.end_fill()
1 b+ R8 L: L1 h! I0 }
% _* d) o r- Z: e p) V0 ^- # 绘制第4颗副星# v- w) P- B( [( J# e' k5 u9 W% }& X
- turtle.up(); `0 o. a* Y8 A6 b& D, @
- turtle.goto(-100,100)
( F- o) y3 Z% h/ ?# R7 M2 \$ b - turtle.setheading(300)# K Y( L( C" u3 J# r$ ~
- turtle.down(). S5 y" Y3 r) e7 t
- turtle.begin_fill()
- O9 m, { t1 z* K: g% @; ]( f - for i in range (5):) q; ^, Y) w# c
- turtle.forward(20)& E7 P t% u2 E4 g. t
- turtle.left(144)* D* c' ?# b: S9 E
- turtle.end_fill()/ G. b, i9 }" l7 q+ V& ]8 @
- turtle.hideturtle() # 隐藏小海龟# A+ R0 F9 V( A7 i
- turtle.done()
复制代码 7 \$ k0 A. p9 U) L6 P2 p$ O% _8 g
在画完第四颗小五角星以后,我们的工作还没有做完,turtle 默认让海龟的图标显示出来,当我们国旗画完以后,应该将这个图标隐藏,hideturtle方法就是用来隐藏海龟的。
2 Q6 P1 t+ f, k
$ n5 l) ] n; V+ q7 y$ z/ M最后,我们需要加上done方法表示绘制完成。这样我们的国旗就停留在屏幕上了。 `8 [9 J; U: f' ^$ c
. _# L; B, B; m" J+ O; U+ C" I6 }
; Z; m% ?2 J0 @ G) F
$ ~- I& P. V" @% G7 b以上就是使用turtle绘制国旗的案例,在这个案例中5颗五角星的绘制流程其实是一样的,只是五角星的大小和坐标有所不同。但是我们使用了5个循环来做,这种做法是很“笨“的,其实我们可以只使用1个循环,通过参数(传递坐标值,和绘制大小的值)的形式来完成国旗的绘制。想一想,你会怎么优化Python的代码,用1个循环来绘制国旗呢?再想一想,你还可以怎样给这个国旗加上旗杆呢?
7 m# }4 {( a6 o# B- `0 z* Z% n; V! N5 I
程序运行后的效果图如下:, g) W' q7 R. m. i4 E
$ y5 z. H$ D3 e
3 ^' l1 G. l2 I. F x. w$ {6 A4 U" M& L v! o* X( p
最后完整源代码如下:. S$ d9 ~+ Z' o& Q
- # -*- coding: utf-8 -*-
3 i# }& M" |1 \ - """
; ? i% `% A' U7 i/ e$ q9 T - @Team: 新大榭论坛
U+ H6 c" P3 t - @Author: 张黎斌
3 k1 O# E3 U- y8 [) N5 o - @update: 2021-09-18
$ H8 y! a z8 H* p5 L - @Version: v1.0( f2 [2 M. h" Y3 H/ ^" S
- @BBSid: 7749-01-01
2 q3 v/ {+ w9 l6 k6 [. k$ p3 {" s. ] - @Level: B( G" w. _6 N8 x- X+ G" i
- ------------------------------------------------------------------+
# q+ M# c! Y1 u" W+ [+ O - 【说明】:用 Python turtle 画一面国旗,庆祝祖国72华诞* }7 @/ s3 l& i x! k, c: U+ |: z: o
- ------------------------------------------------------------------+$ q" U# o; Y- Q
- """/ D# p; s0 ?; E( h/ M7 p
- print("") 9 o; {. B! t4 r) x3 J
- print("////////////////////////////////////////////////////////////")4 Z5 H# q% Q& V2 C6 F( l& b
- print("// //")
e: n B! F5 W, P( f7 s' u" k( @ - print("// 新大榭Python文件启动程序(py文件双击) V1.4.21.0901 //")
3 s5 ?2 Y. |/ r3 T" V& |. L - print("// ------------------------------------------------------ //")
2 U+ N; u+ Z: ?8 w, \# e - print("// 新大榭Web实验室 http://lab.daxie.net.cn/ //")
- ?0 }, q. G$ [5 D8 H - print("// //") 0 ^: ?/ A( k8 B$ {5 J, g
- print("////////////////////////////////////////////////////////////")# H2 T% B0 f3 h$ W8 s+ A7 H: H$ l
- print("")
& W. Y2 m7 J! R) w) I - print("『用 Python turtle 画一面国旗』本题解答如下:")0 o' |* }, a8 L# j: X# x
- print("------------------------------------------------------------")
% k/ q9 U! ?* g; T - print(">>> ",end="")
0 L) h' s) g2 G8 N8 d% _ - 5 H- v1 X/ A3 f9 N, [: \/ {
- # 以下为主程序核心代码 ↓↓↓
- M/ {! S* z8 a6 U% _+ [ - "/////////////////////////////////////////////////////////////////"& g P4 e9 r) }1 a7 ^& K5 M- G/ ]
# e8 J" R! b5 u- import turtle # 导入turtle模块! c s. V2 K. w
- turtle.speed(10) # 设置画笔绘制速度
) l% m# R/ @8 C, K# s# ?- } - 9 Z& D4 O: v1 Q4 g/ Y) L
- # 国旗的四边, V& l8 _% g2 u; U4 ~6 |) n
- turtle.up()
2 R! I( m+ _$ S3 T - turtle.goto(-200, 200)+ M {1 D$ K& @; F8 g. `
- turtle.down()$ I9 v I" x0 Z: z
- turtle.begin_fill()
- I! w6 E& j5 Q5 D - turtle.fillcolor("red") # 填充色
8 }# K3 M* J. a+ C - turtle.pencolor("red") # 画笔颜色
% l4 |# h2 B+ \, W6 [% Z: ] - for i in range(2):
$ n& k. N6 I5 U1 T - turtle.forward(438) # 向前移动438
0 O" P9 u! Z- s+ t# z% C" L$ P4 F; Y - turtle.right(90) # 以角度单位向右90度转动, {* c k$ \( [4 @/ I
- turtle.forward(292) # 向前移动292
6 Y+ F0 V- V6 V5 f$ i; G! N- F0 _" J - turtle.right(90) # 以角度单位向右90度转动& Y; \; [: p1 F4 L i5 a- @. o7 s
- turtle.end_fill() # 结束四边的填充" j5 f0 T5 C; l, k s
- 5 x: x1 g; |0 O r: i1 Z5 m
- # 更改海龟的画笔颜色和填充色4 T8 I* A+ o9 W) ]: _0 W
- turtle.fillcolor('yellow') # 填充色
; ]" P7 Y. e2 C ]; A0 B; u - turtle.pencolor("yellow") # 画笔颜色
% A+ Q/ C0 k q Y C - : u5 g" m$ Y- v% U. i- q: P" \
- # 绘制大五角星, U$ E4 f2 c; `
- turtle.up() # 抬笔不绘制
1 q2 _7 U% {1 J% S( S" h& M - turtle.goto(-170, 145) # 画笔设置到起始位置7 G/ L, n6 G1 j7 e
- turtle.down()
- Q$ t: e0 N0 X( O. |4 i - turtle.begin_fill()( U9 o: ?/ {2 [. J( x ^, ^& `
- for i in range(5): # 循环5次7 G/ z* q& ]& D' ?8 J# _
- turtle.forward(50) # 向前移动50* A& E; f# \4 `: m( v" U! f- {
- turtle.right(144) # 以角度单位向右转动
8 W" V% U" Q5 ]; e9 A# }0 q - turtle.end_fill() # 结束填充7 X: _) ^' x/ ^# q0 H
- & f# ]0 ^& Y' q3 k% a
- # 绘制第1颗副星
3 u/ q/ w; q$ \3 U# R - turtle.up()
$ m! a1 {- D+ P0 k, h" D - turtle.goto(-100,180)
) y2 `+ H" K" S$ _8 k0 w& i5 E - turtle.setheading(305)9 b! [3 C5 h) F I' Y4 w( [0 ?
- turtle.down()
/ F' B& y' x" Z2 Z - turtle.begin_fill()
# J) ^* g7 r5 R9 Q: l! l# U - for i in range (5):% V4 `2 T+ X0 B, _( k" K* @
- turtle.forward(20)
8 w; k6 y g) d" o2 X% J - turtle.left(144)
- a& c7 P) Q n: F - turtle.end_fill()1 S: Y/ ^ `( \4 Z+ H
# l3 Y6 o) Q( F- # 绘制第2颗副星) R" ^* X$ {/ }& r) ?( A, E+ W
- turtle.up()3 C& O7 i) J% i$ Q
- turtle.goto(-85,150)' ^# B, Q4 l/ J4 z
- turtle.setheading(30)6 [$ m/ J3 r3 e4 v; T4 @/ V# ^
- turtle.down()
0 j" D$ f9 Y* ]$ n0 ] - turtle.begin_fill()1 l" t y0 q0 c+ `
- for i in range (5):
9 |7 E, a" A# v2 ?3 Z/ X9 z4 K0 ^: f - turtle.forward(20); O1 t0 F3 B3 I' u1 r
- turtle.right(144)0 u! `$ j9 A* H3 E/ c( X; V6 z8 W
- turtle.end_fill()
% q; N2 A n, d) O- {; I+ ]# [ - : H, t& }) x- \3 J/ l, e
- # 绘制第3颗副星8 _" E) C& w) D7 l0 N+ j3 ^8 R
- turtle.up()
+ t, z: ]! |' t: D - turtle.goto(-85,120)
' K+ E& q; L7 A6 B( V - turtle.setheading(0)
F6 s( P% v( `! x. b2 H# J. m - turtle.down()/ u% z- Y( h Y1 S9 X4 h9 H
- turtle.begin_fill()
/ T1 H! `5 R6 A* E - for i in range (5):
) s, p3 D p8 B( x/ a6 i - turtle.forward(20)& C4 H! F. T1 G8 _
- turtle.right(144)# b2 E) z v+ c* E0 s
- turtle.end_fill()
- U. B' G. T% y* `
3 c6 Q7 P+ u2 M5 S- # 绘制第4颗副星
2 i/ G8 u1 K2 Q/ o3 x9 Q - turtle.up()
2 J+ J6 T7 i, F - turtle.goto(-100,100): D4 a' D ^" I4 W3 p* N8 N
- turtle.setheading(300)
: j/ u# X, d# x! @# K: F- { - turtle.down()1 p3 _5 T& b. M2 L* ]7 U7 A
- turtle.begin_fill()
2 O* J! }4 y, J' x% m% q5 ^ - for i in range (5):
& i( y8 V9 m4 ~9 G0 v - turtle.forward(20)
/ _$ y6 I% N$ ]/ u - turtle.left(144)- Q4 f/ M5 L, W
- turtle.end_fill()2 e( g1 n9 b- y9 ~: H; ^
- turtle.hideturtle() # 隐藏小海龟
- L% D6 t; q) ~! j; }9 f: ~. w - turtle.done(), H. A7 q M3 x X; |: \( f! l
3 b6 D% l! m# v* F* x/ _- "/////////////////////////////////////////////////////////////////"
4 x$ e- x2 A! m7 F5 E) a
8 A- y7 W' M L# h- # ↓↓↓ 以下代码为程序界面美化
( C; u: {2 W& v& d - print("") 1 ?0 P5 x: Q& m1 K3 Y! `
- print("////////////////////////////////////////////////////////////")' d( b9 O7 S+ m/ l/ o2 {* R
- : o9 U$ k* [) G0 T1 V
- # ↓↓↓ 以下代码优化与答题无关,可屏蔽IDLE程序意外退出!' D. t O* @2 V
- print("") * g5 |8 n# A5 ]( o$ g2 Z
- print("┏----------------------------┓")$ @! m; V" t# F7 I/ Q v% \0 A
- print("┣--- 按下回车键即退出程序 ---┫")$ f, t5 H" z. K. h
- print("┗----------------------------┛")
) @7 u: u! d' X) Y- n5 b1 [4 P - print("")
' G7 u, L9 |) E" G- Z* w - input(">>> ")
复制代码 |
|