Ce code affiche des figures (cercles, lignes, ...) et l'image de leurs transformations via une fonction complexes.
Commandes :
t : changer de fonctions complexes
c : changer de figures
p/m : agrandir/rétrécir (via une homothétie)
Approfondissements/sources :
http://xavier.hubaut.info/coursmath/com/complexe.htm
https://en.wikipedia.org/wiki/Joukowsky_transform
http://mathfaculty.fullerton.edu/mathews/c2003/JoukowskiTransMod.html
Le code :
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
###################################
# #
# COURBES COMPLEXES #
# #
# #
# #
# langage : Python 2.7 #
# API : Pygame #
# date : 18/08/16 #
# version : 1.0 #
# auteur : ringo73 #
# #
###################################
import pygame as pg
from pygame.locals import *
from math import pi, cos, sin
from os import popen, environ, name
from pygame.draw import line
try:
from ctypes import windll
except ImportError:
print "Importation non possible de windll."
def getSystemResolutionOnWin():
return windll.user32.GetSystemMetrics(0), windll.user32.GetSystemMetrics(1)
def getSystemResolutionOnLin():
screen = popen("xrandr -q -d :0").readlines()[0]
tmp = screen.split()
return int( tmp[7] ), int( tmp[9][:-1] )
def formulae(t,x,y):
if t == JOUKOWSKY :
if x ** 2 - y ** 2 != 0 :
res = [ x / ( x ** 2 + y ** 2 ) + x , -y / ( x ** 2 + y ** 2 ) + y ]
else:
res = None
elif t == SQUARE :
res = [ x ** 2 - y ** 2 , 2 * x * y ]
elif t == IDENTITY :
res = [ x , y ]
elif t == REVERSE :
if x ** 2 - y ** 2 != 0 :
res = [ x / ( x ** 2 + y ** 2 ) , -y / ( x ** 2 + y ** 2 ) ]
else:
res = None
elif t == CUBE :
res = [ x ** 3 - 3 * x * y ** 2 , 3 * x ** 2 * y - y ** 3 ]
return res
def change_repere(x, y):
x = int(x) + WIN_WIDTH // 2
y = int(-y) + WIN_HEIGH // 2
return [x,y]
def circle_points(r,n,o):
tb = []
theta = 2 * pi / n
for i in range(n) :
tb.append( [ o[X] + r * cos( theta * i ) , o[Y] + r * sin( theta * i ) ] )
return tb
def circles_points(n,o):
tb = []
theta = 2 * pi / n
for r in range(1,WIN_WIDTH//2,4) :
for i in range(n) :
tb.append( [ o[X] + r * cos( theta * i ) , o[Y] + r * sin( theta * i ) ] )
return tb
def lines_ver_points(dx,dy):
tb = []
I, J = WIN_HEIGH // dy, WIN_WIDTH // dx
x, y = 0, 0
for j in range(-J//2,J//2) :
x = j * dx
for i in range(-I//2,I//2+1) :
if j % 2 == 0 :
y = i * dy
else:
y = -i * dy
tb.append( [ x , y ] )
return tb
def lines_hor_points(dx,dy):
tb = []
I, J = WIN_HEIGH // dy, WIN_WIDTH // dx
x, y = 0, 0
for i in range(-I//2,I//2) :
y = i * -dy
for j in range(-J//2,J//2+1) :
if i % 2 == 0 :
x = -j * dx
else:
x = j * dx
tb.append( [ x , y ] )
return tb
#def lines_hor_points(N,n):
#tb = []
#d = WIN_HEIGH / n
#dd = WIN_WIDTH / N
#x, y = 0, 0
#for j in range(-n//2,n//2+1) :
#y = j * d
#for i in range(-N//2,N//2+1) :
#if j % 2 == 0 :
#x = i * dd
#else:
#x = -i * dd
#tb.append( [ x , y ] )
#return tb
def homo(p,k):
return [ p[X] * k , p[Y] * k ]
def compute_fiber(t):
fiber = []
if t == CIRCLE :
fiber = circle_points(1, 1000,(-0.08,0.08))
elif t == CIRCLES :
fiber = circles_points(100,(-0.08,0.08))
elif t == LINES_HOR or t == LINES_ALL :
fiber = lines_hor_points(3, 3)
elif t == LINES_VER :
fiber = lines_ver_points(3, 3)
if t == LINES_ALL :
fiber += lines_ver_points(3, 3)
return fiber
def transform_and_print(bg, trans, k, tf):
fiber = compute_fiber(tf)
image = [ formulae(trans, *e) for e in fiber ]
i = 0
line(bg, BRIGHTBLUE, (0,WIN_HEIGH//2), (WIN_WIDTH-1,WIN_HEIGH//2), 2)
line(bg, BRIGHTBLUE, (WIN_WIDTH//2,0), (WIN_WIDTH//2,WIN_HEIGH-1), 2)
for i in range(1,len(fiber)) :
line(bg, BLACK, change_repere(*homo(fiber[i-1],k)), change_repere(*homo(fiber[i],k)), 1)
i = 0
while i < len(image) :
if image[i] == None :
image.remove( image[i] )
else:
i += 1
for i in range(1,len(image)) :
line(bg, RED, change_repere(*homo(image[i-1],k)), change_repere(*homo(image[i],k)), 1)
def main():
tps = [ 0.0 , 0.0 ]
para = [ IDENTITY , 1.0 , LINES_ALL ]
raffraichir = True
zoom = 1.0
# Initialisation de la fenêtre d'affichage
environ['SDL_VIDEO_CENTERED'] = '1'
pg.init()
screen = pg.display.set_mode((WIN_WIDTH, WIN_HEIGH), pg.DOUBLEBUF | pg.HWSURFACE)
pg.display.set_caption("Courbes complexes")
pg.key.set_repeat (500, 30)
bg = pg.Surface(screen.get_size())
# Initialisation de l'horloge
clock = pg.time.Clock()
# Affichage d'un texte
#font = pg.font.SysFont("arial", FONT_SIZE)
#textpos = [ WIN_WIDTH * 0.05 , WIN_HEIGH * 0.07 ]
# Boucle d'évènements
while True :
# S'assurer que le jeu ne fonctionne pas à plus de 60 images par secondes
clock.tick(60)
tps[PRES] = pg.time.get_ticks()
for event in pg.event.get():
if event.type == pg.QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
exit()
elif event.type == KEYDOWN and event.key == K_t :
raffraichir = True
para[0] = ( para[0] + 1 ) % 5
if para[0] == SQUARE :
para[1] = 1.0
para[2] = LINES_ALL
elif para[0] == CUBE :
para[1] = 0.125
para[2] = LINES_ALL
elif para[0] == JOUKOWSKY :
para[1] = 200.0
para[2] = CIRCLE
elif event.type == KEYDOWN and event.key == K_c :
raffraichir = True
para[2] = ( para[2] + 1 ) % 5
elif event.type == KEYDOWN and event.key == K_p :
raffraichir = True
para[1] *= 2
elif event.type == KEYDOWN and event.key == K_m :
raffraichir = True
para[1] /= 2
if raffraichir :
raffraichir = False
bg.fill(WHITE)
#bg.blit(font.render("Polyedre : " + POLYEDRE[actual_poly], 1, BLACK), textpos)
transform_and_print(bg, *para)
print [ FUNCTIONS[para[0]] , "k = " + str(para[1]) , DRAWINGS[para[2]] ]
screen.blit(bg, (0, 0))
tps[PAST] = tps[PRES]
pg.display.flip()
#############################
#########constantes##########
#############################
if name == "nt" :
WIN_WIDTH, WIN_HEIGH = getSystemResolutionOnWin()
elif name == "posix" :
WIN_WIDTH, WIN_HEIGH = getSystemResolutionOnLin()
else:
WIN_WIDTH = 500
WIN_HEIGH = 380
WIN_WIDTH = int( WIN_WIDTH * 0.8 )
WIN_HEIGH = int( WIN_HEIGH * 0.8 )
#FONT_SIZE = int( WIN_WIDTH * 0.05 )
#FREQ = 4
#Mouse Button, Scroll Wheel
MB_LEFT, MB_MIDDLE, MB_RIGHT, MBSW_UP, MBSW_DOWN = 1, 2, 3, 4, 5
# R G B
WHITE = (250, 250, 250)
BLACK = ( 10, 10, 10)
GREEN = ( 0, 155, 0)
BRIGHTBLUE = ( 0, 50, 255)
BROWN = (174, 94, 0)
RED = (200, 0, 0)
#############################
########enumerations#########
#############################
PRES, PAST, DELAY = 0, 1, 2
X, Y, Z = 0, 1, 2
IDENTITY, SQUARE, CUBE, JOUKOWSKY, REVERSE = 0, 1, 2, 3, 4
LINES_HOR, LINES_VER, LINES_ALL, CIRCLE, CIRCLES = 0, 1, 2, 3, 4
#############################
########dictionnaires########
#############################
DRAWINGS = { LINES_HOR : "LINES_HOR" , LINES_VER : "LINES_VER" , LINES_ALL : "LINES_ALL" , CIRCLE : "CIRCLE" , CIRCLES : "CIRCLES" }
FUNCTIONS = { CUBE : "CUBE" , JOUKOWSKY : "JOUKOWSKY" , IDENTITY : "IDENTITY" , SQUARE : "SQUARE" , REVERSE : "REVERSE" }
if __name__ == '__main__' : main()
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.