我正在尝试用 Python turtle 图形绘制字母“O”。为了提示绘制“O”,可以通过按键调用其功能。这是我到目前为止所拥有的:
def draw_O():
# Draw an O
penup()
forward(letter_height/4)
pendown()
forward(letter_width/2)
circle(letter_height/4, 90)
forward(letter_height/2)
circle(letter_height/4, 90)
forward(letter_width/2)
circle(letter_height/4, 90)
forward(letter_height/2)
circle(letter_height/4, 90)
forward(letter_width/2)
penup()
forward(space_width + letter_height/4)
pendown()
onkey(draw_O, "o")
用户可以使用由另一个按键提示的对话框来更改 letter_height
和 letter_width
变量,范围为 10-170 之间的任何值。现在,如果 letter_height = 170
& letter_width = 10
,则“O”如下所示:
但是,如果你将其与“H”(我的程序可以绘制的另一个字母)进行比较,你可以很容易地看到它们不成比例:
我想要做的是为“O”画一个椭圆,其垂直半径等于letter_height
,其水平半径等于letter_width
,这样“O”会随着 letter_width
的增加而变短,并随着 letter_height
的增加而变高。问题是,我真的不知道该怎么做!我听说你可以盖章,但我真的确实不想想要使用盖章方法,因为它的动画看起来不太吸引人。另外,当我尝试将 letter_height
和 letter_width
值映射到它时,由于某种原因它覆盖了整个屏幕!
总之,我想知道如何在 turtle 图形中绘制一个椭圆可以像圆形一样进行操作(更改椭圆的半径长度,更改椭圆的范围等)。我不想想要使用turtle.stamp()
方法,那么除了在上面印上一个椭圆之外,还有什么方法可以绘制椭圆吗? Canvas ?非常感谢任何帮助!
最佳答案
测试@moomoomoo309的椭圆代码并发现问题后(打印在错误的位置,宽度和高度与参数不匹配,忽略 turtle 标题,因此无法打印倾斜的椭圆,标题不跟踪绘图,不离开笔在原始状态等)我决定尝试编写自己的。
我选择使用turtle.circle()
作为相对于现有 turtle 位置和方向绘制椭圆的模型,允许用户更改步骤(即制作其他步骤)不规则多边形),保留笔的状态和位置,等等。这就是我想出的(我使用 self
而不是 turtle
或 pen
因为我打算将其作为一种方法安装):
import turtle
import math
def ellipse(self, x_radius, y_radius, steps=60):
down = self.isdown() # record pen state for restoration later
if not down:
self.pendown()
heading_radians = math.radians(self.heading())
theta_radians = -math.pi / 2
extent_radians = 2 * math.pi
step_radians = extent_radians / steps
extent_radians += theta_radians
x_center, y_start = self.position()
y_center = y_start + y_radius
cos_heading, sin_heading = math.cos(heading_radians), math.sin(heading_radians)
while True:
x, y = x_center + math.cos(theta_radians) * x_radius, y_center + math.sin(theta_radians) * y_radius
# readjust x & y to set the angle of the ellipse based on the original heading of the turtle
x, y = x - x_center, y - y_start
x, y = x * cos_heading - y * sin_heading, x * sin_heading + y * cos_heading
x, y = x + x_center, y + y_start
self.setheading(self.towards(x, y)) # turtle faces direction in which ellipse is drawn
self.goto(x, y)
if theta_radians == extent_radians:
break
theta_radians = min(theta_radians + step_radians, extent_radians) # don't overshoot our starting point
self.setheading(self.towards(x_center, y_start)) # set correct heading for the next thing we draw
if not down: # restore pen state on return
self.penup()
(可选)将此方法添加到我们的 turtle 中 Adding a Method to an Existing Object Instance :
from functools import partial
yertle = turtle.Turtle()
yertle.ellipse = partial(ellipse, yertle)
演示代码显示我们可以使用turtle.ellipse()绘制的所有新形状
:
if __name__ == "__main__":
from functools import partial
yertle = turtle.Turtle()
yertle.ellipse = partial(ellipse, yertle)
import random
yertle.speed("fastest")
yertle.hideturtle()
yertle.penup()
screen = turtle.Screen()
for _ in range(75):
radius = random.randint(10, 50)
yertle.setheading(random.randint(0, 360))
yertle.setx(random.randint(-screen.window_width()//2 + radius * 2, screen.window_width()//2 - radius * 2))
yertle.sety(random.randint(-screen.window_height()//2 + radius + 2, screen.window_height()//2 - radius * 2))
yertle.color((random.random(), random.random(), random.random()), (random.random(), random.random(), random.random()))
flag = random.choice([True, False, False])
if flag:
yertle.begin_fill()
yertle.ellipse(radius, radius / 0.5 + random.random() * 3, steps=random.choice([3, 4, 5, 6, 7, 8, 60, 60, 60]))
if flag:
yertle.end_fill()
screen.exitonclick()
示例输出
我尝试按照 turtle.circle()
实现 extent
但无法让它在任意范围内正常工作(即以这种方式您可以以相同的范围调用turtle.ellipse()
两次,并让它在停止的地方继续曲线),所以我把它留到另一天。
将我的答案带回OP最初的问题,我们现在可以这样做:
import turtle
import math
def ellipse(self, x_radius, y_radius, steps=60):
# ...
def draw_O():
# Draw an O
turtle.penup()
turtle.forward(letter_height/4)
turtle.pendown()
ellipse(turtle, letter_width, letter_height)
turtle.penup()
turtle.forward(space_width + letter_height/4)
turtle.pendown()
letter_width = 10
letter_height = 170
space_width = 5
turtle.onkey(draw_O, "o")
turtle.listen()
turtle.done()
生成OP所需的基于瘦椭圆的字母O:
关于python - 除了冲压之外,如何在Python turtle graphics 中绘制椭圆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284958/