Projective transformation matrix

From JSXGraph Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

The underlying JavaScript code

    var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-10, 10, 10, -10]});

    // Compute a projective transformation which maps the polygon p1 to the polygon p2.
    var p1 = board.create('polygon', [[-5,0], [0,0], [0,7], [-5,7]], {fillColor: 'yellow'});
    var p2 = board.create('polygon', [[2,-3], [7,-4], [5,3], [4,4]], {fillColor: 'yellow', visible: false});

    // Two global variables containing the transformation matrix (in vector and in matrix form)
    var x_global = [];
    var mat_global = [[0,0,0], [0,0,0], [0,0,0]];

    // This function computes the transformation matrix
    var updateTransformationMatrix = function() {
        var i, j, k, M = [];

        // Initialise a 13x13 matrix to zero.
        for (i = 0; i < 13; i++) {
            M.push([0,0,0,0,0, 0,0,0,0,0, 0,0,0]);
        }

        // 12 equations and 13 unknowns for the transformation matrix mat_global such that
        // mat_global * p1 - p2 * (i, j, k, l)^T = 0
        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                for (k = 0; k < 4; k++) {
                    M[i * 4 + k][i * 3 + j] = p1.vertices[k].coords.usrCoords[j];
                }
            }
        }
        for (i = 0; i < 3; i++) {
            for (k = 0; k < 4; k++) {
                M[i * 4 + k][9 + k] = -p2.vertices[k].coords.usrCoords[i];
            }
        }
        // Equation 13: set mat_global[0][0] = 1.
        // Remember that in JSXGraph the coordinates are ordered by (z, x, y)
        M[12][0] = 1;

        // RHS vector
        var b = [0,0,0,0,0, 0,0,0,0,0, 0,0,1];
        // Solve the system
        x_global = JXG.Math.Numerics.Gauss(M, b);

        // Convert the solution vector into matrix form
        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                mat_global[i][j] = x_global[i * 3 + j].toFixed(3);
            }
        }

        // Output of the transformation matrix
        var txt = '';
        for (i = 0; i < 3; i++) {
            txt += '<tr><td>' + mat_global[i].join('</td><td>') + '</td></tr>\n';
        }
        document.getElementById('jxg_output').innerHTML = txt;
    };

    updateTransformationMatrix();

    // Functions which return the coordinates of x_global
    var x_fcts = [];
    for (let i = 0; i < 9; i++) {
        x_fcts[i] = () => x_global[i];
    }

    var transform = board.create('transform', x_fcts, {type: 'generic'});
    var p3 = board.create('polygon', [p1, transform]);

    // Whenever a point of p1 is dragged, the transfomation matrix will be updated.
    for (let i = 0; i < 4; i++) {
        p1.vertices[i].on('drag', function() {
            updateTransformationMatrix();
        });
    }