-
-
Save gsw945/6ec3cf6aeffdc2175d2a9d7f51a99705 to your computer and use it in GitHub Desktop.
Python Logo using bezier curves and the turtle module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import turtle | |
import math | |
def lerp(a, b, t): | |
"""Linear interpolation function. returns a when t==0, returns b when t==1 | |
and linearly interpolates for values inbetween""" | |
return (a * (1 - t)) + (b * t) | |
def lerp2(a, b, t): | |
"""2-dimensional linear interpolation function""" | |
return lerp(a[0], b[0], t), lerp(a[1], b[1], t) | |
def bezier(p0, p1, p2, p3, t): | |
"""calculate coordinates for point t on the bezier defined by p1-p4 | |
see http://upload.wikimedia.org/wikipedia/commons/thumb/d/db/B%C3%A9zier_3_big.gif/240px-B%C3%A9zier_3_big.gif | |
for a visual explanation""" | |
c1 = lerp2(p1, p2, t) | |
c2 = lerp2(p0, c1, t) | |
c3 = lerp2(c1, p3, t) | |
c4 = lerp2(c2, c3, t) | |
return c4 | |
def stepturtle(turtle, x, y): | |
"""step turtle so it ends at x/y""" | |
while turtle.distance(x, y)>0.5: | |
rotdif = turtle.towards(x, y) # see how much we need to turn | |
turn = rotdif - turtle.heading() | |
if turn > 180: | |
turtle.left(turn-360) | |
elif turn < -180: | |
turtle.left(turn+360) | |
else: | |
turtle.left(turn) # turn | |
distance = turtle.distance(x, y) # see how far we need to go | |
turtle.forward(distance) # go | |
def turtlebezier(turtle, p0, p1, p2, p3): | |
"""walk the turtle along a bezier""" | |
t = 0 | |
while t < 1: | |
t += 0.001 | |
x, y = bezier(p0, p1, p2, p3, t) # calculate position for that point on the bezier | |
# only step if the distance is bigger than one pixel. | |
if turtle.distance(x, y) >= 1: | |
stepturtle(turtle, x, y) # move turtle to position | |
def turtlecircle(turtle, r, x, y): | |
"""walk the turtle along a circle""" | |
# calculate circumference, rounded up to the nearest integer. | |
circumference = int(math.ceil(r*2*math.pi)) | |
# calculate the size of a step along the circle in radians | |
stepsize = math.pi*2/circumference | |
for i in range(circumference+1): | |
# calculate position along the circle | |
cx = x + math.cos(i*stepsize) * r | |
cy = y + math.sin(i*stepsize) * r | |
# move there | |
stepturtle(turtle, cx, cy) | |
for flipx, flipy, color in ((-1, 1, "#366fa0"), (1, -1, "#ffd045")): | |
turtle.penup() | |
stepturtle(turtle, 0 * flipx, 4 * flipy) | |
turtle.pendown() | |
turtle.fillcolor(color) | |
turtle.color(color) | |
turtle.begin_fill() | |
turtlebezier(turtle, (-28 * flipx, 4 * flipy), (-43 * flipx, 5 * flipy), | |
(-56 * flipx, 16 * flipy), (-56 * flipx, 29 * flipy)) | |
turtlebezier(turtle, (-56 * flipx, 88 * flipy), (-56 * flipx, 108 * flipy), | |
(-60 * flipx, 118 * flipy), (0 * flipx, 118 * flipy)) | |
turtlebezier(turtle, (0 * flipx, 118 * flipy), (60 * flipx, 118 * flipy), | |
(57 * flipx, 108 * flipy), (57 * flipx, 88 * flipy)) | |
stepturtle(turtle, 57 * flipx, 65 * flipy) | |
stepturtle(turtle, 0 * flipx, 65 * flipy) | |
stepturtle(turtle, 0 * flipx, 57 * flipy) | |
turtlebezier(turtle, (80 * flipx, 57 * flipy), (100 * flipx, 57 * flipy), | |
(118 * flipx, 60 * flipy), (118 * flipx, 0 * flipy)) | |
turtlebezier(turtle, (118 * flipx, 0 * flipy), (118 * flipx, -60 * flipy), | |
(103 * flipx, -55 * flipy), (83 * flipx, -55 * flipy)) | |
stepturtle(turtle, 65 * flipx, -55 * flipy) | |
turtlebezier(turtle, (65 * flipx, -30 * flipy), (65 * flipx, -11 * flipy), | |
(48 * flipx, 4 * flipy), (29 * flipx, 4 * flipy)) | |
stepturtle(turtle, 0 * flipx, 4 * flipy) | |
turtle.end_fill() | |
turtle.fillcolor("white") | |
turtle.color("white") | |
turtle.penup() | |
stepturtle(turtle, 33 * flipx, 91 * flipy) | |
turtle.pendown() | |
turtle.begin_fill() | |
turtlecircle(turtle, 11, 33 * flipx, 91 * flipy) | |
turtle.end_fill() | |
turtle.hideturtle() | |
turtle.done() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment