Frédéric Mélantois
WPF : Les transformations et les calculs matriciels
Le framework WPF permet d’effectuer un grand nombre de transformations sur des éléments héritant de la classe UIElement. Nous allons détailler les calculs matriciels.
Par Frédéric Mélantois publié le 16/11/2008 à 22:30, lu 2372 fois, 5 pages
 2 | Transformations et calculs matriciels : un peu de théorie
Etudions la formulation mathématique d’une rotation d’un objet sur lui-même dans un plan. L’angle de rotation sera beta.
Supposons que la rotation se fasse à l’origine. Un point en position p(p0,p1) subira une rotation en p’(p’0,p’1).
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image1.jpeg
 
On peut écrire :
P0 = p cos(alpha) et p1 = p sin(alpha)
De même que :
P’0 = p cos(alpha+beta)
P’0 = p cos(alpha) cos(beta) – p sin(alpha) sin(beta)
On applique la simplification :
P’0 = p0 cos(beta) – p1 sin(beta)
On fait la même chose pour p’1 :
P’1 = p sin(alpha+beta)
p’1 = p cos(alpha) sin(beta) + p sin(alpha) cos(beta)
p’1 = p0 sin(beta) + p1 cos(beta)
La rotation peut être décrite par une matrice 3x3 :
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image2.jpeg
 
Que l’on modifie puisque l’axe des y se trouve « vers le bas » sur un ordinateur :
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image3.jpeg
 
Cette transformation permettra d’effectuer une rotation autour du point d’origine en (0,0). Si notre objet ne se trouve pas à l’origine, celui-ci ne pourra pas effectuer une rotation sur lui-même avec l’application de cette matrice. Il convient donc de placer l’objet à l’origine, d’effectuer la rotation et de replacer l’objet roté à sa position initiale :
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image4.jpeg
 
Une translation dans le plan peut être décrite par la matrice :
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image5.jpeg
 
La rotation d’un objet sur lui-même peut donc être écrite par une translation, une rotation puis une translation :
 
/content/40bf7d2b-c4be-4896-b9b0-d3a470b77591/image6.jpeg
 
On comprend bien par cette formule que l’on réduit le nombre d’opérations matricielles pour le cas particulier d’une rotation d’un objet sur lui-même. Si nous devions écrire une classe prenant en charge le calcul matriciel, nous pourrions l’écrire de cette façon :

public class Matrice

{

    private double[,] mat;

 

    public Matrice()

    {

        mat = new double[3, 3];

        for (int row = 0; row < 3; row++)

            for (int col = 0; col < 3; col++)

            {

                mat[row, col] = (row == col) ? 1.0 : 0.0;

            }

    }

 

    public double this[int row, int col]

    {

        get { return mat[row, col]; }

        set { mat[row, col] = value; }

    }

 

 

    public static Matrice operator *(Matrice m1, Matrice m2)

    {

        Matrice m = new Matrice();

        for (int row = 0; row < 3; row++)

            for (int col = 0; col < 3; col++)

            {

                m[row, col] = 0;

                for (int cpt = 0; cpt < 3; cpt++)

                {

                    m[row, col] += m1[row, cpt] * m2[cpt, col];

                }

            }

 

        return m;

    }

 

    public static Matrice Translation(double dx, double dy)

    {

        Matrice m = new Matrice();

        m[0, 2] = dx;

        m[1, 2] = dy;

        return m;

    }

 

    public static Matrice Rotation(double dx, double dy, double angle)

    {

        Matrice m = new Matrice();

        double c = Math.Cos(angle);

        double s = Math.Sin(angle);

 

        m[0, 0] = c;

        m[0, 1] = -s;

        m[0, 2] = dx * (1 - c) + (dy * s);

        m[1, 0] = s;

        m[1, 1] = c;

        m[1, 2] = dy * (1 - c) - (dx * s);

        m[2, 0] = m[2, 1] = 0;

        m[2, 2] = 1;

        return m;

    }

}

Il nous faudrait rajouter la multiplication prenant en compte un point et nous aurions les bases pour effectuer des transformations dans le plan. Toutefois, cette écriture est bien loin d’être optimisée. En effet, l’utilisation des tableaux multidimensionnels n’est pas un modèle de performance.
 
» Démarrer une discussion