-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path__main__.py
More file actions
206 lines (174 loc) · 5.95 KB
/
Copy path__main__.py
File metadata and controls
206 lines (174 loc) · 5.95 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
"""2026-06-29
Caquinhos Redux 09
Pisos de caquinhos de São Paulo, realidade alternativa.
ericof.com
png
Sketch,py5,CreativeCoding,Voronoi
"""
from opensimplex import OpenSimplex
from random import shuffle
from sketches.padroes.cacos import popula_cacos
from sketches.utils.draw import canvas
from sketches.utils.draw.grade import cria_grade
from sketches.utils.helpers import sketches as helpers
from sketches.utils.helpers.images import estencil_como_forma
from sketches.utils.helpers.images import resource_image_as_array
from sketches.utils.helpers.timing import report_time
import py5
sketch = helpers.info_for_sketch(__file__, __doc__)
cor_fundo = py5.color(226, 214, 187)
cor_fundo_interna = py5.color(60, 60, 45)
CORES_PESOS = (
(py5.color(152, 59, 47), 93),
(py5.color(218, 160, 57), 2),
(py5.color(0), 3),
)
celula_x = 20
celula_y = 20
mult_x = 20
mult_y = 20
borda = 0.15
faixa_bagunca = 20
profundidade_caco = 4
profundidade_estencil = 20
# Ponto de luz controlado pelo mouse: x,y vem do cursor, altura (z) e tom sao
# fixos. A ambiente baixa evita que os cacos longe da luz fiquem pretos.
luz_altura = 800
luz_cor = py5.color(255, 244, 214)
luz_ambiente = py5.color(40, 40, 40)
# Distancia do anel de sementes-sentinela alem da area interna. Precisa ser
# maior que o deslocamento maximo de uma semente interna (mult + faixa_bagunca)
# para que toda semente visivel fique cercada e sua celula seja finita.
margem_guarda = 400
noise_generator = OpenSimplex(seed=py5.random_int(20_000))
cacos: list[py5.Py5Shape] = []
def cores_pesos() -> list[int]:
"""Expande ``CORES_PESOS`` numa lista com cada cor repetida conforme seu peso.
A lista e embaralhada e serve de base para o sorteio ponderado de cores
em :func:`cor_caco`.
:returns: Lista de cores com repeticao proporcional ao peso de cada uma.
"""
cores = []
for cor, peso in CORES_PESOS:
cores.extend([cor] * peso)
shuffle(cores)
return cores
CORES = cores_pesos()
def inicializa():
global cacos
grade = cria_grade(*helpers.DIMENSOES.external, 0, 0, celula_x, celula_y)
with report_time("Calculando..."):
cacos = popula_cacos(
*helpers.DIMENSOES.external,
celula_x,
celula_y,
grade,
mult_x,
mult_y,
faixa_bagunca,
margem_guarda,
borda,
profundidade_caco,
noise_generator,
CORES,
)
def setup():
global estencil, mascara
py5.size(*helpers.DIMENSOES.external, py5.P3D)
inicializa()
mascara = resource_image_as_array("sampa-reverso.png")
estencil = estencil_como_forma(
mascara, cor_fundo, profundidade=profundidade_estencil
)
def desenha_fundo(cor: int):
"""Desenha o fundo por baixo dos caquinhos."""
with py5.push():
py5.fill(cor)
py5.no_stroke()
py5.rect(0, 0, *helpers.DIMENSOES.external)
def draw():
py5.background(cor_fundo)
# Posicao da luz no espaco interno: o mouse e screen-space, entao
# descontamos a origem do painel (pos_interno).
luz_x = py5.mouse_x - helpers.DIMENSOES.pos_interno[0]
luz_y = py5.mouse_y - helpers.DIMENSOES.pos_interno[1]
with py5.push():
py5.translate(0, 0, -25)
# Fundo desenhado antes das luzes para manter o rejunte chapado; os
# prismas se assentam nele (base em z=0) e sobem em direcao a camera.
desenha_fundo(cor_fundo_interna)
# Luz pontual seguindo o mouse + ambiente baixa, no mesmo espaco dos
# cacos. Iluminam tambem o estencil, para o poco ganhar relevo.
py5.ambient_light(
py5.red(luz_ambiente), py5.green(luz_ambiente), py5.blue(luz_ambiente)
)
py5.point_light(
py5.red(luz_cor),
py5.green(luz_cor),
py5.blue(luz_cor),
luz_x,
luz_y,
luz_altura,
)
for forma in cacos:
py5.shape(forma)
# Estencil iluminado: as paredes verticais do poco sombreiam diferente
# da face frontal, revelando a profundidade. A base do poco assenta
# logo acima do topo dos cacos.
with py5.push():
py5.translate(*helpers.DIMENSOES.pos_interno, profundidade_caco + 1)
py5.shape(estencil)
py5.no_lights()
msg = (
f"celula (x - y): {celula_x} - {celula_y} | "
f"borda: {borda:.2f} | "
f"bagunca: {faixa_bagunca} | "
f"prof: {profundidade_caco} | "
f"est: {profundidade_estencil} | "
f"luz (x - y): {luz_x} - {luz_y}"
)
# Credits and go
canvas.sketch_frame(
sketch,
py5.color(0),
"large_transparent_white",
"transparent_white",
version=2,
msg=msg,
)
def key_pressed():
global celula_x, celula_y, borda, faixa_bagunca, profundidade_caco
global profundidade_estencil, estencil
key = py5.key
match key:
case "r":
inicializa()
case ">" | "<":
passo = 2 if key == ">" else -2
celula_x = max(4, celula_x + passo)
celula_y = max(4, celula_y + passo)
inicializa()
case "w" | "s":
borda = min(0.6, max(0.0, borda + (0.05 if key == "w" else -0.05)))
inicializa()
case "+" | "-":
faixa_bagunca = max(0, faixa_bagunca + (5 if key == "+" else -5))
inicializa()
case "e" | "d":
profundidade_caco = max(0, profundidade_caco + (1 if key == "e" else -1))
inicializa()
case "o" | "l":
profundidade_estencil = max(
0, profundidade_estencil + (2 if key == "o" else -2)
)
estencil = estencil_como_forma(
mascara, cor_fundo, profundidade=profundidade_estencil
)
case " ":
save_and_close()
def save_and_close():
py5.no_loop()
canvas.save_sketch_image(sketch)
py5.exit_sketch()
if __name__ == "__main__":
py5.run_sketch()