Créer une classe "matrices"

Résolu/Fermé
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 - 14 avril 2021 à 11:52
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 - 14 avril 2021 à 16:36
Bonjour,

Je pensais maitriser la programmation objet, mais il faut croire qu'il y a encore des détails
qui m'échappent !

Le code suivant doit en principe créer une matrice de rotation suivant Y puis X
mais il ne me retourne que la matrice identité

Si quelqu'un pouvait m'éclairer, ce serait sympa ...

# -*- coding:Latin-1 -*-
#14/04/2021 11:09:32

from copy import *
from math import *

class Matrix(object):

    def __init__(self,l,c):
        self.ln, self.cn = l, c
        self.liste=[[0.0 for j in range(0,c)] for i in range(0,l)]

    def __getitem__(self, ind):
        return self.liste[ind]

    def __repr__(self):
        display = ''
        for k in range(self.ln):
            display += str(self[k])
            if(k != self.ln-1): display += '\n'
        return(display)

    def is_identity(self):
        for k in range(self.ln): self[k][k] = 1.0

    def __mul__(self,other):

        dest = Matrix(4,4)

        for i in range(self.ln):
            for j in range(self.cn):
                dest[i][j] =\
                self[i][0] * other[0][j] +\
                self[i][1] * other[1][j] +\
                self[i][2] * other[2][j] +\
                self[i][3] * other[3][j]

        return dest

    def translation(self,tx,ty,tz):

        for k in range(self.ln): self[k][k] = 1.0
        self[3][0] = tx; self[3][1] = ty; self[3][2] = tz; self[3][3] = 0

    def rotations(self,rx,ry,rz):

        rx, ry, rz = radians(rx), radians(ry), radians(rz)

        xmat =Matrix(4,4)
        ymat =Matrix(4,4)
        zmat =Matrix(4,4)

        xmat[0][0] = 1; xmat[0][1] = 0; xmat[0][2] = 0; xmat[0][3] = 0
        xmat[1][0] = 0; xmat[1][1] = cos(rx); xmat[1][2] = sin(rx); xmat[1][3] = 0
        xmat[2][0] = 0; xmat[2][1] = -sin(rx); xmat[2][2] = cos(rx); xmat[2][3] = 0
        xmat[3][0] = 0; xmat[3][1] = 0; xmat[3][2] = 0; xmat[3][3] = 1

        ymat[0][0] = cos(ry); ymat[0][1] = 0; ymat[0][2] = -sin(ry); ymat[0][3] = 0
        ymat[1][0] = 0; ymat[1][1] = 1; ymat[1][2] = 0; ymat[1][3] = 0
        ymat[2][0] = sin(ry); ymat[2][1] = 0; ymat[2][2] = cos(ry); ymat[2][3] = 0
        ymat[3][0] = 0; ymat[3][1] = 0; ymat[3][2] = 0; ymat[3][3] = 1

        zmat[0][0] = cos(rz); zmat[0][1] = sin(rz); zmat[0][2] = 0; zmat[0][3] = 0
        zmat[1][0] = -sin(rz); zmat[1][1] = cos(rz); zmat[1][2] = 0; zmat[1][3] = 0
        zmat[2][0] = 0; zmat[2][1] = 0; zmat[2][2] = 1; zmat[2][3] = 0
        zmat[3][0] = 0; zmat[3][1] = 0; zmat[3][2] = 0; zmat[3][3] = 1

        #ry, rx, rz
        mat1 = self * ymat
        mat2 = mat1 * xmat
        mat3 = mat2 * zmat
        self = copy(mat3)


#Créer une matrice de rotation x60 y10 z0
mat = Matrix(4,4)
mat.is_identity()
mat.rotations(60.0,10.0,0.0)

print(mat)

input ('\nPresser Entrée ...')



Configuration: Windows / Edge 89.0.774.76
A voir également:

2 réponses

yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024 1 471
14 avril 2021 à 13:03
bonjour,
je me demande si ce n'est pas plutôt un problème de logique.
je ne sais pas trop ce que tu veux obtenir avec ta fonction rotations(), je ne l'ai donc pas testée.
j'ai essayé une fonction plus simple, qui ajoute 1 à tous les éléments de la matrice, et cela me semble bien se comporter.
    def matinc(self):
        for l in range(self.ln):
            for c in range(self.cn):
                self[l][c] += 1
0
yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024 1 471
14 avril 2021 à 13:15
le soucis, c'est la ligne 72. cela fonctionne bien si tu fais une boucle pour copier le contenu de mat3 dans self.
0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748 > yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024
Modifié le 14 avril 2021 à 13:30
Bonjour,

En fait c'est plus une erreur de pointeurs que de programmation objet.

Ton erreur est de vouloir écraser
self
(qui est une recopie de l'adresse mémoire de l'objet courant) par
mat3
, donc cela ne modifie pas l'objet pointé initialement par
self
.

La solution qu'yg_be propose marcherait dans la mesure où
self
n'est pas modifié, et en corrigeant
self.liste
tu corriges bien ce qu'il faut.

Par contre tu n'as même pas besoin de "payer" un
copy
. Comme
self.list
est une adresse, il suffit de la corriger par l'adresse de la liste que tu as calculée :

mat3 = self * ymat * xmat * zmat
self.liste = mat3.liste


Hors sujet mais au cas où : généralement pour du calcul matriciel on aura plutôt tendance à utiliser
numpy
.

Bonne chance
0
yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024 1 471 > yg_be Messages postés 22698 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 avril 2024
14 avril 2021 à 13:31
ta fonction rotations() ne modifie pas le contenu de la matrice mat.
la ligne 72 modifie la variable locale self, pas le contenu de mat.

tu as deux possibilités, au lieu de
self = copy(mat3)
:
1) copier le contenu de mat3 dans self, avec une boucle (ou une fonction copymat).
2) faire
return(mat3)
, et, en ligne 79:
mat=mat.rotations(60.0,10.0,0.0)
0
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 14 avril 2021 à 14:20
Bonjour et merci à tous les deux,

je me doutais un peu que c'était un problème de portée de variable, mais je ne voyais pas
comment traiter ça

Ca fonctionne parfaitement maintenant



A Mamiemando : oui, je connais numpy, je ne l'ai pas installé, mais bon, je m'amuse, ca me fait un exercice, et j'aime bien avoir le contrôle total :-)
0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
14 avril 2021 à 16:03
Parfait, c'est effectivement un bon exercice. Je bascule ton sujet en résolu :-)
0
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178 > mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024
14 avril 2021 à 16:36
Bah, je pouvais le faire moi-même ...

le temps de tondre ma pelouse :-)
0