Skip to content

Instantly share code, notes, and snippets.

@shinchu
Last active March 28, 2019 13:29
Show Gist options
  • Save shinchu/6f414002b5327c7a98e53d65eb953cd4 to your computer and use it in GitHub Desktop.
Save shinchu/6f414002b5327c7a98e53d65eb953cd4 to your computer and use it in GitHub Desktop.
Drawing Bézier curves with DrawBot
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
p0 = np.array([100, 100])
p1 = np.array([200, 450])
p2 = np.array([450, 100])
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, r])
coord_margin = np.array([10, d*3])
stroke(0)
fill(0)
font('Input Mono Condensed', 10)
for i, point in enumerate([p0, p1, p2]):
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
text("({}, {})".format(point[0], point[1]), point-coord_margin, align="right")
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b2_01.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
p0 = np.array([100, 100])
p1 = np.array([200, 450])
p2 = np.array([450, 100])
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, r])
coord_margin = np.array([10, d*3])
stroke(0.6)
fill(0.6)
font('InputMonoCondensed Light', 10)
for i, point in enumerate([p0, p1, p2]):
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
text("({}, {})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw additional points according to t
for i in range(1, 5, 1):
t = i/5
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
# Draw lines
stroke(0.6)
fill(0.6)
line(p01, p12)
# Draw points and notes
stroke(0)
fill(0)
for j, point in enumerate([p01, p12]):
oval(*(point-r), d, d)
text("P{}{}{}".format(j, j+1, i), point-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b2_02.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
p0 = np.array([100, 100])
p1 = np.array([200, 450])
p2 = np.array([450, 100])
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, r])
coord_margin = np.array([10, d*3])
font('InputMonoCondensed Light', 10)
for i, point in enumerate([p0, p1, p2]):
stroke(0.6)
fill(0.6)
oval(*(point-r), d, d)
if point is not p1:
stroke(None)
fill(None)
text("P{}".format(i), point-notes_margin, align="right")
text("({}, {})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw additional points according to t
o = p0
t_range = [0, 6]
for i in range(*t_range, 1):
t = i/(t_range[1]-1)
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
# Draw lines
stroke(0.6)
fill(0.6)
line(p01, p12)
# Draw points and notes
stroke(0.6)
fill(0.6)
if (i == t_range[0]) or (i == t_range[1]-1):
stroke(None)
fill(None)
for j, point in enumerate([p01, p12]):
oval(*(point-r), d, d)
text("P{}{}{}".format(j, j+1, i), point-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw points on bezier curve
p = p01 + t*(p12 - p01)
stroke(0)
fill(0)
oval(*(p-r), d, d)
text("P({})".format(t), p-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(p[0], p[1]), p-coord_margin, align="right")
line(o, p)
o = p
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b2_03.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size and frames
CANVAS = 500
fps = 50
seconds = 3
total_frames = fps * seconds
duration = 1/fps
# Define control points
p0 = np.array([100, 100])
p1 = np.array([200, 450])
p2 = np.array([450, 100])
for frame in range(total_frames):
newPage(CANVAS, CANVAS)
if frame == total_frames - 1:
frameDuration(1)
else:
frameDuration(duration)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
d = 5
r = d/2
notes_margin = np.array([10, r])
coord_margin = np.array([10, d*3])
font('InputMonoCondensed Light', 10)
# Draw control points and notes
for i, point in enumerate([p0, p1, p2]):
stroke(0.6)
fill(0.6)
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
text("({}, {})".format(point[0], point[1]), point-coord_margin, align="right")
o = p0
t_range = [0, frame+1]
for i in range(*t_range, 1):
t = i/(total_frames-1)
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
# Draw bezier curve
p = p01 + t*(p12 - p01)
stroke(0)
fill(0)
line(o, p)
o = p
text("t={:.4f}".format(t), (CANVAS-60, CANVAS-20), align="left")
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b2_04.gif'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
q0 = np.array([100, 100])
q1 = np.array([200, 450])
q2 = np.array([450, 100])
p0 = q0
p1 = q0 + (q1-q0) * (2/3)
p2 = q2 + (q1-q2) * (2/3)
p3 = q2
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
line(p2, p3)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, -r])
coord_margin = np.array([10, d*2])
stroke(0)
fill(0)
font('Input Mono Condensed', 10)
for i, point in enumerate([p0, p1, p2, p3]):
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b3_01.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
q0 = np.array([100, 100])
q1 = np.array([200, 450])
q2 = np.array([450, 100])
p0 = q0
p1 = q0 + (q1-q0) * (2/3)
p2 = q2 + (q1-q2) * (2/3)
p3 = q2
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
line(p2, p3)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, -r])
coord_margin = np.array([10, d*2])
stroke(0.6)
fill(0.6)
font('InputMonoCondensed Light', 10)
for i, point in enumerate([p0, p1, p2, p3]):
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw additional points according to t
for i in range(1, 5, 1):
t = i/5
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
p23 = p2 + t*(p3-p2)
# Draw lines
stroke(0.6)
fill(0.6)
line(p01, p12)
line(p12, p23)
# Draw points and notes
stroke(0)
fill(0)
for j, point in enumerate([p01, p12, p23]):
oval(*(point-r), d, d)
# text("P{}{}{}".format(j, j+1, i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b3_02.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
q0 = np.array([100, 100])
q1 = np.array([200, 450])
q2 = np.array([450, 100])
p0 = q0
p1 = q0 + (q1-q0) * (2/3)
p2 = q2 + (q1-q2) * (2/3)
p3 = q2
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
line(p2, p3)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, -r])
coord_margin = np.array([10, d*2])
font('InputMonoCondensed Light', 10)
for i, point in enumerate([p0, p1, p2, p3]):
stroke(0.6)
fill(0.6)
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw additional points according to t
t_range = [0, 6]
for i in range(*t_range, 1):
t = i/(t_range[1]-1)
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
p23 = p2 + t*(p3-p2)
# Draw lines
stroke(0.6)
fill(0.6)
line(p01, p12)
line(p12, p23)
if (i == t_range[0]) or (i == t_range[1]-1):
stroke(None)
fill(None)
for j, point in enumerate([p01, p12, p23]):
oval(*(point-r), d, d)
# text("P{}{}{}".format(j, j+1, i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw lines and points
p0112 = p01 + t*(p12 - p01)
p1223 = p12 + t*(p23 - p12)
stroke(0)
fill(0)
line(p0112, p1223)
for point in [p0112, p1223]:
oval(*(point-r), d, d)
# text("P({})".format(t), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(p[0], p[1]), p-coord_margin, align="right")
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b3_03.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size
CANVAS = 500
# Define control points
q0 = np.array([100, 100])
q1 = np.array([200, 450])
q2 = np.array([450, 100])
p0 = q0
p1 = q0 + (q1-q0) * (2/3)
p2 = q2 + (q1-q2) * (2/3)
p3 = q2
newPage(CANVAS, CANVAS)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
line(p2, p3)
# Draw points and notes
d = 5
r = d/2
notes_margin = np.array([10, -r])
coord_margin = np.array([10, d*2])
font('InputMonoCondensed Light', 10)
for i, point in enumerate([p0, p1, p2, p3]):
stroke(0.6)
fill(0.6)
oval(*(point-r), d, d)
if (point is not p1) and (point is not p2):
stroke(None)
fill(None)
text("P{}".format(i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw additional points according to t
o = p0
t_range = [0, 6]
for i in range(*t_range, 1):
t = i/(t_range[1]-1)
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
p23 = p2 + t*(p3-p2)
# Draw lines
stroke(0.6)
fill(0.6)
line(p01, p12)
line(p12, p23)
if (i == t_range[0]) or (i == t_range[1]-1):
stroke(None)
fill(None)
for j, point in enumerate([p01, p12, p23]):
oval(*(point-r), d, d)
# text("P{}{}{}".format(j, j+1, i), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
# Draw lines and points
p0112 = p01 + t*(p12 - p01)
p1223 = p12 + t*(p23 - p12)
stroke(0.6)
fill(0.6)
line(p0112, p1223)
if (i == t_range[0]) or (i == t_range[1]-1):
stroke(None)
fill(None)
for point in [p0112, p1223]:
oval(*(point-r), d, d)
# text("P({})".format(t), point-notes_margin, align="right")
# text("({:.0f}, {:.0f})".format(p[0], p[1]), p-coord_margin, align="right")
p = p0112 + t*(p1223 - p0112)
stroke(0)
fill(0)
oval(*(p-r), d, d)
text("P({})".format(t), p-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(p[0], p[1]), p-coord_margin, align="right")
line(o, p)
o = p
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b3_04.png'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
# Load external packages
import sys
import os
mod_dir = os.path.expanduser('~/.pyenv/versions/3.6.4/lib/python3.6/site-packages')
if mod_dir not in sys.path:
sys.path.append(mod_dir)
import numpy as np
# Define canvas size and frames
CANVAS = 500
fps = 50
seconds = 3
total_frames = fps * seconds
duration = 1/fps
# Define control points
q0 = np.array([100, 100])
q1 = np.array([200, 450])
q2 = np.array([450, 100])
p0 = q0
p1 = q0 + (q1-q0) * (2/3)
p2 = q2 + (q1-q2) * (2/3)
p3 = q2
for frame in range(total_frames):
newPage(CANVAS, CANVAS)
if frame == total_frames - 1:
frameDuration(1)
else:
frameDuration(duration)
# Draw lines
stroke(0.6)
line(p0, p1)
line(p1, p2)
line(p2, p3)
d = 5
r = d/2
notes_margin = np.array([10, -r])
coord_margin = np.array([10, d*2])
font('InputMonoCondensed Light', 10)
# Draw control points and notes
for i, point in enumerate([p0, p1, p2, p3]):
stroke(0.6)
fill(0.6)
oval(*(point-r), d, d)
text("P{}".format(i), point-notes_margin, align="right")
text("({:.0f}, {:.0f})".format(point[0], point[1]), point-coord_margin, align="right")
o = p0
t_range = [0, frame+1]
for i in range(*t_range, 1):
t = i/(total_frames-1)
p01 = p0 + t*(p1-p0)
p12 = p1 + t*(p2-p1)
p23 = p2 + t*(p3-p2)
p0112 = p01 + t*(p12 - p01)
p1223 = p12 + t*(p23 - p12)
# Draw bezier curve
p = p0112 + t*(p1223 - p0112)
stroke(0)
fill(0)
line(o, p)
o = p
text("t={:.4f}".format(t), (CANVAS-60, CANVAS-20), align="left")
# Save image
save_dir = os.path.expanduser('~/Downloads')
file_name = 'b3_05.gif'
saveImage(os.path.join(save_dir, file_name), imageResolution=200)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment