如何使用 python 乌龟画笑脸(弧形)

How to draw smily (arc) using python turtle

我想用 python 乌龟画笑脸。圆形范围将为 120。 我正在尝试关注

import turtle
turtle.circle(100)
turtle.up()
turtle.goto(0, 30)
turtle.down()
turtle.circle(40, 120)

问题是微笑部分。怎么画脸上的笑容?

turtle 模块不提供绘制圆弧或抛物线的高级方法,但不难得出正确的方程。

原点在 (x0, y0) 且半径 r 的圆 C 由等式描述:

(x-x0)^2 + (y-y0)^2 = r^2

我们可以展开这个得到:

x^2 -2x·x0 + x0^2 + y^2 -2y·y0 + y0^2 - r^2 = 0

现在我们可以以y为例,得到二次方程:

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。我们可以使用通常的公式解决这个问题:

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 它的值 returns 坐标 y并使用这些坐标移动乌龟:

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

如:

>>> # bob is a turtle
>>> bob.pendown()
>>> for x in range(-50, 50):
...     y1, _ = find_circle_coord(0, 0, 100, x)
...     bob.goto(x, y1)

通过选择返回的两个坐标之一,您可以选择是绘制 "upper" 还是 "lower" 弧线。

要画一个微笑,你只需想出两个圆圈,一小一大,但中心略高于前一个圆圈,这样它们就有那种交集。

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

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

(x-x0)^2 + (y-y0)^2-r^2 = 0
(x-x0^2) + (y-y0-K)^2-R^2 = 0

现在用第一个方程减去第二个方程得到:

(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

从哪里获得:

y = (K^2 +2K·y0 +r^2 -R^2)/(2K)

并且可以将其中一个圆方程中的y代入,得到该y对应的x。然后你知道使用 find_circle_coord.

绘制哪个 x

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

def find_parabola_coord(a, b, c, x):
    return a*x**2 + b*x + c

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

y - yv = a(x - xv)^2

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

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

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

我不会声称自己已经掌握了定位弧线,我仍在反复试验,但如果您花时间学习 turtle operators 的工作原理,这是可能的。

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)