-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathClipping.pv
More file actions
64 lines (51 loc) · 2.4 KB
/
Copy pathClipping.pv
File metadata and controls
64 lines (51 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""
Masked drawing operations.
PlotDevice can use any Bezier path as a "stencil" to mask-out any
shapes you draw to the canvas. The clip() and mask() commands work with
drawing primitives as well as text and images.
"""
size(300,300)
# ---- Clipping with Primitive Shapes ---- #
# Transformation commands can have an effect on the clipped path, the
# drawing that occurs within the clipping mask, or both. In this case
# we only want our arrow-shaped mask to be rotated (not its contents).
# So we'll generate its Bezier inside a `with rotate' block.
# Rotate the arrow to let it point down.
with rotate(-90):
# The last parameter instructs the command to return the arrow shape
# as a Bezier object rather than drawing it to the canvas.
p = arrow(250, 100, 200, plot=False)
# Beziers have a particularly useful property called `bounds` that returns
# the dimensions of the "bounding box". We'll use these coordinates to
# figure out where to draw ovals so they lie inside the visible portion.
(x,y), (w,h) = p.bounds
# All drawing commands inside of the `with clip()' block are clipped
# according to the given path (in this case the arrow we just defined).
with clip(p):
# draw 200 randomly-rotated lines (actually rectangles with a height of 1)
# positioned within the bounds of the clipping mask
for i in range(400):
fill(random(), random(), 0, random())
s = random(30, 120)
with rotate(random(45, 135)):
rect(x+random(w)-s/2, y+random(h), s, 1)
# ---- Clipping with Text ---- #
# Clipping with text works just like clipping with shapes. The clip() and
# mask() commands can both work with text() objects, but in this case we'll
# use textpath() to generate a Bezier instead (since we need to access its
# `bounds` property).
# Set the font. Note that all state operations work as expected for the
# textpath() command just as they would with text()
font("Didot", "bold", 72)
align(CENTER)
# Return a path that can be used for clipping. Textpaths never draw on screen.
p = textpath("Stencil", WIDTH/2, 270)
# As before, we'll use the Bezier path's bounds to position our clipped contents
(x,y), (w,h) = p.bounds
# use the text's boundaries as a clipping mask
with clip(p):
# Draw 200 rects of a random size and position them within the bounds
for i in range(200):
fill(random(), 0.7, 0, random())
s = random(20)
arc(x+random(w), y+random(h), s)