Amit Jaiswal
Amit Jaiswal

Reputation: 1015

How to draw smily (arc) using python turtle

I want to draw a smily using python turtle. Circle extent will be 120. I am trying following

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

Problem is smile part. How to draw a face smile?

Upvotes: 1

Views: 26172

Answers (3)

Lochan
Lochan

Reputation: 1

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)

Upvotes: 0

cdlane
cdlane

Reputation: 41872

You can do the smile (and smiley face) with the commands that the turtle module provides. The key to getting your arc (of a circle) drawn correctly lies in the combination of goto() and setheading(), see below:

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

I'm not going to claim to have mastered positioning arcs, I'm still doing too much trial and error, but it is possible if you take the time to learn how the turtle operators work.

Have a nice day!

Upvotes: 4

Bakuriu
Bakuriu

Reputation: 101919

The turtle module does not provide advanced methods to drow arcs of circles or parabolas, however it isn't hard to come up with the right equations.

A circle C with origin at (x0, y0) and radius r is described by the equation:

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

We can expand this to get:

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

Now we can take for example the y as variable and obtain the second degree equation:

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

Let d = x^2-2x0·x+x0^2+y0^2-r^2. We can solve this using the usual formula:

y1 = (2y0 + sqrt(4y0^2 - 4d))/2 = y0 + sqrt(y0^2 - d)
y2 = (2y0 - sqrt(4y0^2 - 4d))/2 = y0 - sqrt(y0^2 - d)

So now you can write down a function that, given the coordinates of the center of the circle and the radius, and the value for x it returns the coordinate y and use these coordinates to move the turtle:

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

As in:

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

By choosing one of the two coordinates returned you choose whether to draw the "upper" or "lower" arc.

to draw a smile you simply have to come up with two circles one smaller and a larger one but with the center slightly above the previous one so that they have that kind of intersection.

So you have to choose a circle C1 centered in x0, y0 with radius r and a circle C2 centered in x0, y0+K with radius R > r. Note that C2's center is vertically aligned with C1 center (hence the same x coordinate for the center) but it is above it (note: I'm not sure of y-axis orientation so the +K might be -K...)

To find the intersections you have to solve the system of their equations:

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

Now subtracting the second equation from the first you get:

(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

Where you get:

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

And you can substitute the y in one of the circle equations to obtain the xs corresponding to such y. Then you know which x to draw using find_circle_coord.

If you want to make the mouth more open you could use a circle and a parabola. To find the y value of a point on a parabole it's easy:

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

Or you could use the form of equation of a parabola given its vertex V = (xv, yv):

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

where a controls how steep the parabola is.

Upvotes: 2

Related Questions