前言
我用Python实现了炫酷的3D玫瑰花!
Turtle画图
Turtle 是一个简单的图形库,可用于 Python 编程语言。它可以让你使用 Python 程序画出各种图形,包括线条、图案、几何图形等等。Turtle 的使用非常简单,特别适合初学者学习编程。
以下是关于 Turtle 的入门指南,介绍了 Turtle 的基本功能以及如何通过编程来控制 Turtle 画图。
安装 Turtle
import turtle
如果不报错,则说明你已经成功导入了 Turtle 库。
创建一个 Turtle 画布
在开始画图之前,你需要创建一个画布。使用以下代码来创建一个窗口和一个空白画布:
import turtle
# 创建画布
window = turtle.Screen()
# 创建一个空白画布
canvas = turtle.Turtle()
在这个示例中,我们首先导入了 Turtle 库。然后,使用 turtle.Screen()
创建一个名为 window
的 Turtle 窗口。接下来,我们使用 turtle.Turtle()
创建一个名为 canvas
的新画布,它位于窗口的中心。
移动 Turtle
现在,我们可以开始向画布绘制图形了。首先,让我们看看如何移动 Turtle。Turtle 通过向前或向后移动一定距离来画一条线。在开始之前,让我们先了解一下坐标系。在 Turtle 中,窗口的中心点是坐标原点(0,0),向右是正 X 轴方向,向上是正 Y 轴方向。坐标的单位是画布上的像素。
使用以下代码,让 Turtle 向右移动 50 个像素:
# 移动 Turtle 50 个像素
canvas.forward(50)
forward()
方法让 Turtle 向前移动一定距离,它的参数是像素数。现在,如果你在 Python 窗口中运行代码,你应该可以看到一个向右移动 50 像素的线。如果要向左移动,只需将参数改为负数:
# 向左移动 50 个像素
canvas.forward(-50)
使用 backward()
方法也可以让 Turtle 向后移动一定距离:
# 向后移动 50 个像素
canvas.backward(50)
除了向前和向后移动之外,还可以让 Turtle 向左或向右转动一定角度:
# 向左旋转 90 度
canvas.left(90)
# 向右旋转 45 度
canvas.right(45)
当然,你也可以使用 goto()
方法直接将 Turtle 移动到指定的坐标处:
# 将 Turtle 移动到坐标 (100, 100)
canvas.goto(100, 100)
绘制形状
除了直线以外,Turtle 还可以使用 circle()
方法绘制圆形:
# 绘制半径为 50 的圆形
canvas.circle(50)
circle()
方法的参数是圆的半径,如果要绘制椭圆,可以使用 shapesize()
方法:
# 绘制长半轴为 200,短半轴为 100 的椭圆
canvas.shapesize(200, 100)
当然,你也可以使用 begin\_fill()
和 end\_fill()
方法填充形状:
# 绘制一个黄色的圆形
canvas.color('yellow')
canvas.begin_fill()
canvas.circle(50)
canvas.end_fill()
线条属性
除了移动和绘制形状以外,你还可以设置 Turtle 的线条属性。以下是一些常用的属性:
-
pensize()
设置线条宽度 -
penup()
和pendown()
控制画笔的起始和结束状态 -
color()
设置画笔颜色-speed()
设置画笔移动速度
# 设置线条宽度为 5
canvas.pensize(5)
# 抬起画笔
canvas.penup()
# 移动到坐标 (50, 50)
canvas.goto(50, 50)
# 放下画笔
canvas.pendown()
# 设置画笔颜色为红色
canvas.color('red')
# 设置画笔移动速度为 10
canvas.speed(10)
示例代码
接下来,我们将使用 Turtle 画一个简单的正方形:
import turtle
# 创建画布和 Turtle 对象
window = turtle.Screen()
canvas = turtle.Turtle()
# 设置画笔宽度和颜色
canvas.pensize(5)
canvas.color('red')
# 画正方形
for i in range(4):
canvas.forward(100)
canvas.right(90)
# 显示窗口
turtle.done()
以上代码将创建一个名为 window
的窗口,创建一个名为 canvas
的 Turtle 对象。然后,我们设置了画笔的宽度和颜色。接下来,我们使用 for
循环绘制正方形的四个边。最后,使用 turtle.done()
显示窗口并等待用户关闭。
总结
Turtle 是一个简单的图形库,可用于 Python 编程语言。使用 Turtle,你可以使用 Python 程序画出各种图形,包括线条、图案、几何图形等等。通过本入门指南的介绍,你应该已经了解了 Turtle 的基本操作和功能,可以开始绘制自己的图形了。
玫瑰花
普通玫瑰花
完整程序
import turtle
turtle.Turtle().screen.delay(0)
# 设置初始位置
turtle.penup()
turtle.left(90)
turtle.fd(200)
turtle.pendown()
turtle.right(90)
# 花蕊
turtle.fillcolor("red")
turtle.begin_fill()
turtle.circle(10, 180)
turtle.circle(25, 110)
turtle.left(50)
turtle.circle(60, 45)
turtle.circle(20, 170)
turtle.right(24)
turtle.fd(30)
turtle.left(10)
turtle.circle(30, 110)
turtle.fd(20)
turtle.left(40)
turtle.circle(90, 70)
turtle.circle(30, 150)
turtle.right(30)
turtle.fd(15)
turtle.circle(80, 90)
turtle.left(15)
turtle.fd(45)
turtle.right(165)
turtle.fd(20)
turtle.left(155)
turtle.circle(150, 80)
turtle.left(50)
turtle.circle(150, 90)
turtle.end_fill()
# 花瓣1
turtle.left(150)
turtle.circle(-90, 70)
turtle.left(20)
turtle.circle(75, 105)
turtle.setheading(60)
turtle.circle(80, 98)
turtle.circle(-90, 40)
# 花瓣2
turtle.left(180)
turtle.circle(90, 40)
turtle.circle(-80, 98)
turtle.setheading(-83)
# 叶子1
turtle.fd(30)
turtle.left(90)
turtle.fd(25)
turtle.left(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(-80, 90)
turtle.right(90)
turtle.circle(-80, 90)
turtle.end_fill()
turtle.right(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(85)
turtle.left(90)
turtle.fd(80)
# 叶子2
turtle.right(90)
turtle.right(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(80, 90)
turtle.left(90)
turtle.circle(80, 90)
turtle.end_fill()
turtle.left(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(60)
turtle.right(90)
turtle.circle(200, 60)
turtle.mainloop()
程序分析
这段代码使用 Python 的 turtle 库绘制了一朵复杂的花朵。运行在 Python 解释器中,并使用 turtle.Turtle() 函数创建一个 Turtle 对象进行绘制。
首先设置初始位置,然后使用 turtle.penup() 和 turtle.pendown() 函数分别切换画笔状态为抬起和落下。接下来使用 turtle.circle() 函数和 turtle.fd() 函数绘制花瓣、叶子和花蕊等各个部分,并使用 turtle.fillcolor() 和 turtle.begin_fill() 函数设置填充颜色和启动填充。最后使用 turtle.end_fill() 函数结束填充。
整个过程中涉及到多次调用 turtle.circle() 函数绘制圆弧段,turtle.fd() 函数绘制直线段,turtle.left() 和 turtle.right() 函数控制方向,turtle.setheading() 函数设置朝向等。最后使用 turtle.mainloop() 函数保持绘画窗口的持久显示。
因为代码中使用了多个 turtle 库的函数,感性地理解需要一定的绘画知识和 Python 编程知识。如果对这些函数的使用和参数含义有疑问,可以查阅 turtle 库的官方文档或进行进一步学习。
立体玫瑰花
完整程序
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(projection='3d')
[x, t] = np.meshgrid(np.array(range(25)) / 24.0, np.arange(0, 575.5, 0.5) / 575 * 20 * np.pi + 4 * np.pi)
p = (np.pi / 2) * np.exp(-t / (8 * np.pi))
change = np.sin(15 * t) / 150
u = 1 - (1 - np.mod(3.3 * t, 2 * np.pi) / np.pi) ** 4 / 2 + change
y = 2 * (x ** 2 - x) ** 2 * np.sin(p)
r = u * (x * np.sin(p) + y * np.cos(p))
h = u * (x * np.cos(p) - y * np.sin(p))
c = plt.get_cmap('BuPu')
surf = ax.plot_surface(r * np.cos(t), r * np.sin(t), h, rstride=1, cstride=1, cmap=c, linewidth=0, antialiased=True)
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
plt.show()
程序分析
这段代码使用了 Python 的 matplotlib 库绘制了一个三维玫瑰花图形,其中利用了 numpy 库进行数学计算和生成网格点。
首先创建了一个 5x5 英寸大小的图形对象 fig,然后使用 add_subplot() 函数创建一个 3D 坐标系 ax。接下来生成网格点坐标 x 和 t,并使用这些坐标计算出平面参数 p 和变化值 change,以及空间坐标值 u、y、r 和 h。
然后使用 plt.get_cmap() 函数获取色图对象,并使用坐标值绘制出玫瑰花的曲面 surf。最后使用 set_xticks()、set_yticks() 和 set_zticks() 函数设置坐标轴的刻度标签,然后用 plt.show() 函数显示图形并保持窗口的持久显示。
整个过程中运用了 numpy 库的 meshgrid()、sin()、exp()、arange() 和 mod() 等函数,以及 matplotlib 库的 figure()、subplot()、plot_surface()、get_cmap()、set_xticks()、set_yticks() 和 set_zticks() 等函数,需要一定的数学计算和 Python 编程知识。
四季玫瑰花
完整程序
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
[x, t] = np.meshgrid(np.array(range(25)) / 24.0, np.arange(0, 575.5, 0.5) / 575 * 30 * np.pi - 4 * np.pi)
p = (np.pi / 2) * np.exp(-t / (8 * np.pi))
change = np.sin(20 * t) / 50
u = 1 - (1 - np.mod(3.3 * t, 2 * np.pi) / np.pi) ** 4 / 2 + change
y = 2 * (x ** 2 - x) ** 2 * np.sin(p)
r = u * (x * np.sin(p) + y * np.cos(p)) * 1.5
h = u * (x * np.cos(p) - y * np.sin(p))
# 可取颜色:'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu',
# 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Grays', 'Greens', 'Greens_r',
# 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r',
# 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r',
# 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu',
# 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r',
# 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r',
# 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r',
# 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm',
# 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r',
# 'gist_gray', 'gist_gray_r', 'gist_grey', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow',
# 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gist_yerg', 'gnuplot', 'gnuplot2',
# 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'grey', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet',
# 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma',
# 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer',
# 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain',
# 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis',
# 'viridis_r', 'winter', 'winter_r'
c = plt.get_cmap('gist_heat')
surf = ax.plot_surface(r * np.cos(t), r * np.sin(t), h, rstride=1, cstride=1, cmap=c, linewidth=0, antialiased=True)
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
plt.show()
程序分析
这段代码使用了 numpy 和 matplotlib 的库。它创建了一个三维玫瑰花,其中的点是通过一系列的数学运算计算得出的。
首先,用 np.meshgrid 创建了一个网格,包括 x 和 t 坐标。x 坐标是 0 到 1 的 25 个数,t 坐标是 0 到 30π,步长为 0.5,与它的指数和三角函数一起用于后面的计算。
接下来,通过一些数学公式计算出了一些新的值,如 p、change、u、y、r 和 h。它们分别是:
- p:计算一个正弦函数,用于后面的计算。
- change:计算一个正弦函数,用于后面的计算。
- u:计算一个双曲线函数,用于后面的计算。
- y:根据一些三角函数和指数计算 y 坐标的值。
- r:使用上述计算出的值得出一个极坐标的半径。
- h:使用上述计算出的值得出一个高度。
最后,使用 plt.get_cmap 获得了一个颜色映射,并将这些点绘制到了三维图形中。
该代码中的各项数学运算很复杂,但主要目的是创建一个有趣的、复杂的三维玫瑰花图形。
尾声
喜欢本期玫瑰花的小伙伴们给个爱心呗!