kopia lustrzana https://github.com/villares/sketch-a-day
main
rodzic
8fa0afbc94
commit
da098bf5b6
|
@ -9,6 +9,12 @@ If you enjoy this, be a [patreon](https://patreon.com/arteprog) or make a donati
|
|||
Feel free to [contact me](http://contato.lugaralgum.com) regarding licenses to use my work, teaching opportunities, consulting or other projects.
|
||||
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
329: [code](https://github.com/villares/sketch-a-day/tree/master/s329) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
"""
|
||||
Alexandre B A Villares http://abav.lugaralgum.com - GPL v3
|
||||
|
||||
A helper for the Processing gifAnimation library https://github.com/extrapixel/gif-animation/tree/3.0
|
||||
Download from https://github.com/villares/processing-play/blob/master/export_GIF/unzip_and_move_to_libraries_GifAnimation.zip
|
||||
This helper was inspired by an example by Art Simon https://github.com/APCSPrinciples/AnimatedGIF/
|
||||
|
||||
# add at the start of your sketch:
|
||||
add_library('gifAnimation')
|
||||
from gif_exporter import gif_export
|
||||
# add at the end of draw():
|
||||
gif_export(GifMaker)
|
||||
"""
|
||||
|
||||
def gif_export(GifMaker, # gets a reference to the library
|
||||
filename="exported", # .gif will be added
|
||||
repeat=0, # 0 makes it an "endless" animation
|
||||
quality=255, # quality range 0 - 255
|
||||
delay=200, # this is quick
|
||||
frames=0, # 0 will stop on keyPressed or frameCount >= 100000
|
||||
finish=False): # force stop
|
||||
global gifExporter
|
||||
try:
|
||||
gifExporter
|
||||
except NameError:
|
||||
gifExporter = GifMaker(this, filename + ".gif")
|
||||
gifExporter.setRepeat(repeat)
|
||||
gifExporter.setQuality(quality)
|
||||
gifExporter.setDelay(delay)
|
||||
|
||||
gifExporter.addFrame()
|
||||
|
||||
if frames == 0:
|
||||
if keyPressed or frameCount >= 100000:
|
||||
finish = True
|
||||
elif frameCount >= frames:
|
||||
finish = True
|
||||
|
||||
if finish:
|
||||
gifExporter.finish()
|
||||
print("gif saved")
|
||||
exit()
|
|
@ -0,0 +1,146 @@
|
|||
|
||||
def create_points(non_intersecting=True):
|
||||
background(200)
|
||||
done = False
|
||||
while not done:
|
||||
poly_points = [PVector(random(BORDER, width - BORDER),
|
||||
random(BORDER, height - BORDER)
|
||||
)
|
||||
for _ in range(NUM)]
|
||||
ed = edges(poly_points)
|
||||
done = True
|
||||
if non_intersecting:
|
||||
for p1, p2 in ed[::-1]:
|
||||
for p3, p4 in ed[2::]:
|
||||
# test only non consecutive edges
|
||||
if (p1 != p3) and (p2 != p3) and (p1 != p4):
|
||||
if line_instersect(Line(p1, p2), Line(p3, p4)):
|
||||
done = False
|
||||
break
|
||||
return poly_points
|
||||
|
||||
def is_inside(x, y, poly_points):
|
||||
min_, max_ = min_max(poly_points)
|
||||
if x < min_.x or y < min_.y or x > max_.x or y > max_.y:
|
||||
return False
|
||||
|
||||
a = PVector(x, min_.y)
|
||||
b = PVector(x, max_.y)
|
||||
v_lines = inter_lines(Line(a, b), poly_points)
|
||||
if not v_lines:
|
||||
return False
|
||||
|
||||
a = PVector(min_.x, y)
|
||||
b = PVector(max_.x, y)
|
||||
h_lines = inter_lines(Line(a, b), poly_points)
|
||||
if not h_lines:
|
||||
return False
|
||||
|
||||
for v in v_lines:
|
||||
for h in h_lines:
|
||||
if line_instersect(v, h):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def inter_lines(L, poly_points):
|
||||
inter_points = []
|
||||
for p1, p2 in edges(poly_points):
|
||||
inter = line_instersect(Line(p1, p2), L)
|
||||
if inter:
|
||||
inter_points.append(inter)
|
||||
if not inter_points:
|
||||
return []
|
||||
inter_lines = []
|
||||
if len(inter_points) > 1:
|
||||
inter_points.sort()
|
||||
pairs = zip(inter_points[::2], inter_points[1::2])
|
||||
for p1, p2 in pairs:
|
||||
if p2:
|
||||
inter_lines.append(Line(PVector(p1.x, p1.y),
|
||||
PVector(p2.x, p2.y)))
|
||||
return inter_lines
|
||||
|
||||
|
||||
class Line():
|
||||
""" I should change this to a named tuple... """
|
||||
def __init__(self, p1, p2):
|
||||
self.p1 = p1
|
||||
self.p2 = p2
|
||||
|
||||
def plot(self):
|
||||
line(self.p1.x, self.p1.y, self.p2.x, self.p2.y)
|
||||
|
||||
def lerp(self, other, t):
|
||||
p1 = PVector.lerp(self.p1, other.p1, t)
|
||||
p2 = PVector.lerp(self.p2, other.p2, t)
|
||||
return Line(p1, p2)
|
||||
|
||||
def line_instersect(line_a, line_b):
|
||||
"""
|
||||
code adapted from Bernardo Fontes
|
||||
https://github.com/berinhard/sketches/
|
||||
"""
|
||||
|
||||
x1, y1 = line_a.p1.x, line_a.p1.y
|
||||
x2, y2 = line_a.p2.x, line_a.p2.y
|
||||
x3, y3 = line_b.p1.x, line_b.p1.y
|
||||
x4, y4 = line_b.p2.x, line_b.p2.y
|
||||
|
||||
try:
|
||||
uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
|
||||
uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
|
||||
except ZeroDivisionError:
|
||||
return
|
||||
|
||||
if not(0 <= uA <= 1 and 0 <= uB <= 1):
|
||||
return
|
||||
|
||||
x = line_a.p1.x + uA * (line_a.p2.x - line_a.p1.x)
|
||||
y = line_a.p1.y + uA * (line_a.p2.y - line_a.p1.y)
|
||||
|
||||
return PVector(x, y)
|
||||
|
||||
|
||||
def edges(poly_points):
|
||||
return pairwise(poly_points) + [(poly_points[-1], poly_points[0])]
|
||||
|
||||
def pairwise(iterable):
|
||||
import itertools
|
||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||
a, b = itertools.tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
def min_max(points):
|
||||
points = iter(points)
|
||||
try:
|
||||
p = points.next()
|
||||
min_x, min_y = max_x, max_y = p.x, p.y
|
||||
except StopIteration:
|
||||
raise ValueError, "min_max requires at least one point"
|
||||
for p in points:
|
||||
if p.x < min_x:
|
||||
min_x = p.x
|
||||
elif p.x > max_x:
|
||||
max_x = p.x
|
||||
if p.y < min_y:
|
||||
min_y = p.y
|
||||
elif p.y > max_y:
|
||||
max_y = p.y
|
||||
return (PVector(min_x, min_y),
|
||||
PVector(max_x, max_y))
|
||||
|
||||
def par_hatch(points, divisions, *sides):
|
||||
vectors = [PVector(p.x, p.y) for p in points]
|
||||
lines = []
|
||||
if not sides: sides = [0]
|
||||
for s in sides:
|
||||
a, b = vectors[-1 + s], vectors[+0 + s]
|
||||
d, c = vectors[-2 + s], vectors[-3 + s]
|
||||
for i in range(1, divisions):
|
||||
s0 = PVector.lerp(a, b, i/float(divisions))
|
||||
s1 = PVector.lerp(d, c, i/float(divisions))
|
||||
lines.append(Line(s0, s1))
|
||||
return lines
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 572 KiB |
|
@ -0,0 +1,143 @@
|
|||
|
||||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
||||
SKETCH_NAME = "s329" # 20181124
|
||||
OUTPUT = ".gif"
|
||||
GRID_SIZE = 10
|
||||
|
||||
from line_geometry import Line
|
||||
from line_geometry import par_hatch
|
||||
#add_library('pdf')
|
||||
# add_library('gifAnimation')
|
||||
# from gif_exporter import gif_export
|
||||
|
||||
rule = lambda x, y: random(40) < 20
|
||||
|
||||
def setup():
|
||||
size(700, 700)
|
||||
smooth(8)
|
||||
init_grid(GRID_SIZE)
|
||||
background(200)
|
||||
#beginRecord(PDF, SKETCH_NAME + ".pdf")
|
||||
|
||||
|
||||
def draw():
|
||||
f = frameCount
|
||||
t = cos(f)
|
||||
stroke(0)
|
||||
strokeWeight(3)
|
||||
for c in Cell.cells:
|
||||
c.plot(t)
|
||||
|
||||
if 0 < f < TWO_PI:
|
||||
pass
|
||||
# gif_export(GifMaker, SKETCH_NAME)
|
||||
else:
|
||||
noLoop()
|
||||
# gif_export(GifMaker, finish=True)
|
||||
#endRecord()
|
||||
pass
|
||||
|
||||
def init_grid(grid_size):
|
||||
Cell.border = 125.
|
||||
Cell.spacing = (width - Cell.border *2) / grid_size
|
||||
Cell.cells = []
|
||||
randomSeed(101)
|
||||
for x in range(0, grid_size, 2):
|
||||
for y in range(0, grid_size, 2):
|
||||
new_cell = Cell(x, y)
|
||||
Cell.cells.append(new_cell)
|
||||
Cell.grid[x, y] = new_cell
|
||||
|
||||
randomSeed(frameCount+2)
|
||||
for x in range(-1, grid_size+1, 2):
|
||||
for y in range(-1, grid_size+1, 2):
|
||||
Node.grid0[x, y] = Node(x, y) # extrarir do dict
|
||||
Node.grid1[x, y] = Node(x, y) # extrarir do dict
|
||||
|
||||
|
||||
for c in Cell.cells:
|
||||
c.update_vers()
|
||||
|
||||
class Node():
|
||||
grid0 = dict()
|
||||
grid1 = dict()
|
||||
|
||||
def __init__(self, x, y):
|
||||
self.ix = x
|
||||
self.iy = y
|
||||
self.px = Cell.border + Cell.spacing + x * Cell.spacing
|
||||
self.py = Cell.border + Cell.spacing + y * Cell.spacing
|
||||
if rule(x, y):
|
||||
mx, my = width/2, height/2
|
||||
self.px += (self.px - mx) * 0.15
|
||||
self.py += (self.py - my) * 0.15
|
||||
self.x = self.px
|
||||
self.y = self.py
|
||||
|
||||
class Cell():
|
||||
cells = []
|
||||
grid = dict()
|
||||
|
||||
def __init__(self, x, y):
|
||||
self.ix = x
|
||||
self.iy = y
|
||||
self.px = Cell.border + Cell.spacing + x * Cell.spacing
|
||||
self.py = Cell.border + Cell.spacing + y * Cell.spacing
|
||||
self.vers = []
|
||||
self.num_hatches = int(random(4, 6))
|
||||
self.type_hatches = random(10)
|
||||
|
||||
def plot(self, t):
|
||||
L0, V0 = self.lines, self.vers
|
||||
L1, V1 = self.lines_f, self.vers_f
|
||||
|
||||
for l0, l1 in zip(L0, L1):
|
||||
l = l0.lerp(l1, t)
|
||||
l.plot()
|
||||
beginShape()
|
||||
noFill()
|
||||
for p0, p1 in zip(V0, V1):
|
||||
vertex(lerp(p0.x, p1.x, t), lerp(p0.y, p1.y, t) )
|
||||
endShape(CLOSE)
|
||||
|
||||
def update_vers(self):
|
||||
self.v0 = Node.grid0.get((self.ix-1, self.iy-1))
|
||||
self.v1 = Node.grid0.get((self.ix-1, self.iy+1))
|
||||
self.v3 = Node.grid0.get((self.ix+1, self.iy-1))
|
||||
self.v2 = Node.grid0.get((self.ix+1, self.iy+1))
|
||||
self.vers = [self.v0, self.v1, self.v2, self.v3]
|
||||
self.v0f = Node.grid1.get((self.ix-1, self.iy-1))
|
||||
self.v1f = Node.grid1.get((self.ix-1, self.iy+1))
|
||||
self.v3f = Node.grid1.get((self.ix+1, self.iy-1))
|
||||
self.v2f = Node.grid1.get((self.ix+1, self.iy+1))
|
||||
self.vers_f = [self.v0f, self.v1f, self.v2f, self.v3f]
|
||||
self.hatch()
|
||||
|
||||
def hatch(self):
|
||||
self.lines = []
|
||||
self.lines_f = []
|
||||
n = self.num_hatches
|
||||
r = self.type_hatches
|
||||
if r > 2:
|
||||
self.lines.extend(par_hatch(self.vers, n, 0))
|
||||
self.lines_f.extend(par_hatch(self.vers_f, n, 0))
|
||||
if r < 8:
|
||||
self.lines.extend(par_hatch(self.vers, n, 1))
|
||||
self.lines_f.extend(par_hatch(self.vers_f, n, 1))
|
||||
|
||||
def keyPressed():
|
||||
if key == "n" or key == CODED:
|
||||
init_grid(GRID_SIZE)
|
||||
background(200)
|
||||
#saveFrame("###.png")
|
||||
if key == "s": saveFrame(SKETCH_NAME + ".png")
|
||||
|
||||
# print text to add to the project's README.md
|
||||
def settings():
|
||||
println(
|
||||
"""
|
||||

|
||||
|
||||
{1}: [code](https://github.com/villares/sketch-a-day/tree/master/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
||||
""".format(SKETCH_NAME, SKETCH_NAME[1:], OUTPUT)
|
||||
)
|
|
@ -0,0 +1,145 @@
|
|||
|
||||
# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day
|
||||
SKETCH_NAME = "s329" # 20181123
|
||||
OUTPUT = ".png"
|
||||
GRID_SIZE = 6
|
||||
|
||||
from line_geometry import Line
|
||||
from line_geometry import par_hatch
|
||||
add_library('pdf')
|
||||
# add_library('gifAnimation')
|
||||
# from gif_exporter import gif_export
|
||||
|
||||
rule = lambda x, y: random(40) < 20
|
||||
|
||||
def setup():
|
||||
size(700, 700)
|
||||
smooth(8)
|
||||
init_grid(GRID_SIZE)
|
||||
background(200)
|
||||
#beginRecord(PDF, SKETCH_NAME + ".pdf")
|
||||
|
||||
|
||||
def draw():
|
||||
f = frameCount/2.
|
||||
t = cos(f)
|
||||
stroke(0)
|
||||
#print t
|
||||
for c in Cell.cells:
|
||||
c.plot(t)
|
||||
|
||||
if 0 < f <TWO_PI:
|
||||
pass
|
||||
#gif_export(GifMaker, SKETCH_NAME)
|
||||
else:
|
||||
noLoop()
|
||||
#endRecord()
|
||||
pass
|
||||
|
||||
def init_grid(grid_size):
|
||||
Cell.border = 125.
|
||||
Cell.spacing = (width - Cell.border *2) / grid_size
|
||||
Cell.cells = []
|
||||
randomSeed(101)
|
||||
for x in range(0, grid_size, 2):
|
||||
for y in range(0, grid_size, 2):
|
||||
new_cell = Cell(x, y)
|
||||
Cell.cells.append(new_cell)
|
||||
Cell.grid[x, y] = new_cell
|
||||
|
||||
randomSeed(frameCount+2)
|
||||
for x in range(-1, grid_size+1, 2):
|
||||
for y in range(-1, grid_size+1, 2):
|
||||
Node.grid0[x, y] = Node(x, y) # extrarir do dict
|
||||
Node.grid1[x, y] = Node(x, y) # extrarir do dict
|
||||
|
||||
|
||||
for c in Cell.cells:
|
||||
c.update_vers()
|
||||
|
||||
class Node():
|
||||
grid0 = dict()
|
||||
grid1 = dict()
|
||||
|
||||
def __init__(self, x, y):
|
||||
self.ix = x
|
||||
self.iy = y
|
||||
self.px = Cell.border + Cell.spacing + x * Cell.spacing
|
||||
self.py = Cell.border + Cell.spacing + y * Cell.spacing
|
||||
if rule(x, y):
|
||||
mx, my = width/2, height/2
|
||||
self.px += (self.px - mx) * 0.15
|
||||
self.py += (self.py - my) * 0.15
|
||||
self.x = self.px
|
||||
self.y = self.py
|
||||
|
||||
class Cell():
|
||||
cells = []
|
||||
grid = dict()
|
||||
|
||||
def __init__(self, x, y):
|
||||
self.ix = x
|
||||
self.iy = y
|
||||
self.px = Cell.border + Cell.spacing + x * Cell.spacing
|
||||
self.py = Cell.border + Cell.spacing + y * Cell.spacing
|
||||
self.vers = []
|
||||
self.num_hatches = int(random(5, 12))
|
||||
self.type_hatches = random(10)
|
||||
|
||||
def plot(self, t):
|
||||
L0, V0 = self.lines, self.vers
|
||||
L1, V1 = self.lines_f, self.vers_f
|
||||
|
||||
strokeWeight(1)
|
||||
stroke(0)
|
||||
for l0, l1 in zip(L0, L1):
|
||||
l = l0.lerp(l1, t)
|
||||
l.plot()
|
||||
beginShape()
|
||||
noFill()
|
||||
#stroke(255, 0, 0)
|
||||
for p0, p1 in zip(V0, V1):
|
||||
vertex(lerp(p0.x, p1.x, t), lerp(p0.y, p1.y, t) )
|
||||
endShape(CLOSE)
|
||||
|
||||
def update_vers(self):
|
||||
self.v0 = Node.grid0.get((self.ix-1, self.iy-1))
|
||||
self.v1 = Node.grid0.get((self.ix-1, self.iy+1))
|
||||
self.v3 = Node.grid0.get((self.ix+1, self.iy-1))
|
||||
self.v2 = Node.grid0.get((self.ix+1, self.iy+1))
|
||||
self.vers = [self.v0, self.v1, self.v2, self.v3]
|
||||
self.v0f = Node.grid1.get((self.ix-1, self.iy-1))
|
||||
self.v1f = Node.grid1.get((self.ix-1, self.iy+1))
|
||||
self.v3f = Node.grid1.get((self.ix+1, self.iy-1))
|
||||
self.v2f = Node.grid1.get((self.ix+1, self.iy+1))
|
||||
self.vers_f = [self.v0f, self.v1f, self.v2f, self.v3f]
|
||||
self.hatch()
|
||||
|
||||
def hatch(self):
|
||||
self.lines = []
|
||||
self.lines_f = []
|
||||
n = self.num_hatches
|
||||
r = self.type_hatches
|
||||
if r > 2:
|
||||
self.lines.extend(par_hatch(self.vers, n, 0))
|
||||
self.lines_f.extend(par_hatch(self.vers_f, n, 0))
|
||||
if r < 8:
|
||||
self.lines.extend(par_hatch(self.vers, n, 1))
|
||||
self.lines_f.extend(par_hatch(self.vers_f, n, 1))
|
||||
|
||||
def keyPressed():
|
||||
if key == "n" or key == CODED:
|
||||
init_grid(GRID_SIZE)
|
||||
background(200)
|
||||
#saveFrame("###.png")
|
||||
if key == "s": saveFrame(SKETCH_NAME + ".png")
|
||||
|
||||
# print text to add to the project's README.md
|
||||
def settings():
|
||||
println(
|
||||
"""
|
||||

|
||||
|
||||
{1}: [code](https://github.com/villares/sketch-a-day/tree/master/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
||||
""".format(SKETCH_NAME, SKETCH_NAME[1:], OUTPUT)
|
||||
)
|
Ładowanie…
Reference in New Issue