commit 581332a3223852bd4464fe3295932f0b28410a9e
parent 3ce5b8592746fbd7bde130ad919a163bccf85e2e
Author: hrryt <harry@mayesfield.uk>
Date: Fri, 14 Aug 2026 00:43:29 +0100
Add Segment with hash marker
Diffstat:
7 files changed, 66 insertions(+), 41 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -1,5 +1,6 @@
# Fixes
- Use KaTeX_Math font outside MathML
+- colour="auto" -> no display?
# Questions
- Improve adding fractions
diff --git a/src/components/graphing/Angle.jsx b/src/components/graphing/Angle.jsx
@@ -1,34 +1,5 @@
import Label from './Label.jsx';
-import { getColourClass } from '../../scripts/utils.js';
-
-function sum(arr) {
- return arr.reduce((a, b) => a + b);
-}
-
-function sumVectors(arr) {
- return arr.reduce((a, b) => a.map((ai, i) => ai + b[i]));
-}
-
-function scale(vector, factor) {
- return vector.map(a => a * factor);
-}
-
-function normalise(vector, scaleFactor = 1) {
- const length = Math.sqrt(sum(vector.map(a => a*a)));
- return scale(vector, scaleFactor / length);
-}
-
-function getVector(start, end) {
- return [end[0] - start[0], end[1] - start[1]];
-}
-
-function interpolate(start, end, along) {
- return sumVectors([start, scale(getVector(start, end), along)]);
-}
-
-function interpolateDistance(start, end, distance) {
- return sumVectors([start, normalise(getVector(start, end), distance)]);
-}
+import { getColourClass, getMidpoint, interpolate, interpolateDistance } from '../../scripts/utils.js';
function getArc(points, radius) {
const start = interpolateDistance(points[1], points[0], radius);
@@ -42,9 +13,7 @@ function AngleArc({ points, radius, colour }) {
}
function AngleLabel({ points, radius, colour, children }) {
- const [start, end] = getArc(points, 1);
- const midpoint = interpolate(start, end, 0.5);
- const point = interpolateDistance(points[1], midpoint, 1.5 * radius);
+ const point = interpolateDistance(points[1], getMidpoint(getArc(points, 1)), 1.5 * radius);
return <Label point={point} colour={colour}>{children}</Label>;
}
diff --git a/src/components/graphing/Graph.jsx b/src/components/graphing/Graph.jsx
@@ -2,7 +2,7 @@ import Label from './Label.jsx';
function Grid({ viewBox }) {
const [ minX, minY, width, height ] = viewBox;
- const d = `M ${minX},${minY} h ${width} ${`m -${width},1 h ${width}`.repeat(height)} v -${height} ${`m -1,${height} v -${height}`.repeat(width)}`;
+ const d = `M ${minX},${minY} h ${width}${` m -${width},1 h ${width}`.repeat(height)} v -${height}${` m -1,${height} v -${height}`.repeat(width)}`;
return <path id="grid" d={d} />;
}
@@ -57,19 +57,27 @@ export default function Graph({ children, viewBox, width="300", height="300" })
viewBox="0 0 4 4"
refX="3" refY="2"
markerWidth="4" markerHeight="4"
- markerUnits="strokeWidth"
orient="auto"
>
<polygon class='marker' points="0,0 4,2 0,4" />
</marker>
<marker
id="cross"
- viewBox="0 0 6 6"
- refX="3" refY="3"
- markerWidth="6" markerHeight="6"
- markerUnits="strokeWidth"
+ viewBox="0 0 10 10"
+ refX="5" refY="5"
+ markerWidth="5" markerHeight="5"
+ orient="45"
>
- <polygon class='marker' points="0,1 1,0 3,2 5,0 6,1 4,3 6,5 5,6 3,4 1,6 0,5 2,3" />
+ <polygon class='marker' points="0,4 0,6 4,6 4,10 6,10 6,6 10,6 10,4 4,4 4,0 6,0 6,4" />
+ </marker>
+ <marker
+ id="hash"
+ viewBox="0 0 10 10"
+ refX="5" refY="5"
+ markerWidth="5" markerHeight="5"
+ orient="auto"
+ >
+ <polygon class="marker" points="4,0 4,10 6,10 6,0" />
</marker>
<style>
{style}
diff --git a/src/components/graphing/Segment.jsx b/src/components/graphing/Segment.jsx
@@ -0,0 +1,10 @@
+import { getColourClass, getMidpoint } from '../../scripts/utils.js';
+
+export default function Segment({ points, marker = null, colour = "auto" }) {
+ if (!marker) {
+ const [i, f] = points;
+ return <line x1={i[0]} y1={i[1]} x2={f[0]} y2={f[1]} class={getColourClass(colour)} />;
+ }
+ const allPoints = [points[0], getMidpoint(points), points[1]];
+ return <polyline points={allPoints} marker-mid={`url(#${marker})`} class={getColourClass(colour)} />;
+}
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
@@ -4,6 +4,7 @@ import Quadratic from '../components/graphing/Quadratic.jsx';
import Cubic from '../components/graphing/Cubic.jsx';
import Polygon from '../components/graphing/Polygon.jsx';
import Angle from '../components/graphing/Angle.jsx';
+import Segment from '../components/graphing/Segment.jsx';
export default function Home() {
const viewBox = [-5, -4, 8, 8];
@@ -16,7 +17,8 @@ export default function Home() {
<Quadratic a={2} b={1} c={-3} colour="1" viewBox={viewBox} />
<Polygon points={[[1,2], [-1,1], [-4,3]]} label="P" colour="2" />
<Angle points={[[-4,3], [1,2], [-1,1]]} double={true} colour="2" />
- <Cubic a={1} b={-3} c={3} d={-1} colour="3" viewBox={viewBox}/>
+ <Cubic a={1} b={-3} c={3} d={-1} colour="3" viewBox={viewBox} />
+ <Segment points={[[0,1], [2,2]]} marker="hash" colour="4" />
</Graph>
</div>
</Window>
diff --git a/src/scripts/utils.js b/src/scripts/utils.js
@@ -40,3 +40,36 @@ export function getColourClass(colour) {
if (colour == 'auto') { return ''; }
return `color-${colour}`;
}
+
+function sumVectors(arr) {
+ return arr.reduce((a, b) => a.map((ai, i) => ai + b[i]));
+}
+
+function scale(vector, factor) {
+ return vector.map(a => a * factor);
+}
+
+export function interpolate(start, end, along) {
+ return sumVectors([start, scale(getVector(start, end), along)]);
+}
+
+function sum(arr) {
+ return arr.reduce((a, b) => a + b);
+}
+
+function normalise(vector, scaleFactor = 1) {
+ const length = Math.sqrt(sum(vector.map(a => a*a)));
+ return scale(vector, scaleFactor / length);
+}
+
+function getVector(start, end) {
+ return start.map((a, i) => end[i] - a);
+}
+
+export function interpolateDistance(start, end, distance) {
+ return sumVectors([start, normalise(getVector(start, end), distance)]);
+}
+
+export function getMidpoint(points) {
+ return interpolate(points[0], points[1], 0.5);
+}
diff --git a/src/styles/svg.css b/src/styles/svg.css
@@ -22,6 +22,8 @@ path.axis {
polygon.marker {
fill-opacity: 1;
+ stroke: context-stroke;
+ fill: context-fill;
}
text {