Skip to main content

Plots

Interactive plots allow users to explore mathematical functions by manipulating parameters in real-time. This creates engaging visualizations for understanding function behavior.

Interactive Function Parameters

Create functions with adjustable parameters using sliders:

import { Slider, InteractivePoint } from '@wangyaoshen/locus-interaction';

// Amplitude slider for sine wave
const amplitudeSlider = new Slider({
min: 0,
max: 100,
value: 50,
onChange: (value) => {
redrawFunction(x => value * Math.sin(x));
},
});

// Frequency control
const frequencySlider = new Slider({
min: 0.5,
max: 5,
value: 1,
onChange: (freq) => {
redrawFunction(x => 50 * Math.sin(freq * x));
},
});

Draggable Function Points

Allow users to drag points that define a function:

// Quadratic through three points
const points = [
new InteractivePoint({ position: [-100, 50] }),
new InteractivePoint({ position: [0, -50] }),
new InteractivePoint({ position: [100, 50] }),
];

function updateQuadratic() {
const [p1, p2, p3] = points.map(p => p.getPosition());
// Fit quadratic ax² + bx + c through three points
const coefficients = fitQuadratic(p1, p2, p3);
drawQuadratic(coefficients);
}

points.forEach(p => p.onMove = updateQuadratic);

Function Types

Polynomial Functions

// Linear: f(x) = mx + b
const linearPlot = (m: number, b: number) => (x: number) => m * x + b;

// Quadratic: f(x) = ax² + bx + c
const quadraticPlot = (a: number, b: number, c: number) =>
(x: number) => a * x * x + b * x + c;

// Cubic: f(x) = ax³ + bx² + cx + d
const cubicPlot = (a: number, b: number, c: number, d: number) =>
(x: number) => a * x * x * x + b * x * x + c * x + d;

Trigonometric Functions

// Sine with parameters
const sinePlot = (amplitude: number, frequency: number, phase: number) =>
(x: number) => amplitude * Math.sin(frequency * x + phase);

// Cosine
const cosinePlot = (amplitude: number, frequency: number, phase: number) =>
(x: number) => amplitude * Math.cos(frequency * x + phase);

Parametric Curves

// Circle
const circleParametric = (radius: number, t: number) => [
radius * Math.cos(t),
radius * Math.sin(t),
];

// Lissajous curve
const lissajous = (a: number, b: number, delta: number, t: number) => [
Math.sin(a * t + delta),
Math.sin(b * t),
];

Interactive Plot Examples

Slope Explorer

// Drag a point to change the slope of a line
const slopePoint = new InteractivePoint({
position: [100, 100],
constrain: vertical(100), // x fixed at 100
onMove: (pos) => {
const slope = pos[1] / 100;
drawLine(x => slope * x);
displaySlope(slope);
},
});

Tangent Line

// Drag along a curve to see the tangent line
const curvePoint = new InteractivePoint({
position: [0, 0],
constrain: (pos) => {
// Constrain to parabola y = x²/100
const x = pos[0];
return [x, x * x / 100];
},
onMove: (pos) => {
const x = pos[0];
const slope = 2 * x / 100; // derivative of x²/100
drawTangentLine(pos, slope);
},
});

Rendering Functions

function drawFunction(
ctx: CanvasRenderingContext2D,
f: (x: number) => number,
xMin: number,
xMax: number,
step: number = 1
) {
ctx.beginPath();
let started = false;

for (let x = xMin; x <= xMax; x += step) {
const y = f(x);

if (!started) {
ctx.moveTo(x, y);
started = true;
} else {
ctx.lineTo(x, y);
}
}

ctx.stroke();
}

Tips for Interactive Plots

  1. Smooth Updates: Use requestAnimationFrame for smooth rendering
  2. Bounds Checking: Handle undefined/infinite values in functions
  3. Resolution: Adjust step size based on function complexity
  4. Labels: Show current parameter values for clarity
  5. Constraints: Use constraints to keep control points meaningful