Um pequeno update ao meu cubo5.py Juntei um cuboctaedro. Usar teclas +,-, 1,2,3,4,5,6,9 < > alpha shift
# Título ##################################################### # # cubo6 # Versão: 23-02-2025 # # usar teclas +,-,*,: 1,2,3,4,5,6 # 9 < > alpha shift ############################################################## # # (c) Carlos Paulo A. Freitas (cpaulof@gmail.com) # https://zonaexacta.blogspot.com # https://sites.google.com/view/cpaulof-prog-calc # ############################################################## from math import * from ion import * import time import kandinsky zz=1/25 #Cores: vou deixar 8 cores F=255 cores = [ [0,0,0], #0 preto [F,F,F], #1 branco [F,0,0], #2 vermelho [0,F,0], #3 verde [0,0,F], #4 azul [F,0,F], #5 violeta [F,F,0], #6 vermelho+verde= [0,F,F], #7 [204,153,0] #8 ] N_COLORS=9 #Ecrã LARGURA=320 ALTURA=240 ######################### alpha,phi,theta=0,0,0 olho=[0,1,0] X_MIN = -3 X_MAX = 3 deltaX=(X_MAX-X_MIN)/(LARGURA-1) Y_MIN =-ALTURA/2*(X_MAX-X_MIN)/LARGURA Y_MAX = ALTURA/2*(X_MAX-X_MIN)/LARGURA VY=(Y_MAX-Y_MIN)/2 ZF=0.9 deltaY=(Y_MAX-Y_MIN)/(ALTURA-1) class Poliedro: def __init__(s, v, normais, arestas, faces, nv, na, nf, nl): s.v = v s.normais = normais s.arestas = arestas s.faces = faces s.nv = nv s.na = na s.nf = nf s.nl = nl def descarregaPoliedro(p): p.nv = 0 p.na = 0 p.nf = 0 p.nl = 0 del p.v del p.arestas del p.faces del p.normais def Tetraedro(): vertices = [ [0, 0, 1.0], [2*sqrt(2)/3.0, 0, -1.0/3.0], [-sqrt(2)/3.0, sqrt(6)/3.0, -1.0/3.0], [-sqrt(2)/3.0, -sqrt(6)/3.0, -1.0/3.0] ] normais = [ [-sqrt(2)/3.0, -sqrt(6)/3.0, -1.0/3.0], [-sqrt(2)/3.0, sqrt(6)/3.0, -1.0/3.0], [2*sqrt(2)/3.0, 0, -1.0/3.0], [0, 0, 1] ] arestas = [0,1,0,2,0,3,1,2,2,3,3,1] faces = [0,1,2,0,1,3,0,3,2,1,2,3] p=Poliedro(vertices, normais, arestas, faces, 4, 6, 4, 3) return p def Cubo(): l = 1.0 / sqrt(3.0) vertices = [[-l,-l,-l], [l,-l,-l], [l,l,-l], [-l,l,-l], [-l,l,l], [-l,-l,l], [l,-l,l], [l,l,l]] arestas = [0,1,1,2,2,3,3,0,5,6,6,7,7,4,4,5,1,6,2,7,3,4,0,5] faces = [0,1,2,3,0,1,6,5,5,6,7,4,3,2,7,4,1,2,7,6,0,3,4,5] normais = [[0,0,-1],[0,-1,0],[0,0,1],[0,1,0],[1,0,0],[-1,0,0]] p=Poliedro(vertices, normais, arestas, faces, 8, 12, 6, 4) return p def Octaedro(): vertices = [ [0,0,1], [1,0,0], [0,1,0], [-1,0,0], [0,-1,0], [0,0,-1] ] arestas = [0,1,0,2,0,3,0,4,1,2,2,3,3,4,4,1,1,5,2,5,3,5,4,5] faces = [0,1,2,0,2,3,0,3,4,0,4,1,5,1,2,5,2,3,5,3,4,5,4,1] normais = [[1.0, 1.0, 1],[-1.0, 1.0, 1],[-1.0, -1.0, 1],[1.0, -1.0, 1],[1.0, 1.0, -1],[-1.0, 1.0, -1],[-1.0, -1.0, -1],[1.0, -1.0, -1]] p=Poliedro(vertices, normais, arestas, faces, 6, 12, 8, 3) return p def Dodecaedro(): g=(1+sqrt(5.0))/2.0 v = [[0, 0, 1], [2/3, 0, sqrt(5)/3], [sqrt(5)/3, sqrt(3)/3, 1/3], [(2-g)/3, sqrt(3)/3*g, 1/3], [-1/3, sqrt(3)/3, sqrt(5)/3], [-1/3, -sqrt(3)/3, sqrt(5)/3], [sqrt(5)/3, -sqrt(3)/3, 1/3], [(2-g)/3, -sqrt(3)/3*g, 1/3], [-(g+1)/3, (1-g)*sqrt(3)/3, 1/3], [-(g+1)/3, (-1+g)*sqrt(3)/3, 1/3], [-sqrt(5)/3, sqrt(3)/3, -1/3], [(g-2)/3, sqrt(3)/3*g, -1/3], [(g-2)/3, -sqrt(3)/3*g, -1/3], [-sqrt(5)/3, -sqrt(3)/3, -1/3], [(g+1)/3, (g-1)*sqrt(3)/3, -1/3], [(g+1)/3, -(g-1)*sqrt(3)/3, -1/3], [1/3, -sqrt(3)/3, -sqrt(5)/3], [0, 0, -1], [1/3, sqrt(3)/3, -sqrt(5)/3], [-2/3, 0, -sqrt(5)/3]] arestas = [0, 1, 0, 4, 0, 5, 1, 2, 2, 3, 3, 4, 1, 6, 6, 7, 7, 5, 5, 8, 8, 9, 9, 4, 9, 10, 11, 10, 11, 3, 7, 12, 12, 13, 13, 8, 2, 14, 14, 15, 15, 6, 12, 16, 11, 18, 14, 18, 13, 19, 19, 10, 19, 17, 16, 17, 15, 16, 17, 18] faces = [0,1,2,3,4, 0,4,9,8,5, 0,5,7,6,1, 3,11,10,9,4, 5,8,13,12,7, 1,6,15,14,2, 6,7,12,16,15, 2,14,18,11,3, 8,9,10,19,13, 12,13,19,17,16, 11,18,17,19,10, 14,15,16,17,18] normais = [] for i in range(12): j, k, l, m, n = faces[5*i:5*i+5] normal = [v[j][0] + v[k][0] + v[l][0] + v[m][0] + v[n][0], v[j][1] + v[k][1] + v[l][1] + v[m][1] + v[n][1], v[j][2] + v[k][2] + v[l][2] + v[m][2] + v[n][2]] normais.append(normal) p=Poliedro(v, normais, arestas, faces, 20, 30, 12, 5) return p def Icosaedro(): g=(1+sqrt(5.0))/2.0 v = [[0, 0, 1]] r = 2*sqrt(2-g)/(3-g) #vertices for i in range(5): theta = 2*i*pi/5 v.append([cos(theta)*r, sin(theta)*r, (g-1)/(3-g)]) for i in range(5): theta = (2*i+1)*pi/5 v.append([cos(theta)*r, sin(theta)*r, -(g-1)/(3-g)]) v.append([0, 0, -1]) # arestas a=array(60) # (piramide superior) for i in range(0, 10, 2): a[i] = 0 a[i+1] = (i+2) // 2 for i in range(1, 6): a[2*i+8] = i a[2*i+9] = i % 5 + 1 a[19] = a[10] # (piramide inferior) for i in range(0, 10, 2): a[59-i] = 11 a[58-i] = 10 - i // 2 for i in range(0, 10, 2): a[49-i] = i // 2 + 6 a[48-i] = a[49-i] + 1 a[40] = a[49] # (cilindro central) for i in range(1, 6): a[20+2*(i-1)] = i a[20+2*i-1] = i+5 for i in range(1, 6): a[30+2*(i-1)] = i a[30+2*i-1] = 6 + (i+3) % 5 faces = [0,1,2,0,2,3,0,3,4,0,4,5,0,5,1,2,1,6,3,2,7,4,3,8,5,4,9,1,5,10,1,10,6,2,6,7,3,7,8,4,8,9,5,9,10,6,7,11,7,8,11,8,9,11,9,10,11,10,6,11] # normais normais=[] for i in range(20): j = faces[3 * i] k = faces[3 * i + 1] l = faces[3 * i + 2] normais.append([v[j][0]+v[k][0]+v[l][0], v[j][1]+v[k][1]+v[l][1], v[j][2]+v[k][2]+v[l][2]]) p=Poliedro(v, normais, a, faces, 12, 30, 20, 3) return p def xy2D_To_xz3D(v,s): c,f,dim=0.5,-0.5,len(v) _v=[] for i in range(dim): _v.append([v[i][0]*s,c*s ,v[i][1]*s]) for i in range(dim): _v.append([v[i][0]*s,f*s,v[i][1]*s]) return _v def Cuboctaedro(): a=0.5*sqrt(2) #vertices v = [ [0, a, a], [-a, 0, a], [0, -a, a], [a, 0,a], [a, a,0], [-a, a,0], [-a, -a,0], [a, -a,0], [0, a, -a], [-a, 0,-a], [0, -a,-a], [a, 0,-a] ] arestas = [0,1,1,2,2,3,3,0,0,4,0,5,1,5,1,6,2,6,2,7,3,7,3,4,4,11,4,8,5,8,5,9,6,9,6,10,7,10,7,11,8,9,9,10,10,11,11,8] faces = [[0,1,2,3], [0,4,8,5], [1,5,9,6], [2,7,10,6], [3,7,11,4], [11,8,9,10], [0,5,1], [0,3,4], [1,2,6], [2,3,7], [9,8,5], [11,8,4], [11,10,7], [9,10,6]] nl = [4,4,4,4,4,4,3,3,3,3,3,3,3,3] # normais normais=[] for i in range(6): j = faces[i][0] k = faces[i][1] l = faces[i][2] m = faces[i][3] #normais.append([0,0,0]) normais.append([v[j][0]+v[k][0]+v[l][0]+v[m][0], v[j][1]+v[k][1]+v[l][1]+v[m][1], v[j][2]+v[k][2]+v[l][2]+v[m][2]]) for i in range(6,14): j = faces[i][0] k = faces[i][1] l = faces[i][2] #if i!=7: normais.append([v[j][0]+v[k][0]+v[l][0], v[j][1]+v[k][1]+v[l][1], v[j][2]+v[k][2]+v[l][2]]) #else: # normais.append([0,0,0]) #(s, v, normais, arestas, faces, nv, na, nf, nl): p=Poliedro(v, normais, arestas, faces, 12, 24, 14, nl) return p _B,_C=1,0 BACKGROUND,COR=1,0 INVERT=0 def plot(x,y,cor): c = int(LARGURA*((x - X_MIN)/(X_MAX - X_MIN))) l = int(ALTURA*(1-(y - Y_MIN)/(Y_MAX - Y_MIN))) if(0 <= l < ALTURA): if(0 <= c < LARGURA): col = kandinsky.color(cores[cor][0],cores[cor][1],cores[cor][2]) kandinsky.set_pixel(c,l,col) def fill_rect(x,y,L,A,cor): c = int(LARGURA*((x - X_MIN)/(X_MAX - X_MIN))) l = int(ALTURA*(1-(y - Y_MIN)/(Y_MAX - Y_MIN))) _L = int(L*(LARGURA+0.0)/(X_MAX - X_MIN)) _A = int(A*(ALTURA+0.0)/(Y_MAX - Y_MIN)) kandinsky.fill_rect(c,l,_L,_A,cores[cor]) def clr(): kandinsky.fill_rect(0,0,LARGURA,ALTURA+20,cores[BACKGROUND]) def draw_line(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 steps = max(abs(dx), abs(dy)) if(steps!=0): x_step = dx / steps y_step = dy / steps for i in range(steps + 1): x = floor(x1 + i * x_step) y = floor(y1 + i * y_step) kandinsky.set_pixel(x, y, cores[COR]) def Fline(x,y,a,b): c1 = int(LARGURA*((x - X_MIN)/(X_MAX - X_MIN))) l1 = int(ALTURA*(1-(y - Y_MIN)/(Y_MAX - Y_MIN))) c2 = int(LARGURA*((a - X_MIN)/(X_MAX - X_MIN))) l2 = int(ALTURA*(1-(b - Y_MIN)/(Y_MAX - Y_MIN))) draw_line(c1,l1,c2,l2) from math import * #Algebra Linear e Geometria Analitica def array(n): res=[] for i in range(n): res.append(0) return res def matriz(l,c): res=[] for i in range(l): res.append(array(c)) return res def produtoMat(a,b): #AB=C c=[] la,ca,cb=len(a),len(a[0]),len(b[0]) c=matriz(la,cb) for i in range(la): for j in range(cb): for k in range(ca): c[i][j]+=a[i][k]*b[k][j] return c def produtoMQVector(a,b):#AB=C, A matriz quadrada, B e C vectores dim=len(a) c=[] for i in range(dim): c.append(0) for i in range(dim): for j in range(dim): c[i]+=a[i][j]*b[j] return c def somaMat(a,b):#c=a+b l,col=len(a),len(a[0]) c=matriz(l,col) for i in range(l): for j in range(col): c[i][j]=a[i][j]+b[i][j] def RotX(a): c,s=cos(a),sin(a) Rx=[ [1,0,0], [0,c,-s], [0,s,c] ] return Rx def RotY(a): c,s=cos(a),sin(a) Ry=[ [c,0,s], [0,1,0], [-s,0,c] ] return Ry def RotZ(a): c,s=cos(a),sin(a) Rz=[ [c,-s,0], [s,c,0], [0,0,1] ] return Rz def somaVect(a,b): dim=len(a) c=array(dim) for i in range(dim): c[i]=a[i]+b[i] def subtrVect(a,b): dim=len(a) c=array(dim) for i in range(dim): c[i]=a[i]-b[i] def prodEscalar(u,v): dim=len(u) res=0 for i in range(dim): res+=u[i]*v[i] return res def norm2Vect(v): dim=len(v) res=0 for i in range(dim): res+=v[i]*v[i] return sqrt(res) ############################################# phi,theta,alpha,w=0,0,0,2 R,Rx,Ry,Rz,aux=[],[],[],[],[] x=array(3) wireframe=0 alter=[0,0,0]#0:cores-1:velocidades-2:rot p=Cuboctaedro() v=matriz(p.nv,3) RUN=True while RUN==True: if keydown(KEY_ALPHA): INVERT,alter[0],alter[1]=1,1,0 if keydown(KEY_BACKSPACE): alter[1]=(1+alter[1])%2 if keydown(KEY_SHIFT): INVERT,alter[0]=0,1 elif keydown(KEY_ZERO): alter,w=[1,0,0],2 BACKGROUND,COR,INVERT=1,0,0 elif keydown(KEY_ONE): descarregaPoliedro(p) p=Tetraedro() v=matriz(p.nv,3) elif keydown(KEY_TWO): descarregaPoliedro(p) p=Cubo() v=matriz(p.nv,3) elif keydown(KEY_THREE): descarregaPoliedro(p) p=Octaedro() v=matriz(p.nv,3) elif keydown(KEY_FOUR): descarregaPoliedro(p) p=Dodecaedro() v=matriz(p.nv,3) elif keydown(KEY_FIVE): descarregaPoliedro(p) p=Icosaedro() v=matriz(p.nv,3) elif keydown(KEY_SIX): descarregaPoliedro(p) p=Cuboctaedro() v=matriz(p.nv,3) #wireframe=1 #alter[2]=1 elif keydown(KEY_NINE): if(p.nf > 0): wireframe=1-wireframe if keydown(KEY_PLUS): X_MIN *= ZF X_MAX *= ZF Y_MIN *= ZF Y_MAX *= ZF if keydown(KEY_MINUS): X_MIN /= ZF X_MAX /= ZF Y_MIN /= ZF Y_MAX /= ZF if keydown(KEY_MULTIPLICATION): if alter[1]==1: zz+=0.05 elif alter[1]==0: w+=2 if keydown(KEY_DIVISION): if alter[1]==1: zz-=0.05 elif alter[1]==0: w=max((w-2,0)) if keydown(KEY_LEFT): alter[2]=(alter[2]+1)%5 if keydown(KEY_RIGHT): __C=_C _C=(_C+1)%len(cores) if _C==_B: _C=(_C+1)%len(cores) if __C==COR: BACKGROUND,COR=_B,_C else: BACKGROUND,COR=_C,_B if(alter[0]==1): if(INVERT==1): BACKGROUND,COR,INVERT=_C,_B,0 alter[0]=0 else: BACKGROUND,COR=_B,_C if alter[2]!=1: Rz=RotZ(-(phi/180.0)*pi) Rx=RotX(-(alpha/180.0)*pi) Ry=RotY(theta*pi/180.0) aux=produtoMat(Ry,Rx) R=produtoMat(Rz,aux) else: Rz=RotZ(-(phi/180.0-0.5)*pi) Rx=RotX(-(theta/180.0-0.5)*pi) Ry=RotY(alpha*pi/180.0) aux=produtoMat(Rx,Rz) R=produtoMat(Ry,aux) Rz=RotZ((phi/180.0-0.5)*pi) Rx=RotX((theta/180.0-0.5)*pi) aux=produtoMat(Rx,R) R=produtoMat(Rz,aux) for k in range(p.nv): for i in range(3): x[i]=p.v[k][i] r=produtoMQVector(R,x) for i in range(3): v[k][i]=r[i] if wireframe==1: for k in range(p.na): i=p.arestas[k*2+0] j=p.arestas[k*2+1] Fline(v[i][0],v[i][2],v[j][0],v[j][2]); else: if ( isinstance(p.nl, int )): for k in range(p.nf): for i in range(3): x[i]=p.normais[k][i] r=produtoMQVector(R,x) if(prodEscalar(r,olho)>0): for l in range(p.nl): i=p.faces[k*p.nl+l] j=p.faces[k*p.nl+(l+1)%(p.nl)] Fline(v[i][0],v[i][2],v[j][0],v[j][2]) else: for k in range(p.nf): for i in range(3): x[i]=p.normais[k][i] r=produtoMQVector(R,x) #r=olho if(prodEscalar(r,olho)>0): for l in range(p.nl[k]): i=p.faces[k][l] j=p.faces[k][(l+1)%(p.nl[k])] Fline(v[i][0],v[i][2],v[j][0],v[j][2]) time.sleep(zz) clr() if alter[2]==0 or alter[2]==2: #vou juntar +alguns phi,theta,alpha=(phi+w)%360,(theta+w)%360,(alpha+w)%360 elif alter[2]==1: phi,theta,alpha=(phi+2)%360,0,0 elif alter[2]==3: phi,theta,alpha=0,(theta+w)%360,0 elif alter[2]==4: phi,theta,alpha=0,0,(alpha+w)%360