maths_vectoriel.py

Created by antarctus

Created on March 17, 2023

3.75 KB

Affichage graphique des relations entre deux vecteurs.
Il y a leur coordonnées, le déterminants, le produit scalaire, l’angle formé et leur norme.


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


def draw_sqrt(txt,x,y,c1=(0,)*3,c2=(255,)*3):
  draw_string("V",x,y-1,c1,c2)
  draw_string(txt,x+10,y,c1,c2)
  fill_rect(x+8,y+1,len(txt)*10+2,1,c1)

def draw_vector(txt_list,x,y,c1=(0,)*3,c2=(255,)*3):
  max_=max([len(i) for i in txt_list])
  fill_rect(x,y,20+10*max_,20*len(txt_list),c2)
  for i in [0,1]:
    x_=[0,10+max_*10][i]
    draw_string("()"[i],x+x_,y,c1,c2)
    draw_string("()"[i],x+x_,y+20*(len(txt_list)-1),c1,c2)
    fill_rect(x+x_  ,y+9,10,20*(len(txt_list)-1),c2)
    fill_rect(x+x_+3+i*4,y+9,1 ,20*(len(txt_list)-1),c1)
  for i in range(len(txt_list)):
    draw_string(txt_list[i],x+10,y+20*i,c1,c2)


v=[1,0]
u=[0,1]
focus=0

def draw_line(x1,y1,x2,y2,c):
  width=x2-x1
  height=y2-y1
  if (x1-x2)**2+(y1-y2)**2==0:
    return
  if abs(width)>=abs(height):
    div=height/width
    for i in range(0,width,(width>0)*2-1):
      set_pixel(x1+i,y1+int(div*i+0.5),c)
  else:
    div=width/height
    for i in range(0,height,(height>0)*2-1):
      set_pixel(x1+int(div*i+0.5),y1+i,c)

def norm2(v):
  return v[0]**2+v[1]**2

def norm(v):
  return sqrt(norm2(v))

def prod(v,u):
  return (v[0]*u[0]+v[1]*u[1])

def det(u,v):
  return (v[0]*u[1]-v[1]*u[0])

def ang(u,v):
  return degrees(acos(prod(u,v)/norm(u)/norm(v)))

def str_ang(u,v):
  try:
    a=int(ang(u,v)*1000+0.5)/1000
  except:
    return "undef"
  if int(a)==a:
    a=int(a)
  return str(a)+"°"


def draw_enbou(x,y,n=3,c=(0,)*3):
  for i in range(n):
    set_pixel(x-i,y-i,c)
    set_pixel(x-i,y+i,c)

def draw_enbou_verti(x,y,n=3,c=(0,)*3):
  for i in range(n):
    set_pixel(x-i,y+i,c)
    set_pixel(x+i,y+i,c)

def draw_vect_txt(txt,x,y,c1=(0,)*3,c2=(255,)*3):
  draw_string(txt,x,y,c1,c2)
  fill_rect(x,y+1,len(txt)*10,1,c1)
  draw_enbou(x+len(txt)*10,y+1,3,c1)

def draw_vect(x,y,c,focus=False):
  x,y=160+20*x,80-20*y
  if focus:
    fill_rect(x-5,y-5,10,10,focus)
  fill_rect(x-3,y-3,6,6,c)
  draw_line(160,80,x,y,c)

def draw_grid():
  for x in range(16):
    fill_rect(x*20,0,1,160,(120,)*3)
  for y in range(8):
    fill_rect(0,y*20,320,1,(120,)*3)
  fill_rect(159,0,2,160,(120,)*3)
  fill_rect(0,79,320,2,(120,)*3)
  for i in range(2):
    draw_enbou_verti(159+i,0,6,(120,)*3)
    draw_enbou(320,79+i,6,(120,)*3)

def draw_all_vect():
  draw_vect(u[0],u[1],(255,0,0),[(200,200,0),None][focus])
  draw_vect(v[0],v[1],(0,0,255),[None,(200,200,0)][focus])

def undraw_all_vect():
  draw_vect(u[0],u[1],(255,)*3,(255,)*3)
  draw_vect(v[0],v[1],(255,)*3,(255,)*3)

def draw_all():
  draw_grid()
  draw_all_vect()
  fill_rect(0,160,320,2,(0,)*3)
  fill_rect(0,162,320,60,(255,)*3)

  decal=100
  for i in range(2):
    col=[(255,0,0),(0,0,255)][i]
    draw_vect_txt("uv"[i],5+decal*i,172,col,(255,)*3)
    draw_string("=",15+decal*i,172,col,(255,)*3)
    draw_vector([str(j) for j in [u,v][i]],25+decal*i,162,col,(255,)*3)

    draw_string("|| ||=",5+decal*i,202,col,(255,)*3)
    draw_vect_txt("uv"[i],17+decal*i,202,col,(255,)*3)
    draw_sqrt(str(norm2([u,v][i])),55+decal*i,202,col,(255,)*3)


  for i in range(3):
    draw_string(["det( ; )=","·  =","( ; )="][i],[170,220,200][i],165+i*20)
    draw_vect_txt("u",210,165+i*20,(255,0,0),(255,)*3)
    draw_vect_txt("v",230,165+i*20,(0,0,255),(255,)*3)
    draw_string(str([det(u,v),prod(u,v),str_ang(u,v)][i]),260,165+i*20)


fill_rect(0,0,320,222,(255,)*3)
draw_all()
while not keydown(KEY_EXE):
  while not (keydown(0) or keydown(1) or keydown(2) or keydown(3) or keydown(KEY_OK) or keydown(KEY_EXE)):
    pass
  if keydown(KEY_OK):
    undraw_all_vect()
    focus=1-focus
    draw_all()
    while keydown(KEY_OK):
      pass
  else:
    undraw_all_vect()
    [u,v][focus][0]+=keydown(KEY_RIGHT)-keydown(KEY_LEFT)
    [u,v][focus][1]+=keydown(KEY_UP)-keydown(KEY_DOWN)
  draw_all()
  sleep(0.1)