首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用python turtle绘制笑脸(弧线)

如何使用python turtle绘制笑脸(弧线)
EN

Stack Overflow用户
提问于 2016-05-01 15:47:19
回答 3查看 19.1K关注 0票数 1

我想用蟒龟画一个笑脸。圆范围将为120。我试着追随

代码语言:javascript
复制
import turtle
turtle.circle(100)
turtle.up()
turtle.goto(0, 30)
turtle.down()
turtle.circle(40, 120)

问题是微笑的部分。如何画出笑脸?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-01 16:18:29

turtle模块没有提供高级方法来绘制圆或抛物线的圆弧,但是要想出正确的方程并不难。

(x0, y0)为原点、半径为r的圆C可用下式描述:

代码语言:javascript
复制
(x-x0)^2 + (y-y0)^2 = r^2

我们可以将其扩展为:

代码语言:javascript
复制
x^2 -2x·x0 + x0^2 + y^2 -2y·y0 + y0^2 - r^2 = 0

现在我们可以将y作为变量,得到二次方程:

代码语言:javascript
复制
y^2 -2y0·y +(x^2-2x0·x+x0^2+y0^2-r^2) = 0

d = x^2-2x0·x+x0^2+y0^2-r^2来吧。我们可以使用通常的公式来解决这个问题:

代码语言:javascript
复制
y1 = (2y0 + sqrt(4y0^2 - 4d))/2 = y0 + sqrt(y0^2 - d)
y2 = (2y0 - sqrt(4y0^2 - 4d))/2 = y0 - sqrt(y0^2 - d)

所以现在你可以写一个函数,给定圆心的坐标和半径,以及x的值,它返回坐标y,并使用这些坐标来移动乌龟:

代码语言:javascript
复制
def find_circle_coord(x0, y0, r, x):
    d = x**2 - 2*x0*x + x0**2 + y0**2 - r**2
    D = y0**2 - d
    if D < 0:
        raise ValueError("Value for x is outside the circle!")
    return y0 - D**.5, y0 + D**.5

如下所示:

代码语言:javascript
复制
>>> # bob is a turtle
>>> bob.pendown()
>>> for x in range(-50, 50):
...     y1, _ = find_circle_coord(0, 0, 100, x)
...     bob.goto(x, y1)

通过选择返回的两个坐标中的一个,您可以选择是绘制“上”弧还是“下”弧。

要画一个微笑,你只需要画出两个圆圈,一个小一点,一个大一点,但圆心略高于前一个圆圈,这样它们就会有这样的交叉点。

所以你必须选择一个以x0, y0为中心、半径为r的圆C1和一个以x0, y0+K为中心、半径为R > r的圆C2。请注意,C2的中心与C1中心垂直对齐(因此中心的x坐标相同),但它在它的上方(注意:我不确定y-axis方向,因此+K可能是-K...)

要找到交叉点,你必须求解它们的方程组:

代码语言:javascript
复制
(x-x0)^2 + (y-y0)^2-r^2 = 0
(x-x0^2) + (y-y0-K)^2-R^2 = 0

现在从第一个方程中减去第二个方程:

代码语言:javascript
复制
(y-y0)^2 - (y-y0-K)^2 -r^2 + R^2 = 0
y^2 -2y·y0 +y0^2 - y^2 -y0^2 -K^2 +2y·y0 +2K·y -2K·y0 -r^2 + R^2 = 0
-K^2 +2K·y -2K·y0 -r^2 + R^2 = 0

从哪里可以得到:

代码语言:javascript
复制
y = (K^2 +2K·y0 +r^2 -R^2)/(2K)

并且您可以在其中一个圆方程中替换y,以获得与该y相对应的x。然后,您就知道使用find_circle_coord绘制哪个x了。

如果你想让嘴巴张得更大些,你可以用一个圆圈和一个抛物线。要找到抛物线上某个点的y值,很简单:

代码语言:javascript
复制
def find_parabola_coord(a, b, c, x):
    return a*x**2 + b*x + c

或者你可以使用抛物线方程的形式,给定它的顶点V = (xv, yv)

代码语言:javascript
复制
y - yv = a(x - xv)^2

其中a控制抛物线的陡峭程度。

票数 2
EN

Stack Overflow用户

发布于 2016-05-02 01:20:46

您可以使用turtle模块提供的命令来做微笑(和笑脸)。正确绘制(圆的)圆弧的关键在于goto()setheading()的组合,如下所示:

代码语言:javascript
复制
import turtle

turtle.up()
turtle.goto(0, -100)  # center circle around origin
turtle.down()

turtle.begin_fill()
turtle.fillcolor("yellow")  # draw head
turtle.circle(100)
turtle.end_fill()

turtle.up()
turtle.goto(-67, -40)
turtle.setheading(-60)
turtle.width(5)
turtle.down()
turtle.circle(80, 120)  # draw smile

turtle.fillcolor("black")

for i in range(-35, 105, 70):
    turtle.up()
    turtle.goto(i, 35)
    turtle.setheading(0)
    turtle.down()
    turtle.begin_fill()
    turtle.circle(10)  # draw eyes
    turtle.end_fill()

turtle.hideturtle()
turtle.done()

我不打算声称已经掌握了定位弧,我仍然在做太多的试验和错误,但如果你花时间学习海龟操作符是如何工作的,这是可能的。

票数 4
EN

Stack Overflow用户

发布于 2019-01-22 14:02:52

代码语言:javascript
复制
import turtle
bob = turtle.Turtle()
bob.circle(100)
bob.penup()
bob.goto(50,100)
bob.pendown()
bob.circle(10)
bob.penup()
bob.goto(-50,100)
bob.pendown()
bob.circle(10)
bob.penup()
bob.goto(0,50)
bob.pendown()
bob.circle(100,30)
bob.penup()
bob.goto(0,50)
bob.pendown()
bob.circle(0,-30)
bob.circle(100,-30)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36964337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档