Em uma tarde qualquer, de despretenciosa ociosidade, estava rolando o tiktok quando surgiu a seguinte descrição:
Descrição
Desenhe um triângulo equilátero com os vértices A, B, C e tome um ponto arbitrário D dentro do triângulo.
Escolha um vértice do triângulo aleatoriamente.
Marque o ponto médio X entre D e o vértice escolhido.
Repita esse processo, com X no lugar de D, recursivamente.
O vídeo terminava revelando a seguinte figura final e seu nome.
Triângulo de Sierpinski
Minha reação imediata foi exclamar um sonoro: Nem fu…!
Larguei imediatamente o tiktok e, utilizando os meus rasos conhecimentos de python , fui verificar essa afirmação, altamente inverossímil. Abri o jupyter e comecie a fazer um script que reproduzisse o processo.
Após alguns minutos, tinha um script que me maravilhava com a confirmação daquela figura!
O Triângulo de Sierpinski
O Triângulo de Sierpinski é um exemplo de fractal autossimilar. Ele recebe esse nome em homenagem ao matemático polonês Wacław Sierpiński, que foi o primeiro a descrever essa estrutura.
É possível construir o Triângulo de Sierpinski através de um processo iterativo que tem como ponto de partida um triângulo equilátero.
Determina-se os pontos médios de cada lado dessa figura e une-se esses pontos.
Remove-se o triângulo do meio.
Esses passos são repetidos para cada um dos triângulos restantes.
Jogo do Caos
Tempos depois descobri que aquela descrição do tiktok era na verdade um algorítmo conhecido como jogo do caos.
Este processo cria uma aproximação do Triângulo de Sierpinski. Se os pontos forem coloridos de acordo com os vértices escolhidos, por exemplo A = verde, B = vermelho e C = azul, obtém-se três Triângulos de Sierpinski coloridos dentro de um Triângulo de Sierpinski.
O script que fiz, logo após o vídeo do tiktok, era bem rudimentar. A partir dele eu gerei o seguinte script melhorado que constroi o triângulo descrito no vídeo com 3000 iterações.
import sympy as spimport matplotlib.pyplot as pltimport random as rd##construção de um triângulo equilátero de lado l#construção dos vérticesl=4a, h=l/2, l*sp.sqrt(3)/2A=sp.Matrix([-a,0])B=sp.Matrix([a,0])C=sp.Matrix([0,h])print(f"A = ({float(A[0]):.2f}, {float(A[1]):.2f})")print(f"B = ({float(B[0]):.1f}, {float(B[1]):.1f})")print(f"C = ({float(C[0]):.2f}, {float(C[1]):.2f})")print()#gerando ponto aleatório no interior do triângulodx =round(rd.random()*l - a,2) # coordenada x entre -a e awhile dx ==-a or dx == a: dx =round(rd.random()*l - a,2) adx=sp.Abs(dx) y=h/a*(a-adx) #altura máximady=round(rd.random()*y,2)i=0while dy==0or dy==h: i=i+1 dy=round(rd.random()*y,2)print('Ponto D arbitrário no interior')D=sp.Matrix([dx,dy])print(f"D = ({float(D[0]):.2f}, {float(D[1]):.2f})")#desenhando o triânguloplt.plot([A[0],B[0],C[0],A[0]],[A[1],B[1],C[1],A[1]],'b-')plt.plot(D[0],D[1],'bo',markersize=4) # bo= black, ball#função ponto médiodef med(X,Y):return (X+Y)/2list=[A,B,C]E=rd.choice(list)X=med(E,D)for i inrange(3000): Y=rd.choice(list) X=med(Y,X)if Y==A: plt.plot(X[0],X[1],'go',markersize=1)elif Y==B: plt.plot(X[0],X[1],'ro',markersize=1)else: plt.plot(X[0],X[1],'bo',markersize=1)plt.plot([A[0],B[0],C[0],A[0]],[A[1],B[1],C[1],A[1]],'b-')plt.plot(D[0],D[1],'ko',markersize=4) # ro= red, ballplt.show()
A = (-2.00, 0.00)
B = (2.0, 0.0)
C = (0.00, 3.46)
Ponto D arbitrário no interior
D = (-0.37, 2.62)