Bezier examples

Draw path with bezier commands

size(100, 100)
stroke(1, 0, 0)
fill(None)

newPath()
moveTo((8, 26))
lineTo((44, 48))
lineTo((20, 72))
curveTo((68, 92), (88, 86), (70, 24))
closePath()
drawPath()

Draw text as bezier path

size(814, 674)

B = BezierPath()
B.text('hi', font='Verdana Bold', fontSize=520, offset=(90, 122))

fill(0, 1, 0)
drawPath(B)

fill(0, 0, 1)
r = 9

for x, y in B.onCurvePoints:
    oval(x-r, y-r, r*2, r*2)

Draw a random bezier path

# draw a path through n random points

size(618, 412)

n = 24

B = BezierPath()
for i in range(n):
    # make random point position
    x = randint(0, width())
    y = randint(0, height())
    if i == 0:
        # print 'first point!'
        B.moveTo((x, y))
    else:
        # print 'just another point'
        B.lineTo((x, y))

fill(None)
stroke(1, 0, 0)
strokeWidth(3)
drawPath(B)

Drawing a UFO ‘glif’ object as bezier path

# draw a .glif using the BezierPath object

from robofab.world import RFont

# path to any ufo file
ufo = u"/Users/gferreira/Desktop/Publica_55.ufo"

# open the font, get a glyph
font = RFont(ufo)
glyph = font['a']

B = BezierPath()
for contour in glyph:
    for i, segment in enumerate(contour):
        # curveTo
        if len(segment.points) == 3:
            x1, y1 = segment.points[0].x, segment.points[0].y
            x2, y2 = segment.points[1].x, segment.points[1].y
            x3, y3 = segment.points[2].x, segment.points[2].y
            B.curveTo((x1, y1), (x2, y2), (x3, y3))
        # lineTo or moveTo
        else:
            x, y = segment.points[0].x, segment.points[0].y
            if i == 0:
                B.moveTo((x, y))
            else:
                B.lineTo((x, y))

translate(142, 168)
drawPath(B)

Draw a virtual ‘pen’ around a bezier path

# draw objects along a bezier segment

def vector((x, y), angle, distance):
    """Calculate a new x,y position based on a given angle and distance."""
    x2 = x + cos(radians(angle)) * distance
    y2 = y + sin(radians(angle)) * distance
    return x2, y2

# converted from:
# http://13thparallel.com/archive/bezier-curves/

def B1(t): return t*t*t
def B2(t): return 3*t*t*(1-t)
def B3(t): return 3*t*(1-t)*(1-t)
def B4(t): return (1-t)*(1-t)*(1-t)

def getPoint(t, (x1, y1), (x2, y2), (x3, y3), (x4, y4)):
    x = x1*B1(t) + x2*B2(t) + x3*B3(t) + x4*B4(t)
    y = y1*B1(t) + y2*B2(t) + y3*B3(t) + y4*B4(t)
    return x, y

size(200, 200)
fill(None)
stroke(1, 0, 0)
strokeWidth(1)

B = BezierPath()
B.moveTo((60, 26))
B.curveTo((-34, 186), (196, 202), (158, 44))
drawPath(B)

p1, p4 = B.onCurvePoints
p2, p3 = B.offCurvePoints

Variable([
    dict(name='n', ui='Slider', args=dict(value=80, minValue=2, maxValue=240)),
    dict(name='a', ui='Slider', args=dict(value=45.0, minValue=0.0, maxValue=180.0)),
    dict(name='f', ui='Slider', args=dict(value=0.5, minValue=0.01, maxValue=1.0)),
    dict(name='edges', ui='CheckBox', args=dict(value=True,)),
],
globals())

n = int(n)
r = 10
w, h = r*2, r*2*f

if edges:
    save()
    x1, y1 = vector(p1, a, w/2)
    d1_x, d1_y = x1 - p1[0], y1 - p1[1]
    translate(d1_x, d1_y)
    drawPath(B)
    restore()

    save()
    x4, y4 = vector(p4, a, w/2)
    d4_x, d4_y = x4 - p4[0], y4 - p4[1]
    translate(-d1_x, -d1_y)
    drawPath(B)
    restore()

for i in range(n+1):
    t = i * (1.0 / n)
    x, y = getPoint(t, p1, p2, p3, p4)
    save()
    translate(x, y)
    rotate(a)
    x, y = -r, -h/2
    oval(x, y, w, h) 
    restore()

Using bezier as clipping path

size(300, 200)

x = 20
B = BezierPath()
for i in range(8):
    B.oval(x, 68, 40, 70)
    x += 25

save()
clipPath(B)
scale(0.5)
image("https://i.ytimg.com/vi/JfIgzSoTMOs/hqdefault.jpg", (0, 0))
restore()

# print B.onCurvePoints
# print B.offCurvePoints

x, y, w, h = B.bounds()

fill(None)
stroke(0, 1, 0)
rect(x, y, w, h)

Composition with ‘point inside’ method

size(200, 200)

# make a bezier path
B = BezierPath()
B.moveTo((24, 168))
B.lineTo((14, 24))
B.lineTo((176, 28))
B.lineTo((136, 170))

# draw the bezier path
strokeWidth(5)
fill(None)
stroke(1, 0, 0)
drawPath(B)

# make a grid of elements
# draw them only inside the bezier

stroke(0, 1, 0)
strokeWidth(3)
x, y = 0, 0
dist = 15

for x in range(0, width(), dist):
    for y in range(0, height(), dist):
        if B.pointInside((x, y)):
            r = randint(3, 8)
            oval(x-r, y-r, r*2, r*2)

# change the path's point coordinates
# watch how the bubbles follow the shape

Appending shapes to a bezier path

size(600, 600)

B = BezierPath()
B.oval(44, 68, 200, 200)
B.rect(204, 282, 200, 200)

drawPath(B)

print B.onCurvePoints
print B.offCurvePoints