Python海龟图形除了冲压之外如何画椭圆?

问题描述 投票:0回答:2

我正在尝试用Python乌龟图形画一个字母“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 之间的任何值。现在,“O”如下所示,如果
letter_height = 170
&
letter_width = 10
:

但是,如果你将其与“H”(我的程序可以绘制的另一个字母)进行比较,你可以很容易地看到它们不成比例:

我想做的是为“O”画一个椭圆,其垂直半径等于

letter_height
,水平半径等于
letter_width
,这样“O”就会随着
letter_width
的增加而变短,随着
letter_height
的增加而更高。问题是,我真的不知道该怎么做!我听说你可以盖章,但我真的想使用盖章方法,因为它的动画看起来不太吸引人。另外,当我尝试将我的
letter_height
letter_width
值映射到它时,由于某种原因它覆盖了整个屏幕!

总之,我想知道如何在海龟图形中绘制椭圆,可以像圆形一样操作(更改椭圆的半径长度,更改椭圆的范围等)。我不想使用turtle.stamp()

方法,那么除了在画布上印上一个椭圆之外,还有什么方法可以绘制椭圆吗?非常感谢任何帮助!

python python-3.x turtle-graphics ellipse
2个回答
2
投票
测试@moomoomoo309的椭圆代码并发现问题后(打印在错误的位置,宽度和高度与参数不匹配,忽略海龟标题,因此无法打印倾斜的椭圆,标题不跟踪绘图,不将笔留在原始位置)状态等)我决定尝试编写自己的。

我选择使用

turtle.circle()

 作为相对于现有海龟位置和标题绘制椭圆的模型,允许用户更改步骤(即制作其他不规则多边形),将画笔状态和位置保留在这就是我想到的(我使用 
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()
(可选)按照

向现有对象实例添加方法将此方法添加到我们的乌龟中

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()

示例输出

我尝试实现

extent

 
turtle.circle()
 但无法让它在任意范围内正常工作(即,您可以以相同的范围调用 
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:


0
投票
我很确定这会起作用,但宽度/180 和高度/180 的 180 可能会关闭。

from math import sin,cos,pi def ellipse(pen, x, y, width, height): pen.penup() pen.goto(x + width / 2, height) pen.pendown() penX, penY = pen.pos() for i in range(0, 360): penX += cos(i*pi/180)*width/180 penY += sin(i*pi/180)*height/180 pen.goto(penX, penY) pen.penup()
    
© www.soinside.com 2019 - 2024. All rights reserved.