cubo6.py

Created by cpaulof

Created on February 23, 2025

14 KB

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

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.