graph_3d.py

Created by benoitp

Created on February 08, 2022

6.21 KB


from math import *
from kandinsky import *
from ion import *
from time import sleep


anglePerspective=pi/6
ko=2**(-.5)

def clear():
  fill_rect(0,0,320,240,color(255,255,255))

def drawl(A,B):
  x1=round(A[0])
  x2=round(B[0])
  y1=round(A[1])
  y2=round(B[1])
  if x1>x2:
    x1,y1,x2,y2=x2,y2,x1,y1
  if x1==x2:
    for i in range(min(y1,y2),max(y1,y2)+1):
      set_pixel(x1,i,color(0,0,0))
    return
  a=(y2-y1)/(x2-x1)
  if a<=1 and a>=-1:
    for i in range(x1,x2+1):
      set_pixel(i,y1+round((i-x1)*a),color(0,0,0))
    return
  if y1>y2:
    x1,y1,x2,y2=x2,y2,x1,y1
  for i in range(y1,y2+1):
    set_pixel(round(i/a+x1-y1/a),i,color(0,0,0))

def c3d22d(x,y,z,rot1,rot2,rot3):
  x,y,z=rotate(x,y,z,rot1,rot2,rot3)
  x2=x+ko*y*cos(anglePerspective)
  y2=-z-ko*y*sin(anglePerspective)
  return(x2*70+150,y2*70+100)

def rotate(x,y,z,rot1,rot2,rot3):
  #Rotation autour de l'axe Ox
  nx=x
  ny=cos(rot1)*y-sin(rot1)*z
  nz=sin(rot1)*y+cos(rot1)*z
  x,y,z=nx,ny,nz
  
  #Rotation autour de l'axe Oy
  nx=cos(rot2)*x+sin(rot2)*z
  ny=y
  nz=-sin(rot2)*x+cos(rot2)*z
  x,y,z=nx,ny,nz
  
  #Rotation autour de l'axe Oz
  nx=cos(rot3)*x-sin(rot3)*y
  ny=sin(rot3)*x+cos(rot3)*y
  nz=z
  x,y,z=nx,ny,nz
  
  return x,y,z

def drawcube(rot1,rot2,rot3):
  
  draw_string("x",round(c3d22d(1,0,0,rot1,rot2,rot3)[0]),round(c3d22d(1,0,0,rot1,rot2,rot3)[1]))
  draw_string("y",round(c3d22d(0,1,0,rot1,rot2,rot3)[0]),round(c3d22d(0,1,0,rot1,rot2,rot3)[1]))
  draw_string("z",round(c3d22d(0,0,1,rot1,rot2,rot3)[0]),round(c3d22d(0,0,1,rot1,rot2,rot3)[1]))


  drawl(c3d22d(-1,-1,-1,rot1,rot2,rot3),c3d22d(-1,-1,1,rot1,rot2,rot3))
  drawl(c3d22d(-1,-1,-1,rot1,rot2,rot3),c3d22d(-1,1,-1,rot1,rot2,rot3))
  drawl(c3d22d(-1,-1,-1,rot1,rot2,rot3),c3d22d(1,-1,-1,rot1,rot2,rot3))
  
  drawl(c3d22d(-1,-1,1,rot1,rot2,rot3),c3d22d(-1,1,1,rot1,rot2,rot3))
  drawl(c3d22d(-1,-1,1,rot1,rot2,rot3),c3d22d(1,-1,1,rot1,rot2,rot3))

  drawl(c3d22d(-1,1,1,rot1,rot2,rot3),c3d22d(-1,1,-1,rot1,rot2,rot3))
  drawl(c3d22d(-1,1,1,rot1,rot2,rot3),c3d22d(1,1,1,rot1,rot2,rot3))

  drawl(c3d22d(1,1,1,rot1,rot2,rot3),c3d22d(1,1,-1,rot1,rot2,rot3))
  drawl(c3d22d(1,1,1,rot1,rot2,rot3),c3d22d(1,-1,1,rot1,rot2,rot3))
  
  drawl(c3d22d(1,1,-1,rot1,rot2,rot3),c3d22d(1,-1,-1,rot1,rot2,rot3))
  drawl(c3d22d(1,1,-1,rot1,rot2,rot3),c3d22d(-1,1,-1,rot1,rot2,rot3))
  drawl(c3d22d(1,-1,-1,rot1,rot2,rot3),c3d22d(1,-1,1,rot1,rot2,rot3))

  
  drawl(c3d22d(0,0,-1,rot1,rot2,rot3),c3d22d(0,0,1,rot1,rot2,rot3))
  drawl(c3d22d(0,-1,0,rot1,rot2,rot3),c3d22d(0,1,0,rot1,rot2,rot3))
  drawl(c3d22d(-1,0,0,rot1,rot2,rot3),c3d22d(1,0,0,rot1,rot2,rot3))


def x(t,u):
  return cos(t)*cos(u)
def y(t,u):
  return cos(t)*sin(u)
def z(t,u):
  return sin(t)

def dynamicPlot():
  print("Cette fonction va créer un\nobjet 3d autour duquel vous\npourrez pivoter. Renseignez\nles données, puis l'objet\napparaîtra.Vous pourrez\nutiliser les touches de la\nligne de la touche Shift pour\nle pivoter autour d'un axe.")
  broken=False
  modified=True
  rot1,rot2,rot3=0,0,0
  nbo=int(input("Combien d'objets? 1+"))
  cara_obj=[]
  for itobj in range(nbo):
    print("Définissons l'objet", itobj)
    cara_obj.append(askInfos())
  gr=float(input("zoom (1 conseillé) "))
  while not broken:
    if modified:
      clear()
      for obj in cara_obj:
        xa,ya,za,tmin,tmax,umin,umax,nbstep,maillage=obj
        plot(xa,ya,za,tmin,tmax,umin,umax,rot1,rot2,rot3,nbstep,maillage,gr)
      modified=False
    if keydown(KEY_SHIFT):
      rot1-=.1
      modified=True
    if keydown(KEY_ALPHA):
      rot1+=.1
      modified=True
    if keydown(KEY_XNT):
      rot2-=.1
      modified=True
    if keydown(KEY_VAR):
      rot2+=.1
      modified=True
    if keydown(KEY_TOOLBOX):
      rot3-=.1
      modified=True
    if keydown(KEY_BACKSPACE):
      rot3+=.1
      modified=True
    if keydown(KEY_OK) or keydown(KEY_EXE):
      broken=True
    sleep(.1)
  


def askInfos():
  xas="lambda t,u: "+input("x(t,u)=")
  xa=eval(xas)
  yas="lambda t,u: "+input("y(t,u)=")
  ya=eval(yas)
  zas="lambda t,u: "+input("z(t,u)=")
  za=eval(zas)
  tmin=float(input("tmin "))
  tmax=float(input("tmax "))
  umin=float(input("umin "))
  umax=float(input("umax "))
  nbstep=float(input("precision (20 conseillé) "))
  return xa,ya,za,tmin,tmax,umin,umax,nbstep,1;


def plot(x,y,z,tmin,tmax,umin,umax,rot1=0,rot2=0,rot3=0,nbstep=100,maillage=False,gr=1,cl=(0,0,0)):
  color(cl)
  drawcube(rot1,rot2,rot3)
  ts=(tmax-tmin)/nbstep
  us=(umax-umin)/nbstep
  t=tmin
  if not maillage:
    while t<=tmax:
      u=umin-us
      while u<umax:
        u+=us
        try:
          absc3d=x(t,u)/gr
          ordo3d=y(t,u)/gr
          cote3d=z(t,u)/gr
        except:
          continue
        if abs(absc3d)<=1 and abs(ordo3d)<=1 and abs(cote3d)<=1:
          absc2d,ordo2d=c3d22d(absc3d,ordo3d,cote3d,rot1,rot2,rot3)
          if type(absc2d)!=complex and type(ordo2d)!=complex:
            set_pixel(round(absc2d),round(ordo2d),color(0,0,0))
      t+=ts
  else:
    while t<=tmax:
      u=umin-us
      while u<umax:
        u+=us
        try:
          absc3dP=x(t,u)/gr
          ordo3dP=y(t,u)/gr
          cote3dP=z(t,u)/gr
        except:
          continue
        if abs(absc3dP)<=1 and abs(ordo3dP)<=1 and abs(cote3dP)<=1:
          try:
            absc3dT=x(t+ts,u)/gr
            ordo3dT=y(t+ts,u)/gr
            cote3dT=z(t+ts,u)/gr
            absc3dU=x(t,u+us)/gr
            ordo3dU=y(t,u+us)/gr
            cote3dU=z(t,u+us)/gr
          except:
            continue
          if abs(absc3dT)<=1 and abs(ordo3dT)<=1 and abs(cote3dT)<=1 and t+ts<=tmax:
            absc2d1,ordo2d1=c3d22d(absc3dP,ordo3dP,cote3dP,rot1,rot2,rot3)
            absc2d2,ordo2d2=c3d22d(absc3dT,ordo3dT,cote3dT,rot1,rot2,rot3)
            if type(absc2d1)!=complex and type(ordo2d1)!=complex and type(absc2d2)!=complex and type(ordo2d2)!=complex:
              drawl((absc2d1,ordo2d1),(absc2d2,ordo2d2))
          if abs(absc3dU)<=1 and abs(ordo3dU)<=1 and abs(cote3dU)<=1 and u+us<=umax:
            absc2d1,ordo2d1=c3d22d(absc3dP,ordo3dP,cote3dP,rot1,rot2,rot3)
            absc2d2,ordo2d2=c3d22d(absc3dU,ordo3dU,cote3dU,rot1,rot2,rot3)
            if type(absc2d1)!=complex and type(ordo2d1)!=complex and type(absc2d2)!=complex and type(ordo2d2)!=complex:
              drawl((absc2d1,ordo2d1),(absc2d2,ordo2d2))
      t+=ts

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.