import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Book, Calculator, Grid, Move, ChevronRight, Menu, X, CheckCircle, Info, Target, Layers, Box } from 'lucide-react';
// --- Math Rendering Helper ---
// Upgraded to handle specific LaTeX patterns used in this curriculum
const MathTx = ({ children, block = false }) => {
if (typeof children !== 'string') return null;
let html = children;
// 1. Basic Symbols
html = html
.replace(/\\cdot/g, '·')
.replace(/\\times/g, '×')
.replace(/\\theta/g, 'θ')
.replace(/\\pi/g, 'π')
.replace(/\\lambda/g, 'λ')
.replace(/\\mu/g, 'μ')
.replace(/\\alpha/g, 'α')
.replace(/\\beta/g, 'β');
// 2. Vectors \vec{x} -> Bold Italic with color (Darkened for visibility)
html = html.replace(/\\vec\{([a-zA-Z0-9]+)\}/g, '$1 ');
// 3. Hats \hat{x} -> x with a hat
html = html.replace(/\\hat\{([a-zA-Z0-9]+)\}/g, '^ $1 ');
// 4. Square roots \sqrt{...}
html = html.replace(/\\sqrt\{([^}]+)\}/g, '√$1 ');
// 5. Fractions \frac{a}{b}
html = html.replace(/\\frac\{([^}]+)\}\{([^}]+)\}/g,
'$1 $2 ');
// 6. Binomials/Vectors \binom{a}{b} or \binom{a}{b\\ c}
// Handles 2D and 3D vectors
html = html.replace(/\\binom\{([^}]+)\}\{([^}]+)\}/g, (match, top, bottom) => {
// Handle the 3D case where bottom contains split \\
const bottomParts = bottom.split('\\\\');
const rows = [top, ...bottomParts];
const rowHtml = rows.map(r => `${r.trim()} `).join('');
return `${rowHtml} `;
});
// 7. Matrices/Determinants \begin{vmatrix}...\end{vmatrix}
html = html.replace(/\\begin\{vmatrix\}([\s\S]*?)\\end\{vmatrix\}/g, (match, content) => {
const rows = content.split('\\\\').map(row => {
const cells = row.split('&').map(cell => `
${cell.trim()} `).join('');
return `${cells} `;
});
return ``;
});
// 8. Subscripts/Superscripts
html = html.replace(/\^([0-9a-z]+)/g, '$1 ');
html = html.replace(/_([0-9a-z]+)/g, '$1 ');
return (
);
};
// --- Interactive Components ---
const VectorAdditionVisualizer = () => {
const [v1, setV1] = useState({ x: 3, y: 1 });
const [v2, setV2] = useState({ x: 1, y: 3 });
const gridSize = 20;
const scale = 30;
const origin = { x: 50, y: 250 };
const r1 = { x: v1.x * scale, y: -v1.y * scale };
const r2 = { x: v2.x * scale, y: -v2.y * scale };
const res = { x: r1.x + r2.x, y: r1.y + r2.y };
return (
Interactive Vector Addition
{/* Grid */}
{/* Vectors */}
{/* Vector A */}
a
{/* Vector B (placed at tip of A) */}
b
{/* Resultant */}
a + b
Resultant: {`\\vec{r} = \\binom{${v1.x + v2.x}}{${v1.y + v2.y}}`}
);
};
const DotProductVisualizer = () => {
const [angle, setAngle] = useState(45);
const magA = 100;
const magB = 100;
const rad = (angle * Math.PI) / 180;
const dotProduct = (magA/10 * magB/10 * Math.cos(rad)).toFixed(1);
return (
Dot Product & Angles
{/* Vector A (Fixed Horizontal) */}
{/* Vector B (Rotates) */}
{/* Angle Arc */}
θ
|a| = {magA/10}
|b| = {magB/10}
cos(θ) = {Math.cos(rad).toFixed(3)}
{`\\vec{a} \\cdot \\vec{b} = `} {dotProduct}
{dotProduct === "0.0" ? "Vectors are PERPENDICULAR (Orthogonal)" : dotProduct > 0 ? "Acute Angle" : "Obtuse Angle"}
);
};
// --- Content Data ---
const topics = [
{
id: 'intro',
title: '1. Introduction to Vectors',
level: 'IGCSE',
content: (
Scalars vs Vectors
In physics and mathematics, quantities are classified into two types:
Scalars
Quantities with MAGNITUDE only.
Mass (kg)
Time (s)
Distance (m)
Speed (m/s)
Vectors
Quantities with both MAGNITUDE and DIRECTION.
Force (N)
Displacement (m)
Velocity (m/s)
Acceleration (m/s²)
Notation
We represent vectors geometrically as arrows. The length represents the magnitude, and the arrow points in the direction.
Forms:
Column: {`\\binom{x}{y}`} or {`\\binom{x}{y\\\\ z}`}
Component: {`x\\vec{i} + y\\vec{j}`}
Geometric: {`\\vec{AB}`} (From point A to B)
)
},
{
id: 'arithmetic',
title: '2. Vector Arithmetic',
level: 'IGCSE',
content: (
Addition & Subtraction
Geometrically: Use the "Triangle Law" (Head-to-Tail). To add {'\\vec{a}'} and {'\\vec{b}'} , place the tail of {'\\vec{b}'} at the head of {'\\vec{a}'} . The resultant connects the start to the finish.
Algebraically: Simply add corresponding components.
{`\\binom{a_1}{a_2} + \\binom{b_1}{b_2} = \\binom{a_1 + b_1}{a_2 + b_2}`}
Scalar Multiplication
Multiplying a vector by a scalar (number) {'k'} scales its magnitude.
If {'k > 1'} , it stretches.
If {'0 < k < 1'} , it shrinks.
If {'k < 0'} , it reverses direction.
)
},
{
id: 'magnitude',
title: '3. Magnitude & Unit Vectors',
level: 'IB SL',
content: (
Magnitude
The magnitude (length) of a vector is denoted by {'|\\vec{v}|'} . In 2D and 3D, it is calculated using the Pythagorean theorem.
2D Space
{`|\\vec{v}| = \\sqrt{x^2 + y^2}`}
3D Space
{`|\\vec{v}| = \\sqrt{x^2 + y^2 + z^2}`}
Unit Vectors
A unit vector {'\\hat{u}'} has a magnitude of 1. It is often used to specify direction purely.
To find a unit vector in the direction of {'\\vec{v}'} :
{`\\hat{u} = \\frac{\\vec{v}}{|\\vec{v}|}`}
Standard Basis Vectors:
{'\\vec{i} = \\binom{1}{0},\\ \\vec{j} = \\binom{0}{1}'} (2D)
{'\\vec{k} = \\binom{0}{0\\\\ 1}'} (added for 3D)
)
},
{
id: 'dot_product',
title: '4. The Dot Product (Scalar Product)',
level: 'IB SL',
content: (
Definition
The dot product takes two vectors and returns a scalar . It tells us how much one vector points in the direction of another.
Algebraic Definition:
{`\\vec{a} \\cdot \\vec{b} = a_1b_1 + a_2b_2 + a_3b_3`}
Geometric Definition:
{`\\vec{a} \\cdot \\vec{b} = |\\vec{a}| |\\vec{b}| \\cos(\\theta)`}
Key Properties
If {'\\vec{a} \\cdot \\vec{b} = 0'} , the vectors are Perpendicular (Orthogonal).
If {'\\vec{a} \\cdot \\vec{b} = |\\vec{a}||\\vec{b}|'} , they are parallel (same direction).
Used to find the angle between two vectors: {`\\cos(\\theta) = \\frac{\\vec{a} \\cdot \\vec{b}}{|\\vec{a}||\\vec{b}|}`}
)
},
{
id: 'lines',
title: '5. Vector Equation of Lines',
level: 'IB SL',
content: (
The Formula
Unlike {'y = mx + c'} in 2D, vector equations work in 2D and 3D. A line is defined by a fixed point {'\\vec{a}'} and a direction vector {'\\vec{b}'} .
{'r = a + tb'}
r General point {'\\binom{x}{y}'}
a Position vector of fixed point
b Direction vector
Relationship between Lines
Relationship
Condition
Angle?
Parallel
Direction vectors are scalar multiples: {'\\vec{b_1} = k\\vec{b_2}'}
0°
Intersecting
Unique solution for {'s'} and {'t'} in {'a_1 + t\\vec{b_1} = a_2 + s\\vec{b_2}'}
Calculable via dot product
Skew (3D only)
Not parallel AND no intersection point.
N/A
)
},
{
id: 'cross_product',
title: '6. The Cross Product',
level: 'IB HL',
content: (
HL ONLY
Definition
The cross product {'\\vec{a} \\times \\vec{b}'} results in a Vector that is perpendicular to both {'\\vec{a}'} and {'\\vec{b}'} .
{`\\vec{a} \\times \\vec{b} = \\begin{vmatrix} i & j & k \\\\ a_1 & a_2 & a_3 \\\\ b_1 & b_2 & b_3 \\end{vmatrix}`}
{`= \\binom{a_2b_3 - a_3b_2}{a_3b_1 - a_1b_3 \\\\ a_1b_2 - a_2b_1}`}
Applications
Normal Vector: Finding a vector perpendicular to a plane (essential for plane equations).
Area of Triangle: {`Area = \\frac{1}{2} |\\vec{a} \\times \\vec{b}|`}
Geometric Magnitude: {`|\\vec{a} \\times \\vec{b}| = |\\vec{a}||\\vec{b}|\\sin(\\theta)`}
)
},
{
id: 'planes',
title: '7. Vector Equation of Planes',
level: 'IB HL',
content: (
HL ONLY
Scalar Equation
A plane is defined by a point {'\\vec{a}'} and a normal vector {'\\vec{n}'} (perpendicular to the plane).
{'r \\cdot n = a \\cdot n'}
This expands to the Cartesian form: {'ax + by + cz = d'} , where {'\\binom{a}{b\\\\ c}'} is the normal vector.
Parametric Form
Alternatively, using two non-parallel direction vectors {'\\vec{u}'} and {'\\vec{v}'} on the plane:
{'r = a + \\lambda \\vec{u} + \\mu \\vec{v}'}
Intersection of Planes
The intersection of two non-parallel planes is a Line .
Strategy: The direction of the line of intersection is {'\\vec{n_1} \\times \\vec{n_2}'} .
)
}
];
// --- Main Application Component ---
const App = () => {
const [activeTopicId, setActiveTopicId] = useState('intro');
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const scrollRef = useRef(null);
const activeTopic = topics.find(t => t.id === activeTopicId) || topics[0];
const handleNav = (id) => {
setActiveTopicId(id);
setMobileMenuOpen(false);
if(scrollRef.current) scrollRef.current.scrollTop = 0;
};
return (
{/* Sidebar Navigation */}
VectorMastery
setMobileMenuOpen(false)} className="md:hidden text-slate-300 hover:text-white">
Curriculum Modules
{topics.map(topic => (
handleNav(topic.id)}
className={`w-full text-left px-4 py-3 rounded-lg text-sm transition-colors duration-200 flex items-center justify-between group ${activeTopicId === topic.id ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-200 hover:bg-slate-800 hover:text-white'}`}
>
{topic.title}
{activeTopicId === topic.id && }
{topic.level.includes('HL') && activeTopicId !== topic.id && HL }
))}
Exam Tip
In IB exams, always check if your calculator is in Degrees or Radians mode when calculating angles between vectors.
{/* Main Content Area */}
{/* Mobile Header */}
setMobileMenuOpen(true)} className="mr-4 text-slate-700">
VectorMastery
{/* Scrollable Content */}
{/* Topic Header */}
{activeTopic.level}
Mathematics
{activeTopic.title.split('. ')[1]}
{/* Content Injection */}
{activeTopic.content}
{/* Knowledge Check / Mini Quiz */}
Quick Check
Which of the following is true if {'\\vec{a} \\cdot \\vec{b} = 0'} ?
{['Vectors are parallel', 'Vectors are perpendicular', 'Vectors are equal', 'One vector is zero (necessarily)'].map((opt, i) => (
{String.fromCharCode(65+i)}
{opt}
))}
Self-Check: Recall that a dot product of zero implies orthogonality (90° angle), provided neither vector has zero magnitude.
{/* Navigation Footer */}
{
const idx = topics.findIndex(t => t.id === activeTopicId);
if (idx > 0) handleNav(topics[idx - 1].id);
}}
className={`px-4 py-2 rounded font-medium text-sm ${activeTopicId === topics[0].id ? 'text-slate-400 cursor-not-allowed' : 'text-blue-700 hover:bg-blue-50 hover:text-blue-800'}`}
>
← Previous Topic
{
const idx = topics.findIndex(t => t.id === activeTopicId);
if (idx < topics.length - 1) handleNav(topics[idx + 1].id);
}}
className={`px-4 py-2 rounded font-medium text-sm ${activeTopicId === topics[topics.length - 1].id ? 'text-slate-400 cursor-not-allowed bg-slate-100' : 'bg-blue-700 text-white hover:bg-blue-800 shadow-md hover:shadow-lg transition-all'}`}
>
Next Topic →
);
};
export default App;