#coding: cp852
from turtle import *
from time import *
from math import *


class Twykres3D(object):
  '''Wykres sˆupkowy 3D.'''
  __ANG__=45			# K¥t nachylenia ozi X.
  __J__=10			# Jednostka 
  __ZERO__=(0,0,0)		# Pozycja zera.
  __DIR__={}			# Kierunki.
#------------------------ .INIT ---------------------------------------
  #--- __init__ ===================================
  def __init__(self,J,A,Z):
    '''Ustawia jednostk© osi i nachylenie osi X. Z - Poˆo¾enie (X,Y)3D - zera.'''
    self.__J__=J
    self.__ANG__=A
    self.__ZERO__=Z
    self.__DIR__['X']=180+A
    self.__DIR__['Y']=0
    self.__DIR__['Z']=90

  #--- toRAD ===================================
  def toRAD(self,A):
    '''Zamienia k¥t A na rad.'''
    return A*pi/180.

  #--- __3Dto2D__ ===================================
  def __3Dto2D__(self,X,Y,Z):
    '''Zmiana wsp¢ˆrz©dnych 3D na 2D.'''
    A=self.toRAD(self.__DIR__['X'])
    return (int(self.__J__*(self.__ZERO__[0]+X*cos(A)+Y)),int(self.__J__*(self.__ZERO__[1]+X*sin(A)+Z)))

  #--- __pos__ ===================================
  def __pos__(self,X,Y,Z):
    '''Ustawia w punkcie (X,Y,Z).'''
    pu()
    setpos(*self.__3Dto2D__(X,Y,Z))
    pd()

  #--- __setDIR__ ===================================
  def __setDIR__(self,DIR):
    '''Ustawia kierunek DIR.'''
    setheading(self.__DIR__[DIR])

  #--- __drawN__ ===================================
  def __drawN__(self,DIR,N=10,fact=1.0):
    '''rysuje o˜ DIR o dˆugo˜ci N z dnego punktu.'''
    self.__setDIR__(DIR)
    for i in range(N):
      self.__draw1__(i,fact)

  #--- __drawN0__ ===================================
  def __drawN0__(self,DIR,N=10,fact=1.0):
    '''Rysuje o˜ DIR o dˆugo˜ci N z punktu "0".'''
    self.__pos__(0,0,0)
    self.__drawN__(DIR,N,fact)

  #--- __axis__ ===================================
  def __axis__(self,**P):
    '''Rysuje wszystkie osie.'''
    for x in ['X','Y','Z']:
      if not x in P: P[x]=10
      self.__drawN0__(x,P[x],2. if x=='Y' else 1.0 )
  
  #--- __draw1__ ===================================
  def __draw1__(self,I,fact=1.):
    '''rysuje odcinek jednostkowy.'''
    fd(self.__J__)
    tic=int(self.__J__/30.)
    if tic==0:tic=2
    for x in range(2):  #---.90,-,180,-,19
      rt(90)
      fd(tic)
      rt(90)
    I+=1
    if I%int(fact)==0:
      write('%0.1f'%(I/fact))

  #--- fdN ===================================
  def fdN(self,D,A):
    '''Rysuje A krok¢w w kierunku D.'''
    self.__setDIR__(D)
    fd(A*self.__J__)

  #--- __drawBAR__ ===================================
  def __drawBAR__(self,X,Y,Z,dX,dY,dZ,C):
    '''Rysuje sˆupek 3D w kolorze C (zmodyfikowanym) (X,Y,Z)-wsp¢ˆrz©dne punktu: tylnego,lewego,dolnego. dX,dY,dZ - wymiary w osiach.'''
    def fdK(D):
      '''Ruch w kierunku D o szeroko˜† kierunkow¥.'''
      if D in ['x','y','z']:			# maˆe litery oznaczaj¥ minus.
        K=-1
        D=D.upper()
      else:
        K=+1
      self.fdN(D,K*(dX if D=='X' else dY if D=='Y' else dZ))

    def isWALL(S):
      '''Sprawdza czy ˜ciana ndla sekwencji S ma oba wymiary r¢¾ne od 0.'''
      for s in S.upper():
        if s =='X' and dX==0:return False
        if s =='Y' and dY==0:return False
        if s =='Z' and dZ==0:return False
      return True

    def drawWALL(S,CX,dP,T=''):
      '''Rysuje ˜cian© wg wzorca S w kolorze dodatkowym CX dodaje dP.'''
      SS='XYZ'
      for s in SS:
        if not s in S:
          A=s
      S+=S.lower()
      print('S:',S,A)
      if isWALL(S):			# Dolna ˜ciana
        color(C,CX)
        if A=='X': self.__pos__(X+dP,Y,Z)
        if A=='Y': self.__pos__(X,Y+dP,Z)
        if A=='Z': self.__pos__(X,Y,Z+dP)
        begin_fill()
        for x in S:
          fdK(x)
        end_fill()
        if T:
          write(T,font=('Arial',11))

    colormode(255)			# Zakres kolor¢w 0..255
    (R,G,B)=C
    C1=(R+10,G+10,B+10)			# Troch© ja˜niejszy kolor
    C2=(R+40,G+40,B+40)               	# Wyra«nie ja˜niejszy kolor

    if dZ<0:
      drawWALL('YX',C2,0,'%s'%dZ)		# Dolna ˜ciana
    else:
      drawWALL('YX',C2,0)			# Dolna ˜ciana
    drawWALL('ZY',C,dX)                 	# Przednia ˜ciana
    drawWALL('ZX',C1,dY)                	# Boczna ˜ciana
    if dZ>=0:                           	# Gdy sˆupek dodatni rysuje:
      drawWALL('YX',C2,dZ,'%s'%dZ)              # G¢rna ˜ciana 

# --- Powi©kszenie na caˆy ekran. ----
screen = Screen()				# Praca na ekranie.

# --- FULL SCREEN ---
root = screen._root				# Dost©p do ekranu.
root.attributes("-fullscreen", True)		# Powi©kszenie okna na caˆy ekran.

sleep(1)
# --- Bˆyskawiczne rysowanie --- ## Wyˆacza animacje (zmniejsza ilo˜c klatek).
tracer(20, 5)
ht()						# HIDE Turtle
speed(0)
# --- Wykres (losowy) ---
W=Twykres3D(20,45,(-10,+2))
W.__axis__(X=22,Y=30,Z=16)

for y in range(20):
  for x in range(10):       
    W.__drawBAR__(x*2.2,y*2.2,0,2,2,(6+(-(y+x))if x%3!=y%5 else+(x+y))/2.,(180 if x%3==0 else 25,180 if x%3==1 else 25,180 if x%3==2 else 25))

q=0
Y=2000
for y in range(0,20,2):
  W.__pos__(24+q,2*y,0)
  write('%s.%s'%(Y,q),font=('Times New Roman',14))
  q=(q+1)%8/2
  if q==0:
    Y+=1
     
sleep(15)
