Projective transformation matrix: Difference between revisions

From JSXGraph Wiki
No edit summary
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
<html>
<table id="jxg_output"></table>
</html>
<jsxgraph width="600" height="600">
<jsxgraph width="600" height="600">
     var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-10, 10, 10, -10]});
     var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-10, 10, 10, -10]});
Line 4: Line 8:
     // Compute a projective transformation which maps the polygon p1 to the polygon p2.
     // 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 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});
     var p2 = board.create('polygon', [[2,-3], [7,-4], [5,3], [4,4]], {fillColor: 'yellow'});


     // Two global variables containing the transformation matrix (in vector and in matrix form)
     // Two global variables containing the transformation matrix (in vector and in matrix form)
Line 49: Line 53:
         }
         }


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


Line 75: Line 79:
     }
     }
</jsxgraph>
</jsxgraph>
<html>
<pre id="jxg_output" cols="50" rows="20"></pre>
</html>


===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]]

Latest revision as of 10: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();
        });
    }