<iframe src="http://jsxgraph.uni-bayreuth.de/share/iframe/projective-transformation-matrix" style="border: 1px solid black; overflow: hidden; width: 550px; aspect-ratio: 55 / 65;" name="JSXGraph example: Projective transformation matrix" allowfullscreen ></iframe>
<table id="jxg_output"></table> <div id="board-0-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-0" class="jxgbox" style="aspect-ratio: 1 / 1; width: 100%;" data-ar="1 / 1"></div> </div> <script type = "text/javascript"> /* This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'board-0'; var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-10, 10, 10, -10], keepaspectratio: true }); // 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' }); // 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(); }); } </script>
/* This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'your_div_id'; // Insert your id here! var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-10, 10, 10, -10], keepaspectratio: true }); // 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' }); // 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(); }); }
<table id="jxg_output"></table>
// Define the id of your board in BOARDID var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-10, 10, 10, -10], keepaspectratio: true }); // 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' }); // 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(); }); }
This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits.