Projective transformation matrix
From JSXGraph Wiki
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();
});
}