kopia lustrzana https://github.com/villares/sketch-a-day
day 24
rodzic
624c6b9d4b
commit
7f2e9a46f4
|
|
@ -4,9 +4,13 @@
|
|||
|
||||
Hi! I'm [Alexandre Villares](https://abav.lugaralgum.com), let's see if I can make one small program (*sketch*) a day.
|
||||
|
||||

|
||||
|
||||
024b: [sketch_180124b](https://github.com/villares/sketch-a-day/tree/master/sketch_180124b) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] Tomorrow I'll try adding some sliders & movement to this graph
|
||||
|
||||

|
||||
|
||||
023b: [sketch_180123b](https://github.com/villares/sketch-a-day/tree/master/sketch_180123b) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
|
||||
023b: [sketch_180123b](https://github.com/villares/sketch-a-day/tree/master/sketch_180123b) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] Farrel's Sliders adding random displacement
|
||||
|
||||
022: missed :(
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
s18020b - Alexandre B A Villares
|
||||
s18023b - Alexandre B A Villares
|
||||
https://abav.lugaralgum.com/sketch-a-day
|
||||
|
||||
Slider code by Peter Farell (older version tweeked by me)
|
||||
|
|
|
|||
Plik binarny nie jest wyświetlany.
|
|
@ -0,0 +1,2 @@
|
|||
mode=Python
|
||||
mode.id=jycessing.mode.PythonMode
|
||||
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 180 KiB |
|
|
@ -0,0 +1,197 @@
|
|||
"""
|
||||
s18020b - Alexandre B A Villares
|
||||
https://abav.lugaralgum.com/sketch-a-day
|
||||
|
||||
Slider code by Peter Farell (older version tweeked by me)
|
||||
https://github.com/hackingmath/python-sliders
|
||||
"""
|
||||
#from slider import Slider
|
||||
|
||||
# r1 = Slider(-50, 50, 0)
|
||||
# r2 = Slider(-50, 50, 0)
|
||||
# np = Slider(3, 50, 10)
|
||||
|
||||
CEL_SIZE = 50
|
||||
HALF_CEL = CEL_SIZE / 2
|
||||
|
||||
pontos = set() # conjunto de Pontos
|
||||
arestas = [] # lista de Arestas
|
||||
|
||||
TAM_PONTO = 50 # TAM_PONTO dos Pontos \
|
||||
TAM_BARRA = 100
|
||||
VEL_MAX = 2 # velocidade máxima nas ortogonais vx e vy
|
||||
|
||||
|
||||
def setup():
|
||||
global ROWS, COLS # filas e colunas
|
||||
size(400, 400)
|
||||
fill(0)
|
||||
ROWS, COLS = int(height / CEL_SIZE), int(width / CEL_SIZE)
|
||||
for r in range(ROWS):
|
||||
for c in range(COLS):
|
||||
x, y = HALF_CEL + c * CEL_SIZE,\
|
||||
HALF_CEL + r * CEL_SIZE
|
||||
pontos.add(Ponto(x, y)) # acrescenta um Ponto
|
||||
|
||||
|
||||
|
||||
import random as rnd # para não conflitar com o random do Processing
|
||||
|
||||
|
||||
def draw():
|
||||
background(128) # limpa a tela
|
||||
# para cada ponto
|
||||
for ponto in pontos:
|
||||
ponto.desenha() # desenha
|
||||
ponto.move() # atualiza posição
|
||||
# para cada aresta
|
||||
for aresta in arestas: # checa se há Arestas com Pontos já removidos
|
||||
if (aresta.p1 not in pontos) or (aresta.p2 not in pontos):
|
||||
arestas.remove(aresta) # nesse caso remove a Aresta também
|
||||
else: # senão
|
||||
aresta.desenha() # desenha a linha
|
||||
aresta.puxa_empurra() # altera a velocidade dos pontos
|
||||
|
||||
# Sob clique do mouse seleciona/deseleciona Pontos ou Arestas
|
||||
def mouseClicked():
|
||||
for ponto in pontos: # para cada Ponto checa distância do mouse
|
||||
if dist(mouseX, mouseY, ponto.x, ponto.y) < TAM_PONTO / 2:
|
||||
ponto.sel = not ponto.sel # inverte status de seleção
|
||||
mouse = PVector(mouseX, mouseY)
|
||||
for aresta in arestas: # para cada Aresta checa o 'mouse over'
|
||||
if pointInsideLine(mouse, aresta.p1, aresta.p2, 6):
|
||||
aresta.sel = not aresta.sel # inverte status de seleção
|
||||
|
||||
|
||||
def keyPressed(): # Quando uma tecla é pressionada
|
||||
# Barra de espaço acrescenta Pontos na posição atual do mouse
|
||||
if key == ' ':
|
||||
pontos.add(Ponto(mouseX, mouseY)) # acrescenta Ponto no set
|
||||
# 'd' remove os Pontos previamente selecionandos com clique, marcados em preto.
|
||||
if key == 'd':
|
||||
for ponto in pontos:
|
||||
# se a lista tiver pelo menos 2 pontos
|
||||
if ponto.sel and len(pontos) > 1:
|
||||
pontos.remove(ponto) # remove pontos selecionados
|
||||
for aresta in arestas:
|
||||
if aresta.sel: # se a lista tiver pelo menos 2 pontos
|
||||
arestas.remove(aresta) # remove pontos selecionados
|
||||
|
||||
def mouseDragged(): # quando o mouse é arrastado
|
||||
for ponto in pontos: # para cada Ponto checa distância do mouse
|
||||
if dist(mouseX, mouseY, ponto.x, ponto.y) < TAM_PONTO / 2:
|
||||
# move o Ponto para posição do mouse
|
||||
ponto.x, ponto.y = mouseX, mouseY
|
||||
ponto.vx = 0
|
||||
ponto.vy = 0
|
||||
|
||||
class Ponto():
|
||||
|
||||
" Pontos num grafo, VEL_MAX inicial sorteada, criam Arestas com outros Pontos "
|
||||
|
||||
def __init__(self, x, y, cor=color(0)):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = 0 # para compatibilidade com PVector...
|
||||
self.vx = random(-VEL_MAX, VEL_MAX)
|
||||
self.vy = random(-VEL_MAX, VEL_MAX)
|
||||
self.sel = False # se está selecionado, começa sem seleção
|
||||
self.cor = color(random(128, 255), # R
|
||||
random(128, 255), # G
|
||||
random(128, 255), # B
|
||||
128) # Alpha ~50%
|
||||
self.cria_arestas()
|
||||
|
||||
def desenha(self):
|
||||
if self.sel:
|
||||
stroke(0)
|
||||
else:
|
||||
noStroke()
|
||||
fill(self.cor)
|
||||
ellipse(self.x, self.y, TAM_PONTO, TAM_PONTO)
|
||||
if dist(mouseX, mouseY, self.x, self.y) < TAM_PONTO:
|
||||
stroke(255)
|
||||
noFill()
|
||||
ellipse(self.x, self.y, TAM_PONTO + 5, TAM_PONTO + 5)
|
||||
# fill(0)
|
||||
# text(str(len(pontos)) + " " + str(len(arestas)), self.x, self.y)
|
||||
|
||||
def move(self):
|
||||
self.x += self.vx
|
||||
self.y += self.vy
|
||||
if not (0 < self.x < width):
|
||||
self.vx = -self.vx
|
||||
if not (0 < self.y < height):
|
||||
self.vy = -self.vy
|
||||
self.vx = self.limitar(self.vx, VEL_MAX)
|
||||
self.vy = self.limitar(self.vy, VEL_MAX)
|
||||
|
||||
def cria_arestas(self, modo='random'):
|
||||
if modo == 'random':
|
||||
lista_pontos = list(pontos)
|
||||
if lista_pontos:
|
||||
nova_aresta = Aresta(rnd.choice(lista_pontos), self)
|
||||
arestas.append(nova_aresta)
|
||||
elif modo == 'all':
|
||||
for ponto in pontos:
|
||||
nova_aresta = Aresta(ponto, self)
|
||||
arestas.append(nova_aresta)
|
||||
|
||||
def limitar(self, v, v_max):
|
||||
if v > v_max:
|
||||
return v_max
|
||||
elif v < -v_max:
|
||||
return -v_max
|
||||
else:
|
||||
return v
|
||||
|
||||
class Aresta():
|
||||
|
||||
""" Arestas contém só dois Pontos e podem ou não estar selecionadas """
|
||||
|
||||
def __init__(self, p1, p2):
|
||||
self.p1 = p1
|
||||
self.p2 = p2
|
||||
self.sel = False
|
||||
|
||||
def desenha(self):
|
||||
if self.sel:
|
||||
stroke(0)
|
||||
else:
|
||||
stroke(255)
|
||||
line(self.p1.x, self.p1.y, self.p2.x, self.p2.y)
|
||||
noStroke()
|
||||
fill(255)
|
||||
ellipse(self.p1.x, self.p1.y, TAM_PONTO / 6, TAM_PONTO / 6)
|
||||
ellipse(self.p2.x, self.p2.y, TAM_PONTO / 6, TAM_PONTO / 6)
|
||||
|
||||
def puxa_empurra(self):
|
||||
d = dist(self.p1.x, self.p1.y, self.p2.x, self.p2.y)
|
||||
delta = TAM_BARRA - d
|
||||
dir = PVector.sub(self.p1, self.p2)
|
||||
dir.mult(delta / 1000)
|
||||
self.p1.vx = self.p1.vx + dir.x
|
||||
self.p1.vy = self.p1.vy + dir.y
|
||||
self.p2.vx = self.p2.vx - dir.x
|
||||
self.p2.vy = self.p2.vy - dir.y
|
||||
|
||||
|
||||
def pointInsideLine(thePoint, theLineEndPoint1, theLineEndPoint2, theTolerance):
|
||||
# from Andreas Schlegel / http://www.sojamo.de """
|
||||
dir = PVector(theLineEndPoint2.x, theLineEndPoint2.y, 0)
|
||||
dir.sub(theLineEndPoint1)
|
||||
diff = PVector(thePoint.x, thePoint.y, 0)
|
||||
diff.sub(theLineEndPoint1)
|
||||
try:
|
||||
insideDistance = diff.dot(dir) / dir.dot(dir)
|
||||
except ZeroDivisionError:
|
||||
insideDistance = 1000
|
||||
if (0 < insideDistance < 1):
|
||||
closest = PVector(theLineEndPoint1.x, theLineEndPoint1.y, 0)
|
||||
dir.mult(insideDistance)
|
||||
closest.add(dir)
|
||||
d = PVector(thePoint.x, thePoint.y)
|
||||
d.sub(closest)
|
||||
distsqr = d.dot(d)
|
||||
return (distsqr < pow(theTolerance, 2))
|
||||
return False
|
||||
Plik binarny nie jest wyświetlany.
|
|
@ -0,0 +1,75 @@
|
|||
"""
|
||||
Slider code by Peter Farell
|
||||
htts://twitter.com/hackingmath
|
||||
http://farrellpolymath.com/
|
||||
|
||||
Get the most recent version here:
|
||||
https://github.com/hackingmath/python-sliders
|
||||
"""
|
||||
# USAGE:
|
||||
#>from slider import Slider
|
||||
#
|
||||
# Outside the setup function I created the slider object:
|
||||
#
|
||||
#>slider1 = Slider(0,20,6)
|
||||
#
|
||||
# You have to tell it the range of the slider (in this case 0 to 20)
|
||||
# and the default value, when the program first runs (in this case, 6).
|
||||
#
|
||||
# Inside the setup function you give it a position on the screen:
|
||||
#
|
||||
#>slider1.position(20,20)
|
||||
#
|
||||
# Finally in the draw function you assign the value of the slider to a variable and work with it interactively. I just wanted to show it was returning and updating the value, so I just printed it out in the console:
|
||||
#
|
||||
#>num = slider1.value()
|
||||
#>println(num)
|
||||
#
|
||||
|
||||
class Slider:
|
||||
|
||||
def __init__(self, low, high, default):
|
||||
'''slider has range from low to high
|
||||
and is set to default'''
|
||||
self.low = low
|
||||
self.high = high
|
||||
self.val = default
|
||||
self.clicked = False
|
||||
|
||||
def position(self, x, y):
|
||||
'''slider's position on screen'''
|
||||
self.x = x
|
||||
self.y = y
|
||||
# the position of the rect you slide:
|
||||
self.rectx = self.x + map(self.val, self.low, self.high, 0, 120)
|
||||
self.recty = self.y - 10
|
||||
|
||||
def value(self):
|
||||
'''updates the slider and returns value'''
|
||||
pushStyle()
|
||||
rectMode(CENTER)
|
||||
# black translucid rect behind slider
|
||||
fill(0, 100)
|
||||
stroke(0)
|
||||
rect(self.x + 60, self.y, 130, 20)
|
||||
# gray line behind slider
|
||||
strokeWeight(4)
|
||||
stroke(200)
|
||||
line(self.x, self.y, self.x + 120, self.y)
|
||||
# press mouse to move slider
|
||||
if dist(mouseX, mouseY, self.rectx + 5, self.recty + 10) < 20:
|
||||
fill(200)
|
||||
textSize(10)
|
||||
text(int(self.val), self.rectx, self.recty + 35)
|
||||
if mousePressed:
|
||||
self.rectx = mouseX
|
||||
# constrain rectangle
|
||||
self.rectx = constrain(self.rectx, self.x, self.x + 120)
|
||||
# draw rectangle
|
||||
strokeWeight(1)
|
||||
fill(255)
|
||||
rect(self.rectx, self.recty + 10, 10, 20)
|
||||
self.val = map(self.rectx, self.x, self.x + 120, self.low, self.high)
|
||||
# draw label
|
||||
popStyle()
|
||||
return self.val
|
||||
Ładowanie…
Reference in New Issue