// Numbas version: exam_results_page_options {"name": "Ben's copy of 3 point triangle", "extensions": ["jsxgraph"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"variable_groups": [{"name": "Unnamed group", "variables": []}], "metadata": {"description": "

Draws a triangle based on 3 input points. Calculates length, area, perimeter, heights and internal angles

", "licence": "Creative Commons Attribution 4.0 International"}, "advice": "

(i) To find $f(\\var{x1})$, you start at $\\var{x1}$ on the $x$-axis, go up or down until you reach the blue line, and then look at the $y$-coordinate. This $y$-coordinate is the answer.  In this question, after going up/down from $\\var{x1}$, we reach the $y$-coordinate $\\var{y1}$, so the answer is $f(\\var{x1})=\\var{y1}$.

\n

(ii) There are two options. The first option (which is not efficient) is trial-and-error: pick some random value of $x$ and determine $f(x)$. If $f(x) = \\var{y2}$, then your pick is the answer.  If not, then try a different value of $x$, hopefully getting closer and closer each time.   The second (and better) option is to 'work backwards' - we know what $f(x)$ should be, which means we know what the $y$-coordinate should be.  So start at $\\var{y2}$ on the $y$-axis, go left or right until you reach the blue line, and look at the $x$-coordinate. In this question, after going left/right from $\\var{y2}$, we reach the $x$-coordinate $\\var{x2}$, so this is the answer.  You can check this is correct: what is $f(\\var{x2})$? It is $\\var{y2}$, as we wanted!

\n

(iii) The $y$-intercept is the height at which the blue line touches the $y$-axis.  In this question, the blue line crosses the $y$-axis at a height of $\\var{c}$, so the answer is $\\var{c}$.

\n

(iv) To calculate the gradient, you choose two points which lie on the line, and calculate the change in height divided by the change in $x$.  It does not matter which two points you choose, but to make it easier, you should pick points whose coordinates are easy to read.  In this question, two points which are on the line are $(\\var{x1}, \\var{y1})$ and $(\\var{x2},\\var{y2})$.  Then the change of height is $\\var{y2} - \\var{y1}$ and the change in $x$ is $\\var{x2} - \\var{x1}$.  Dividing gives the answer $\\var{m}$, which is the number we want.

\n

(v) The equation of a line can be written as $y = mx + c$.  $m$ is the gradient and $c$ is the $y$-intercept.  But we have calculated these two quantities in the previous two questions: the $y$-intercept was $\\var{c}$ and the gradient was $\\var{m}$. Replacing $m$ and $c$ with these numbers gives the equation $y= \\var{m}x + \\var{c}$, which is the answer.

\n

(vi) This question is asking exactly the same thing as the question in (ii), but is phrased differently. This is because the definition of $f^{-1}$ is that it is the function which un-does what $f$ does.  For example, we know that $f(\\var{x1})=\\var{y1}$ - therefore, automatically, $f^{-1}(\\var{y1})$ has to be $\\var{x1}$.  Re-worded, $f$ maps $\\var{x1}$ to $\\var{y1}$, so because $f^{-1}$ un-does this, it means $f^{-1}$ maps $\\var{y1}$ back to $\\var{x1}$.   Back to the question at hand, it asked what $f^{-1}(\\var{y2})$ is.  By definition, this means we want to know what value of $x$ is needed to get $f(x) = \\var{y2}$, which is exactly what was asked in (ii). 

", "name": "Ben's copy of 3 point triangle", "tags": [], "parts": [{"showFeedbackIcon": true, "showCorrectAnswer": true, "prompt": "

{plotgraph(x1,x2,y1,y2,units)}

\n

All units are in mmcmmkm

", "variableReplacements": [], "marks": 0, "scripts": {"mark": {"order": "instead", "script": "// This functions plots two dimensioned lines \n// Max and min x and y values for the axis.\nvar x_min = 0;\nvar x_max = 50;\nvar y_min = 0;\nvar y_max = 50;\n//TODO check whether these are necessary for larger graphs\nvar offset = 1;\nvar scale = 1;\nvar scaleOffset = offset*scale;\n\n//Browser compatibility\nJXG.Options.text.display = 'internal';\n//Use MathJax for LaTeX display\nJXG.Options.text.useMathJax = true;\n\n// Make the JSXGraph board.\nvar div = Numbas.extensions.jsxgraph.makeBoard(\n '400px',\n '400px',\n {\n boundingBox: [x_min,y_max,x_max,y_min],\n axis: false,\n }\n);\n\n// div.board is the object created by JSXGraph, which you use to \n// manipulate elements\nvar board = div.board; \n\n//Draw three points\nvar A = board.create('point', [5, 5], \n {size:0, fixed:true,\n label:{offset: [-10,-10]}});\nvar B = board.create('point', [x1, y1],\n {size:2, fixed:false, face:'+',\n label:{offset: [0,10]}});\nvar C = board.create('point', [x2, y2],\n {size:2, fixed:false, face:'+',\n label:{offset: [10,0]}});\n\n//Draw a line between them\nvar AB = board.create('line',[A,B],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\nvar BC = board.create('line',[B,C],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\nvar AC = board.create('line',[A,C],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\n\n//Draw angle and label\nvar ABC = board.create('nonreflexangle', [A,B,C], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar ABCLabel = ABC.label.setText(function () {\n var angle = 180.0 * ABC.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nABCLabel.setAttribute({anchorX:'middle'});\n\nvar BCA = board.create('nonreflexangle', [B,C,A], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar BCALabel = BCA.label.setText(function () {\n var angle = 180.0 * BCA.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nBCALabel.setAttribute({anchorX:'middle'});\n\nvar CAB = board.create('nonreflexangle', [C,A,B], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar CABLabel = CAB.label.setText(function () {\n var angle = 180.0 * CAB.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nCABLabel.setAttribute({anchorX:'middle'});\n\n//Dummy text for testing variables\ntempText = board.create('text',[25,45,\n function () {return 'ABC = ' +(180.0*ABC.Value()/Math.PI).toFixed(2)+ \"\\u00B0\"}]);\n\n\n//Calculate midpoint\n//TODO Check whether these are useful or not\nvar midABx = (A.X() + B.X())/2;\nvar midABy = (A.Y() + B.Y())/2;\nvar midBCx = (B.X() + C.X())/2;\nvar midBCy = (B.Y() + C.Y())/2;\n\n//Set up dimension labels to be properly aligned\ntextAB = board.create('text', \n [function () {return (A.X() + B.X())/2},\n function () {return ((A.Y() + B.Y())/2)+scaleOffset},\n function () {return +A.Dist(B).toFixed(1) + ' ' +units}],\n {fontSize:15, anchorX:'middle'});\n\ntextBC = board.create('text', \n [function () {return (B.X() + C.X())/2},\n function () {return ((B.Y() + C.Y())/2)+scaleOffset},\n function () {return +B.Dist(C).toFixed(1) + ''}],\n {fontSize:15, anchorX:'middle'});\n\ntextAC = board.create('text', \n [function () {return (A.X() + C.X())/2},\n function () {return ((A.Y() + C.Y())/2)+scaleOffset},\n function () {return +A.Dist(C).toFixed(1) + ''}],\n {fontSize:15, anchorX:'middle'});\n\nvar tABRot = board.create('transform', \n [function () {return AB.getAngle()}, \n function () {return (A.X() + B.X())/2}, \n function () {return (A.Y() + B.Y())/2}],\n {type:'rotate'});\n\nvar tBCRot = board.create('transform', \n [function () {return BC.getAngle()}, \n function () {return (B.X() + C.X())/2}, \n function () {return (B.Y() + C.Y())/2}],\n {type:'rotate'});\n\nvar tACRot = board.create('transform', \n [function () {return AC.getAngle()}, \n function () {return (A.X() + C.X())/2}, \n function () {return (A.Y() + C.Y())/2}],\n {type:'rotate'});\n\n//Perform text rotations and update\ntABRot.bindTo(textAB);\ntBCRot.bindTo(textBC); \ntACRot.bindTo(textAC);\nboard.update();\n\nreturn div;"}}, "variableReplacementStrategy": "originalfirst", "type": "gapfill"}], "variablesTest": {"condition": "", "maxRuns": 100}, "rulesets": {}, "ungrouped_variables": ["x1", "x2", "y1", "y2", "unitList", "units"], "preamble": {"js": "", "css": ""}, "functions": {"plotgraph": {"definition": "// This functions plots two dimensioned lines \n// Max and min x and y values for the axis.\nvar x_min = 0;\nvar x_max = 50;\nvar y_min = 0;\nvar y_max = 50;\n//TODO check whether these are necessary for larger graphs\nvar offset = 1;\nvar scale = 1;\nvar scaleOffset = offset*scale;\n\n//Browser compatibility\nJXG.Options.text.display = 'internal';\n//Use MathJax for LaTeX display\nJXG.Options.text.useMathJax = true;\n\n// Make the JSXGraph board.\nvar div = Numbas.extensions.jsxgraph.makeBoard(\n '400px',\n '400px',\n {\n boundingBox: [x_min,y_max,x_max,y_min],\n axis: false,\n }\n);\n\n// div.board is the object created by JSXGraph, which you use to \n// manipulate elements\nvar board = div.board; \n\n//Draw three points\nvar A = board.create('point', [5, 5], \n {size:0, fixed:true,\n label:{offset: [-10,-10]}});\nvar B = board.create('point', [x1, y1],\n {size:2, fixed:false, face:'+',\n label:{offset: [0,10]}});\nvar C = board.create('point', [x2, y2],\n {size:2, fixed:false, face:'+',\n label:{offset: [10,0]}});\n\n//Draw a line between them\nvar AB = board.create('line',[A,B],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\nvar BC = board.create('line',[B,C],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\nvar AC = board.create('line',[A,C],{fixed:false, straightFirst:false, straightLast:false, strokeWidth: 1});\n\n//Draw angle and label\nvar ABC = board.create('nonreflexangle', [A,B,C], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar ABCLabel = ABC.label.setText(function () {\n var angle = 180.0 * ABC.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nABCLabel.setAttribute({anchorX:'middle'});\n\nvar BCA = board.create('nonreflexangle', [B,C,A], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar BCALabel = BCA.label.setText(function () {\n var angle = 180.0 * BCA.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nBCALabel.setAttribute({anchorX:'middle'});\n\nvar CAB = board.create('nonreflexangle', [C,A,B], {type:'sector', orthoType:'square', orthoSensitivity:0.4, radius:2});\nvar CABLabel = CAB.label.setText(function () {\n var angle = 180.0 * CAB.Value() / Math.PI;\n if ((angle > 90.4) || (angle < 89.6)) {\n return ''+angle.toFixed(1);\n } else {\n return '';\n }\n});\nCABLabel.setAttribute({anchorX:'middle'});\n\n//Dummy text for testing variables\ntempText = board.create('text',[25,45,\n function () {return 'ABC = ' +(180.0*ABC.Value()/Math.PI).toFixed(2)+ \"\\u00B0\"}]);\n\n\n//Calculate midpoint\n//TODO Check whether these are useful or not\nvar midABx = (A.X() + B.X())/2;\nvar midABy = (A.Y() + B.Y())/2;\nvar midBCx = (B.X() + C.X())/2;\nvar midBCy = (B.Y() + C.Y())/2;\n\n//Set up dimension labels to be properly aligned\ntextAB = board.create('text', \n [function () {return (A.X() + B.X())/2},\n function () {return ((A.Y() + B.Y())/2)+scaleOffset},\n function () {return +A.Dist(B).toFixed(1) + ' ' +units}],\n {fontSize:15, anchorX:'middle'});\n\ntextBC = board.create('text', \n [function () {return (B.X() + C.X())/2},\n function () {return ((B.Y() + C.Y())/2)+scaleOffset},\n function () {return +B.Dist(C).toFixed(1) + ''}],\n {fontSize:15, anchorX:'middle'});\n\ntextAC = board.create('text', \n [function () {return (A.X() + C.X())/2},\n function () {return ((A.Y() + C.Y())/2)+scaleOffset},\n function () {return +A.Dist(C).toFixed(1) + ''}],\n {fontSize:15, anchorX:'middle'});\n\nvar tABRot = board.create('transform', \n [function () {return AB.getAngle()}, \n function () {return (A.X() + B.X())/2}, \n function () {return (A.Y() + B.Y())/2}],\n {type:'rotate'});\n\nvar tBCRot = board.create('transform', \n [function () {return BC.getAngle()}, \n function () {return (B.X() + C.X())/2}, \n function () {return (B.Y() + C.Y())/2}],\n {type:'rotate'});\n\nvar tACRot = board.create('transform', \n [function () {return AC.getAngle()}, \n function () {return (A.X() + C.X())/2}, \n function () {return (A.Y() + C.Y())/2}],\n {type:'rotate'});\n\n//Perform text rotations and update\ntABRot.bindTo(textAB);\ntBCRot.bindTo(textBC); \ntACRot.bindTo(textAC);\nboard.update();\n\nreturn div;", "parameters": [["x1", "number"], ["x2", "number"], ["y1", "number"], ["y2", "number"], ["units", "number"]], "type": "html", "language": "javascript"}}, "extensions": ["jsxgraph"], "variables": {"y1": {"description": "", "definition": "random(20..45)", "name": "y1", "group": "Ungrouped variables", "templateType": "anything"}, "y2": {"description": "", "definition": "random(0..45 except y1)", "name": "y2", "group": "Ungrouped variables", "templateType": "anything"}, "units": {"description": "", "definition": "random(1..4)", "name": "units", "group": "Ungrouped variables", "templateType": "anything"}, "x2": {"description": "", "definition": "random(25..45 except x1)", "name": "x2", "group": "Ungrouped variables", "templateType": "anything"}, "unitList": {"description": "

Units that are to be used for the question.

", "definition": "[ \"mm\", \"cm\", \"m\", \"km\" ]", "name": "unitList", "group": "Ungrouped variables", "templateType": "list of strings"}, "x1": {"description": "", "definition": "random(5..20)", "name": "x1", "group": "Ungrouped variables", "templateType": "anything"}}, "statement": "

Referring to the line below.

", "type": "question", "contributors": [{"name": "Ben Brawn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/605/"}]}]}], "contributors": [{"name": "Ben Brawn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/605/"}]}