<iframe src="https://jsxgraph.uni-bayreuth.de/share/iframe/soccer-offside-line" style="border: 1px solid black; overflow: hidden; width: 550px; aspect-ratio: 55 / 65;" name="JSXGraph example: Soccer offside line" allowfullscreen ></iframe>
<div id="board-0-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-0" class="jxgbox" style="aspect-ratio: 4 / 3; width: 30%;" data-ar="4 / 3"></div> </div> <div id="board-1-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-1" class="jxgbox" style="aspect-ratio: 4 / 3; width: 30%;" data-ar="4 / 3"></div> </div> <div id="board-2-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-2" class="jxgbox" style="aspect-ratio: 4 / 3; width: 30%;" data-ar="4 / 3"></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 BOARDID0 = 'board-0'; const BOARDID1 = 'board-1'; const BOARDID2 = 'board-2'; const BOARDID = BOARDID0; const board1 = JXG.JSXGraph.initBoard(BOARDID0, { boundingbox: [-10, 10, 10, -10] }); const board2 = JXG.JSXGraph.initBoard(BOARDID1, { boundingbox: [-10, 10, 10, -10] }); const board3 = JXG.JSXGraph.initBoard(BOARDID2, { boundingbox: [-10, 10, 10, -10] }); board1.addChild(board2); board1.addChild(board3); // Polygon in camera image var p1 = board1.create('polygon', [[-8, -6], [9, -6], [5, 6.5], [-6, 7]], { fillColor: 'green' }); // Polygon in model view var p2 = board2.create('polygon', [[-5, -4], [5, -4], [5, 4], [-5, 4]], { fillColor: 'green', vertices: { visible: false, fixed: true } }); // Polygon on TV screen (copy of p1) var p3 = board3.create('polygon', [ [() => p1.vertices[0].X(), () => p1.vertices[0].Y()], [() => p1.vertices[1].X(), () => p1.vertices[1].Y()], [() => p1.vertices[2].X(), () => p1.vertices[2].Y()], [() => p1.vertices[3].X(), () => p1.vertices[3].Y()] ], { fillColor: 'green', vertices: { visible: false } }); // // Compute a projective transformation which maps the polygon p1 to the polygon p2. // // Two global variables containing the transformation matrix (in vector and in matrix form) var x_global = [], x2_global = [], mat_global = [[0, 0, 0], [0, 0, 0], [0, 0, 0]], mat2_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]); } // Set up the system of linear equations: // 12 equations and 13 unknowns for the 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; // Right hand side 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]; } } // Invert the matrix to get the inverse transform mat2_global = JXG.Math.inverse(mat_global); // Convert the matrix into vector form for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { x2_global[i * 3 + j] = mat2_global[i][j]; } } }; // First computation of the transformation matrix updateTransformationMatrix(); // Store the transformation vectors in functions // in order to make the JSXGraph transformation dynamic var x_fcts = [], x2_fcts = []; for (let i = 0; i < 9; i++) { x_fcts[i] = () => x_global[i]; x2_fcts[i] = () => x2_global[i]; } // Create the transform from p1 to p2 and its inverse. var transform = board1.create('transform', x_fcts, { type: 'generic' }); var transform2 = board2.create('transform', x2_fcts, { type: 'generic' }); // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. for (let i = 0; i < 4; i++) { p1.vertices[i].on('drag', updateTransformationMatrix); } var player = { fillColor: 'white', strokeColor: 'black', size: 6 }; // Set a point in the camera image var A = board1.create('point', [-2.5, 0], player); // Create its image and a vertical line through the point in the model var A2 = board2.create('point', [A, transform], player); var line1 = board2.create('segment', [ [() => A2.X(), -4], [() => A2.X(), 4]], { strokeColor: 'yellow' }); // Transform the point and the line into the TV screen var A3 = board3.create('point', [A2, transform2], player); var line2 = board3.create('segment', [line1, transform2], { strokeColor: 'yellow' }); </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 BOARDID0 = 'your_div_id_0'; // Insert your 1st board id here! const BOARDID1 = 'your_div_id_1'; // Insert your 2nd board id here! const BOARDID2 = 'your_div_id_2'; // Insert your 3rd board id here! const board1 = JXG.JSXGraph.initBoard(BOARDID0, { boundingbox: [-10, 10, 10, -10] }); const board2 = JXG.JSXGraph.initBoard(BOARDID1, { boundingbox: [-10, 10, 10, -10] }); const board3 = JXG.JSXGraph.initBoard(BOARDID2, { boundingbox: [-10, 10, 10, -10] }); board1.addChild(board2); board1.addChild(board3); // Polygon in camera image var p1 = board1.create('polygon', [[-8, -6], [9, -6], [5, 6.5], [-6, 7]], { fillColor: 'green' }); // Polygon in model view var p2 = board2.create('polygon', [[-5, -4], [5, -4], [5, 4], [-5, 4]], { fillColor: 'green', vertices: { visible: false, fixed: true } }); // Polygon on TV screen (copy of p1) var p3 = board3.create('polygon', [ [() => p1.vertices[0].X(), () => p1.vertices[0].Y()], [() => p1.vertices[1].X(), () => p1.vertices[1].Y()], [() => p1.vertices[2].X(), () => p1.vertices[2].Y()], [() => p1.vertices[3].X(), () => p1.vertices[3].Y()] ], { fillColor: 'green', vertices: { visible: false } }); // // Compute a projective transformation which maps the polygon p1 to the polygon p2. // // Two global variables containing the transformation matrix (in vector and in matrix form) var x_global = [], x2_global = [], mat_global = [[0, 0, 0], [0, 0, 0], [0, 0, 0]], mat2_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]); } // Set up the system of linear equations: // 12 equations and 13 unknowns for the 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; // Right hand side 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]; } } // Invert the matrix to get the inverse transform mat2_global = JXG.Math.inverse(mat_global); // Convert the matrix into vector form for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { x2_global[i * 3 + j] = mat2_global[i][j]; } } }; // First computation of the transformation matrix updateTransformationMatrix(); // Store the transformation vectors in functions // in order to make the JSXGraph transformation dynamic var x_fcts = [], x2_fcts = []; for (let i = 0; i < 9; i++) { x_fcts[i] = () => x_global[i]; x2_fcts[i] = () => x2_global[i]; } // Create the transform from p1 to p2 and its inverse. var transform = board1.create('transform', x_fcts, { type: 'generic' }); var transform2 = board2.create('transform', x2_fcts, { type: 'generic' }); // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. for (let i = 0; i < 4; i++) { p1.vertices[i].on('drag', updateTransformationMatrix); } var player = { fillColor: 'white', strokeColor: 'black', size: 6 }; // Set a point in the camera image var A = board1.create('point', [-2.5, 0], player); // Create its image and a vertical line through the point in the model var A2 = board2.create('point', [A, transform], player); var line1 = board2.create('segment', [ [() => A2.X(), -4], [() => A2.X(), 4]], { strokeColor: 'yellow' }); // Transform the point and the line into the TV screen var A3 = board3.create('point', [A2, transform2], player); var line2 = board3.create('segment', [line1, transform2], { strokeColor: 'yellow' });
<jsxgraph width="30%, 30%, 30%" aspect-ratio="4 / 3, 4 / 3, 4 / 3" numberOfBoards="3" title="Soccer offside line" description="This construction was copied from JSXGraph examples database: BTW HERE SHOULD BE A GENERATED LINKuseGlobalJS="false"> /* 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 board1 = JXG.JSXGraph.initBoard(BOARDID0, { boundingbox: [-10, 10, 10, -10] }); const board2 = JXG.JSXGraph.initBoard(BOARDID1, { boundingbox: [-10, 10, 10, -10] }); const board3 = JXG.JSXGraph.initBoard(BOARDID2, { boundingbox: [-10, 10, 10, -10] }); board1.addChild(board2); board1.addChild(board3); // Polygon in camera image var p1 = board1.create('polygon', [[-8, -6], [9, -6], [5, 6.5], [-6, 7]], { fillColor: 'green' }); // Polygon in model view var p2 = board2.create('polygon', [[-5, -4], [5, -4], [5, 4], [-5, 4]], { fillColor: 'green', vertices: { visible: false, fixed: true } }); // Polygon on TV screen (copy of p1) var p3 = board3.create('polygon', [ [() => p1.vertices[0].X(), () => p1.vertices[0].Y()], [() => p1.vertices[1].X(), () => p1.vertices[1].Y()], [() => p1.vertices[2].X(), () => p1.vertices[2].Y()], [() => p1.vertices[3].X(), () => p1.vertices[3].Y()] ], { fillColor: 'green', vertices: { visible: false } }); // // Compute a projective transformation which maps the polygon p1 to the polygon p2. // // Two global variables containing the transformation matrix (in vector and in matrix form) var x_global = [], x2_global = [], mat_global = [[0, 0, 0], [0, 0, 0], [0, 0, 0]], mat2_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]); } // Set up the system of linear equations: // 12 equations and 13 unknowns for the 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; // Right hand side 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]; } } // Invert the matrix to get the inverse transform mat2_global = JXG.Math.inverse(mat_global); // Convert the matrix into vector form for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { x2_global[i * 3 + j] = mat2_global[i][j]; } } }; // First computation of the transformation matrix updateTransformationMatrix(); // Store the transformation vectors in functions // in order to make the JSXGraph transformation dynamic var x_fcts = [], x2_fcts = []; for (let i = 0; i < 9; i++) { x_fcts[i] = () => x_global[i]; x2_fcts[i] = () => x2_global[i]; } // Create the transform from p1 to p2 and its inverse. var transform = board1.create('transform', x_fcts, { type: 'generic' }); var transform2 = board2.create('transform', x2_fcts, { type: 'generic' }); // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. for (let i = 0; i < 4; i++) { p1.vertices[i].on('drag', updateTransformationMatrix); } var player = { fillColor: 'white', strokeColor: 'black', size: 6 }; // Set a point in the camera image var A = board1.create('point', [-2.5, 0], player); // Create its image and a vertical line through the point in the model var A2 = board2.create('point', [A, transform], player); var line1 = board2.create('segment', [ [() => A2.X(), -4], [() => A2.X(), 4]], { strokeColor: 'yellow' }); // Transform the point and the line into the TV screen var A3 = board3.create('point', [A2, transform2], player); var line2 = board3.create('segment', [line1, transform2], { strokeColor: 'yellow' }); </jsxgraph>
// Define the ids of your boards in BOARDID0, BOARDID1,... const board1 = JXG.JSXGraph.initBoard(BOARDID0, { boundingbox: [-10, 10, 10, -10] }); const board2 = JXG.JSXGraph.initBoard(BOARDID1, { boundingbox: [-10, 10, 10, -10] }); const board3 = JXG.JSXGraph.initBoard(BOARDID2, { boundingbox: [-10, 10, 10, -10] }); board1.addChild(board2); board1.addChild(board3); // Polygon in camera image var p1 = board1.create('polygon', [[-8, -6], [9, -6], [5, 6.5], [-6, 7]], { fillColor: 'green' }); // Polygon in model view var p2 = board2.create('polygon', [[-5, -4], [5, -4], [5, 4], [-5, 4]], { fillColor: 'green', vertices: { visible: false, fixed: true } }); // Polygon on TV screen (copy of p1) var p3 = board3.create('polygon', [ [() => p1.vertices[0].X(), () => p1.vertices[0].Y()], [() => p1.vertices[1].X(), () => p1.vertices[1].Y()], [() => p1.vertices[2].X(), () => p1.vertices[2].Y()], [() => p1.vertices[3].X(), () => p1.vertices[3].Y()] ], { fillColor: 'green', vertices: { visible: false } }); // // Compute a projective transformation which maps the polygon p1 to the polygon p2. // // Two global variables containing the transformation matrix (in vector and in matrix form) var x_global = [], x2_global = [], mat_global = [[0, 0, 0], [0, 0, 0], [0, 0, 0]], mat2_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]); } // Set up the system of linear equations: // 12 equations and 13 unknowns for the 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; // Right hand side 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]; } } // Invert the matrix to get the inverse transform mat2_global = JXG.Math.inverse(mat_global); // Convert the matrix into vector form for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { x2_global[i * 3 + j] = mat2_global[i][j]; } } }; // First computation of the transformation matrix updateTransformationMatrix(); // Store the transformation vectors in functions // in order to make the JSXGraph transformation dynamic var x_fcts = [], x2_fcts = []; for (let i = 0; i < 9; i++) { x_fcts[i] = () => x_global[i]; x2_fcts[i] = () => x2_global[i]; } // Create the transform from p1 to p2 and its inverse. var transform = board1.create('transform', x_fcts, { type: 'generic' }); var transform2 = board2.create('transform', x2_fcts, { type: 'generic' }); // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. // Whenever a point of p1 is dragged, the transformation matrix and its // inverse will be updated. for (let i = 0; i < 4; i++) { p1.vertices[i].on('drag', updateTransformationMatrix); } var player = { fillColor: 'white', strokeColor: 'black', size: 6 }; // Set a point in the camera image var A = board1.create('point', [-2.5, 0], player); // Create its image and a vertical line through the point in the model var A2 = board2.create('point', [A, transform], player); var line1 = board2.create('segment', [ [() => A2.X(), -4], [() => A2.X(), 4]], { strokeColor: 'yellow' }); // Transform the point and the line into the TV screen var A3 = board3.create('point', [A2, transform2], player); var line2 = board3.create('segment', [line1, transform2], { strokeColor: 'yellow' });
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.