Difference between revisions of "Projective transformation matrix"

From JSXGraph Wiki
Jump to navigationJump to search
Line 53: Line 53:
 
         }
 
         }
  
         //try {
+
         // Output of the transformation matrix
            var txt = '';
+
        var txt = '';
            for (i = 0; i < 3; i++) {
+
        for (i = 0; i < 3; i++) {
                txt += '<tr><td>' + mat_global[i].join('</td><td>') + '</td></tr>\n';
+
            txt += '<tr><td>' + mat_global[i].join('</td><td>') + '</td></tr>\n';
            }
+
        }
            document.getElementById('jxg_output').innerHTML = txt;
+
        document.getElementById('jxg_output').innerHTML = txt;
            console.log(txt);
 
        //} catch (err) {};
 
 
 
 
     };
 
     };
  
Line 85: Line 82:
 
===The underlying JavaScript code===
 
===The underlying JavaScript code===
 
<source lang="javascript">
 
<source lang="javascript">
 +
    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();
 +
        });
 +
    }
 
</source>
 
</source>
  
 
[[Category:Examples]]
 
[[Category:Examples]]
 
[[Category:Geometry]]
 
[[Category:Geometry]]

Revision as of 12:19, 22 July 2020

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();
        });
    }