commit f1cba9e07f27a533b22c6750aed479696a037a92
parent 7354bc7de0d7c5c89206cb18a6ccfe77a988b3f5
Author: fen123456 <fenwthompson@gmail.com>
Date: Sat, 8 Aug 2026 23:00:14 +0100
groundwork for transformation questions
Diffstat:
6 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -8,8 +8,10 @@
- Add graphing questions
- Find all roots of this quintic (or something) polynomial (repeated root knowledge)
- Transformations of shapes and graphs (curves)
+ - Make text same size for all graph scalings.
- Drop-down for finer controls
- tricky parallel lines / internal angles etc questions
+- automate allQuestions using file exploration
# Other stuff
- minesweeper / youtube video.
diff --git a/src/components/questions/DoubleTransformationQuestion.jsx b/src/components/questions/DoubleTransformationQuestion.jsx
@@ -0,0 +1,49 @@
+import { getRandomChoice, getRandomInt } from "../../scripts/utils";
+import CoordinateLabel from "../graphing/CoordinateLabel";
+import Graph from "../graphing/Graph";
+import Question from "../Question";
+
+function pointToString(point) {
+ return point[0].toString() + ',' + point[1].toString()
+}
+
+function shapeToString(shape) {
+ console.log(shape.map((point) => pointToString(point)).join(" "))
+ return shape.map((point) => pointToString(point)).join(" ")
+}
+
+function rotatePoint(point, angle, axis=[0, 0]) {
+ const diff = [point[0] - axis[0], point[1] - axis[1]]
+ const c = Math.cos(angle)
+ const s = Math.sin(angle)
+ return [axis[0] + c*diff[0] + s*diff[1], axis[1] + c*diff[1] - s*diff[0]]
+}
+
+
+export default function DoubleTransformationQuestion({ seed, showAnswer }) {
+ const viewBox = [-7, -7, 14, 14]
+ const originalShape = [[0, 1], [2, 1], [0, 2]]
+ const axis = [getRandomInt(-3, 3, seed), getRandomInt(-3, 3, seed + .1)]
+ const angle = getRandomChoice([Math.PI/2, Math.PI, 3*Math.PI/2], seed + .2)
+
+ // Rotation then translation!. could do other way around if really needed.
+ const midShape = originalShape.map((point) => rotatePoint(point, angle))
+
+ const rotatedAxis = rotatePoint(axis, angle)
+ const translationVector = axis.map((value, i) => value - rotatedAxis[i])
+
+ const endShape = midShape.map((point) => point.map((value, i) => value + translationVector[i]))
+
+
+ const question = (<>
+ <p>What single transformation..?</p>
+ <Graph viewBox={viewBox} width="300" height="300">
+ <polygon points={shapeToString(originalShape)} />
+ <polygon points={shapeToString(midShape)} />
+ <polygon points={shapeToString(endShape)} />
+ <CoordinateLabel x={axis[0]} y={axis[1]} position="top" />
+ </Graph>
+ </>)
+
+ return <Question question={question} answer="" showAnswer={showAnswer} />
+}
+\ No newline at end of file
diff --git a/src/components/questions/QuadraticEquationQuestion.jsx b/src/components/questions/QuadraticEquationQuestion.jsx
@@ -10,10 +10,13 @@ function formatQuadraticExpression(a, b, c) {
function formatFraction(num, denom) {
const hcf = getHCF(Math.abs(num), Math.abs(denom))
- num = num / hcf
- denom = denom / hcf
- if (denom == 1) { return `${num}`; }
- return `frac(${num}, ${denom})`
+ const prefix = num / denom > 0 ? "" : "-"
+
+ num = Math.abs(num / hcf)
+ denom = Math.abs(denom / hcf)
+
+ if (denom == 1) { return `${prefix}${num}`; }
+ return `${prefix}frac(${num}, ${denom})`
}
function formatRoots(l, m, n, o) {
diff --git a/src/data/questions/gcse/double-transformations.js b/src/data/questions/gcse/double-transformations.js
@@ -0,0 +1,12 @@
+import DoubleTransformationQuestion from "/src/components/questions/DoubleTransformationQuestion";
+
+export const data = {
+ questionLists: [{
+ id: 0,
+ n: 3,
+ questions: [{
+ type: DoubleTransformationQuestion,
+ variables: {},
+ }]
+ }]
+}
+\ No newline at end of file
diff --git a/src/pages/QuestionIndex.jsx b/src/pages/QuestionIndex.jsx
@@ -10,6 +10,9 @@ const allQuestions = [{
}, {
id: 'adding-fractions',
label: 'Adding Fractions'
+ }, {
+ id: 'double-transformations',
+ label: 'Double Transformations'
}]
}, {
id: 'a-level',
diff --git a/src/styles/main.css b/src/styles/main.css
@@ -1,10 +1,22 @@
+:root {
+ --highlight: #008080;
+
+ --background: var(--highlight);
+
+ --graph-1: var(--highlight);
+ --graph-2: #43509E;
+ --graph-3: #DC267F;
+ --graph-4: #FE6100;
+ --graph-5: #FFB000;
+}
+
body {
- background-color: #008080;
+ background-color: var(--background);
margin: 0;
}
nav.taskbar {
- max-width: 100vw !important;
+ max-width: 100vw;
}
button.taskbar-element.active {