1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > python画椭圆的逻辑_除了冲压外 如何在Python龟图形中绘制椭圆?

python画椭圆的逻辑_除了冲压外 如何在Python龟图形中绘制椭圆?

时间:2021-11-12 11:04:40

相关推荐

python画椭圆的逻辑_除了冲压外 如何在Python龟图形中绘制椭圆?

我正在尝试用Python乌龟图形绘制字母" O"。要提示" O"的图形,可通过按键调用其功能。这是我到目前为止的内容:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20def 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")

用户可以使用另一个按键提示的对话框,在10-170之间的任意值中更改letter_height和letter_width变量。现在,如果letter_height = 170和letter_width = 10,则出现" O",如下所示:

但是,如果将其与" H"(可以由我的程序绘制的另一个字母)进行比较,则可以很容易地看出它们之间没有任何比例关系:

我想做的是为" O"绘制一个椭圆,其垂直半径等于letter_height且其水平半径等于letter_width,这样当letter_width增大时," O"将变短,并且letter_height增加时,该值越高。问题是,我真的不知道该怎么做!我听说可以盖章,但是我真的不想使用图章方法,因为它的动画看起来不那么吸引人。另外,当我尝试将letter_height和letter_width值映射到它时,由于某种原因,它会覆盖整个屏幕!

总之,我想知道如何在乌龟图形中绘制一个椭圆,该椭圆可以像一个圆一样进行操作(更改椭圆的半径长度,更改椭圆的范围等)。我不想使用turtle.stamp()方法,因此除了在画布上盖印椭圆以外,还有什么方法可以绘制椭圆形?任何帮助深表感谢!

您是说动态操纵吗? 还是只是参数化?

@ Peter Wood好,圆是参数化的还是动态操纵的?

我认为您必须用很多直线来近似它。

该图显示了一个胶囊,顺便说一句,不是椭圆形

除了@cdlanes答案,这看起来很有趣:/coordcirclealgorithm.html

在测试@ moomoomoo309的椭圆代码并发现问题后(错误位置,宽度和高度上的打印与参数不匹配,忽略了乌龟标题,因此无法打印倾斜的椭圆,标题无法跟踪绘图,不会使笔处于原始状态等),我决定尝试编写自己的。

我选择使用turtle.circle()作为模型,以相对于现有乌龟位置和方向绘制椭圆的位置为准,允许用户更改步长(即制作其他不规则多边形),保持笔的状态和位置开始,等等。这就是我的想法(我打算使用self代替turtle或pen,因为我打算将其安装为方法):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

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

(可选)通过向现有对象实例添加方法,将此方法添加到乌龟中:

1

2

3

4from functools import partial

yertle = turtle.Turtle()

yertle.ellipse = partial(ellipse, yertle)

演示代码显示我们可以使用turtle.ellipse()绘制的所有新形状:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35if __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 a la turtle.circle(),但是无法使其在任意范围内正常工作(即,您可以在相同范围内两次调用turtle.ellipse()并使它继续运行弯曲的地方),所以我又把它留了一天。

将我的答案带回OP的原始问题,我们现在可以执行以下操作:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29import 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:

我很确定这是可行的,宽度/ 180和高度/ 180的180可能会关闭。

1

2

3

4

5

6

7

8

9

10

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

此代码不会在x,y处绘制椭圆; 它不会将其绘制为width宽或height高。 width180和height180表达式中的180可能应该接近60,并且实际上根本不应该存在,除了您使用penX +=代替penX +(同上penY +=)。 此代码忽略了乌龟的当前航向,因此您无法绘制对角椭圆。 香港专业教育学院试图我自己的ellipse()的实现来解决这些问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。